Egghunter with Intel x86
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
Student ID: SLAE-975
Assignment number: #3
Github repository: https://github.com/amonsec/SLAE/tree/master/assignment-3
This post is part of my SLAE series.
You can find the previous post at this address: https://amonsec.net/training/linux-assembly-x86/2018/linux-tcp-reverse-shell-from-scratch-with-intel-x86-assembly
In this post we will discuss this weird thing called egghunter, what is his utility and in which cases? For that, this post is going to be split-ed in three parties.
- Egghunter from scratch;
- Egghunter?! what da f*ck and
- Egghunter in a Windows exploit
What you need in order to reproduce the process:
- A Linux x86 system (Kali Linux in my case)
- Your brain (and maybe a cup a coffee or eight)
If you want to recreate for scratch the windows exploit:
Egghunter?! what da f*ck.
An egghunter is a sequence of instructions that can parse the stack and the heap in order to find the location of a given pattern and jump right after it to redirect the execution flow. There are different egghunters all around the Web, but here, we will create a basic egghunter that use the access Linux system call
However, why an egghunter can be useful, and why we need to learn how to use it?
Sometimes, in exploit development you don’t have enough place after smashing the stack and you need to find a place where you can put your shellcode and redirect the execution flow at the beginning of this malicious code in order to execute it. With only few bytes, in most cases, no more than 40 bytes, you can inject your egghunter and put in any other place you eight bytes pattern followed by your shellcode, after that, you only need to wait.
The egghunter is going to search in the stack and the heap for our eight byte pattern and then, when he found it, jump to him.
For this reason, egghunters are highly use in exploit development. This a must have technique.
Virtual Address Space
First, let me show you this awesome picture from Gustavo Duarte. This is, one of the best if not the best post and picture to understand the Linux memory layout and in our case the memory parsing.
Note, this is for x86 (32 bits) architecture.
How egghunter works?!
Two major type of egghunter exist:
- Byte crawling egghunter;
- Page crawling egghunter.
The Byte crawling egghunter start from the top of the stack and parse every single byte until he found the eight byte pattern, but if the egghunter try to parse an unmapped memory area we will have a segmentation fault (SIGSEV).
While, the page crawling egghunter, first check if the memory page (4096 bytes) is usable or not. If yes, search for the pattern, else move in another memory page. It’s easy to understand that the second one, is much more robust than the first one.
So, our egghunter will do a string comparison for each byte in usable memory pages and will redirect the execution flow if the result of the string comparison is not null.
Egghunter from scratch
All this work is based on the awesome documentation of Skape.
First, we need to initialise all registers that we will use, such as EDX and ECX. After that, we will create two procedures that they will increment EDX with one memory page (4096 bytes in our case) or increment EDX by one. Note, we use the cld instruction to be sure the direction flag (DF) is unset since we will use later the scasd instruction.
So, the beginning of the code should be looking like that:
Then, we are going to find if the current memory page is usable. For that, we can use the access system call that are checking for user’s permissions for a file and in our case the currently executed binary.
EAX will point to the system call number and EBX to the memory page content.
When the access subroutine try to access to the given memory page first bytes, but can’t use it due to an invalid memory page, an EFAULT error is throw.
That means, we try to access to a place outside the memory space usable by our binary. So, if the result of the access subroutine is equal to EFAULT (0xfffffffe = -14) we will increment the EDX register by one, else we are in an usable memory page.
OK, now, we are ready to search in an usable memory page our pattern. The easiest way is put into EAX our pattern, and to use the scasd instruction, which is really good explained here.
The scasd instruction will return zero if the value of the EDI register and EAX are equal, else, return one if the value of the EDI register and the EAX register are not equal. With this simple logic we can create a loop that will run until we found our pattern.
Here, EAX contain our pattern and EDI the string that we want to compare to EAX.
Note, in order to have a more reliable egghunter and to avoid the egghunter to redirect the execution flow into himself, our pattern, before our shellcode, is doubled, that’s why we use two times the scasd instruction.
Finally we have something like that.
We can compile the code and extract the shellcode
Now, let’s create a simple shellcode with the Metasploit framework.
We have everything ready, we can now create a C file that will use our egghunter in order to find and execute our Metasploit’s shellcode.
Let’s compile this one.
Note, here I use strace in order to see the parsing process.
Egghunter in a Windows exploit
A Few times ago, I started to learn Windows’ exploits development and I quickly learned the usefulness of egghunters. I let a really well known script called mona.py did it for me.
And this following code is one of my Windows’ exploit that I built from scratch:
Schema of the exploit’s structure:
Our egghunter (from Immunity Debugger):
Our shellcode (from Immunity Debugger):