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: SLAE-924
The task is to:
- Study about egghunter
- Create a working demo of the egghunter
- Should be configurable for different payloads
What is egghunter?
The detailed description of egghunting can be found here. This post also based on this whitepaper.
I’ll try to describe the main concepts here briefly.
Egg hunting is a technique that allows us to use small shellcode to find main BIG shellcode. It is very useful when buffer size is too small to place entire shellcode there.
To write our egg hunter we will use
access system call. Using of this syscall can help us to encounter invalid memory address. When syscall encounters an invalid memory address, it returns
EFAULT error code. And this information allows our egg hunter to safely traverse the process VAS (Virtual Address Space) .
We will use
int access(const char *pathname, int mode);
Syscall reference can be found here:
access syscall number is
Firstly we will point
ebx to our egg:
Then we will zero out
xor ecx, ecx mul ecx
The next two instructions will perform a page alignment operation on the current pointer. Bitwise
or of the current pointer (stored in
edx register) and then incrementing
edx by one.
This two operations is like adding
0x1000 to the value in edx.
next_page: or dx, 0xfff searching_egg: inc edx
The next operation is:
This operation pushes ЕАХ, ЕСХ, EDX, ЕВХ, ESP, EBP, ESI, EDI register values to the stack for future use.
ebx register will store the pointer to be validated plus 4. Why plus 4? Cause it allows us to eight bytes to be validated at once.
lea ebx, [edx + 4]
In the next step we will move system call number to the
mov al, 0x21 int 0x80
Then we should compare value in
eax register with the
0xf2,which represents the low byte of the EFAULT return value.
Now we should
pop register values from the stack.
If value of
eax register equals to
0xf2 which means that we have no access to this page, our egghuter will jump to
If we have access to this page and there is no
EFAULT we will compare the pointer and our egg we are searching for.
cmp [edx], ebx
If they don’t match, the implementation jumps to the inc edx instruction which simply goes to the next address in the current page.
If the egg matches with the content of the pointer in
edx it will compare content of the pointer in
edx + 4 with the egg.
If they don’t match it will jump again to
Otherwise the egg is found!
That’s how our egghunter implementation looks like:
Let’s compile it!
nasm -f elf32 -o egghunter.o egghunter.nasm ld -o egghunter egghunter.o objdump -d egghunter -M intel
Let’s extract the opcodes:
objdump -d ./egghunter|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
As a main shellcode we will use our old reverse_tcp shellcode from the previous assignment:
We will use
Let’s compile it and RUN!
gcc shellcode.c -z execstack ./a.out
And it works: