Last active
October 13, 2020 03:29
-
-
Save debasishm89/5746556 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
; 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