Whoop Whoop. We’re back – this time (and just very shortly after Easter) – we’re hunting eggs! 🙂
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
Student ID: SLAE-890
So, what is an Egghunter implementation? Well, first of all, I’d say you take a look at this great paper:
A guy called skape explains very thoroughly various possibilities how to implement an Egghunter. But what is an Egghunter?
An Egghunter implementation comes handy in situations (e.g. during an exploit), where space on Stack is limited and it’s just not big enough to store the full glory of all your shellcode bytes. In order to solve that dilemma, you need to do some sort of multi stage shellcoding. First stage will be a small stub that actively searches the memory for the 2nd stage (your real shellcode a.k.a. “the egg”) and, once it finds it, jumps to it. This first stage is called Egghunter.
In order to allow this first stage to find our shellcode, we are preparing a bit of memory to have the following structure:
4-BYTES OF SIGNATURE (TAG) 4-BYTES OF SIGNATURE (TAG) ... SHELLCODE ...
In my implementation I was using the access syscall method, since it’s the most easy to read and quite self explanatory. Here the code for the egghunter:
(As usual, all the code can be found on my github page).
It really is quite simple The program just iterates over page aligned address blocks (0x1000, 0x2000, 0x3000, …. until the very end of memory) and tries to access them by exploiting the access() syscall. Please note that we’re actually trying to access memory+4 bytes, since that guarantees, that memory+0 bytes (page start) would then also work (required for our egg byte compare).
Once we find an accessible memory block (page), we compare the memory for our egg signature 0x90509050. We do that twice in order not to trigger on the “mov eax, 0x90509050” code but instead only trigger when finding the real egg.
Once we got this double hit (two signatures found in a row), we can safely assume that we found the entry to our shellcode and so we just jump to that memory address right after the 8 bytes of signature. Done! Shellcode – executed.
Pretty cool stuff 🙂
In order to test this in a simulated memory environment, I developed a small C program (poc.c) to separate the egghunter from the shellcode. The egghunter gets triggered to search the whole memory for the egg/shellcode and once it finds it, execution gets passed over to the shellcode.
In my case I just used the course’s “execve-stack” example as shellcode. All it does is run /bin//sh by using the execve syscall. So in case of success, the poc.c should just open a new local shell. So, here the code:
- Map some memory for the egghunter, copy code into memory.
- Allocate some memory for the shellcode, copy code into it.
- Trigger the egghunter code.
- Free memory, exit cleanly.
Easy, clean and nice. Ah yes, and it works, too! 🙂
Hope you enjoyed reading. Take care.