Assignment #3 for the SLAE certification asks the student to do the following:
- Study about the Egg Hunter shellcode
- Create a working demo of the Egghunter
- Should be configurable for different payloads
Based on what I found during my research, the basic idea behind an egg hunter is that you will have the first stage of your shellcode search through memory for an “egg” that you provide. Somewhere in memory will be the second stage of your shellcode that has the egg at the beginning. The first stage searches for that egg, and when it is found, the first stage jumps to the second stage and the second stage of the shellcode is executed.
The egg hunter is especially useful for exploit development, as you may not know exactly where in memory your shellcode payload will be. The egg hunter is a small piece of shellcode that can be used to find that payload and execute it.
The first stage should be the egg hunter code. It’s job is to find the egg in memory.
The second stage will have the shellcode payload you want to execute. For this example, my shellcode payload will use execve to launch /bin/bash.
How the egg hunter will work
There are many different ways to create an egg hunter. Corelan has a great tutorial on egg hunters and how to use them in Windows exploit development here: https://www.corelan.be/index.php/2010/01/09/exploit-writing-tutorial-part-8-win32-egg-hunting/
There is also a very detailed paper written by skape on how to create fast and efficient egg hunters in both Linux and Windows shellcode here: http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf
For my egg hunter, I decided to make something simple and easy to create. The egg hunter will iterate through memory addresses, and compare the value at that memory address to the provided egg. If the value matches the egg, the egg hunter will jump to that memory space and execute the second stage of the shellcode payload.
The memory of the application would look something like <egg hunter><random memory><egg><second stage shellcode><random memory>. The egg hunter will keep searching through memory until the egg is found, and then jump to the second stage and execute.
To get started with the egg hunter code, I wanted to provide the egg hunter with a memory address to begin searching from. I wanted to make sure that the memory address would be after the egg is first provided in the shellcode, so that the egg hunter doesn’t inadvertently jump to the wrong location. To do this, I did a JMP-CALL-POP so that and address after the egg is defined is obtained.
jmp short get_address
;this will set up the egg to be hunted
pop eax ; put a memory address in eax after doing the jmp-call-pop
# more later
# more later
; this is just for the jmp-call-pop to get a memory address in EAX as a starting point to start searching for the egg
After this is done, the memory address after the call egg instruction will be stored in the register EAX.
With the starting memory address in EAX, the value of the egg will be placed into the EBX register.
mov dword ebx, 0xdeadbeef ; this is the egg to search for
The egg should be a unique value that is unlikely to appear in memory as normal instructions.
The egg hunter
Now, to create the egg hunter code. This will work by increasing the memory address stored in EAX by one, and then compare the egg stored in EBX to the value stored at the memory address in EAX.
To better ensure that the egg hunter code has actually found the egg and second stage of the shellcode, the second stage will actually have the egg in front of it twice. So, in memory it would look like <egg><egg><second stage shellcode>. If the egg is found twice in a row, the egg hunter will jump to the memory address following that second egg and execute the payload. The assembly looks like this:
cmp dword [eax], ebx
cmp dword [eax], ebx
add eax, 0x4
To test the egg hunter and simulate the egg hunter and the second stage being in different areas of memory, the following C code was used.
unsigned char egghunter = \
unsigned char egg = \
“\xef\xbe\xad\xde” /* first egg */
“\xef\xbe\xad\xde” /* second egg */
“\x31\xc0\x50\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80”; /* place your shellcode payload here */
printf(“Shellcode Length: %d\n”, strlen(egghunter));
int (*ret)() = (int(*)())egghunter;
The C code will first load the shellcode saved in “egghunter” into memory and execute from there. The egg hunter will run until it finds the two eggs that are at the beginning of the “egg” variable.
Testing the egg hunter
The egg hunter assembly code was compiled and objdump was used to obtain the shellcode.
This shellcode was added to shellcode.c, which was then compiled and executed.
The egg hunter executed and successfully found the egg. The second stage was then executed, which launched /bin/bash.
Analyzing in GDB
To confirm that this was working properly and that the egg hunter was actually searching for the egg and find it, GDB was used to analyze the egg-hunter-shellcode application.
A breakpoint was set for 0x0804a04d, which is the memory address after the first jne back to the beginning of the egg hunter. If the application made it to this instruction, it meant that the comparison of EBX and the value EAX pointed to were equal, and the first egg was found.
The breakpoint was hit. Inspeacing the EBX register and the values at EAX showed that the egg was found.
Inspecting the memory address stored in EAX showed that the next 8 bytes were the egg twice in a row. This means that the egg hunter should then jump to the second stage of the shellcode.
After the execution of the application was continued, the egg hunter jumped to the second stage and execve launched /bin/bash.
The assembly code for the egg hunter can be found here: https://github.com/FatRodzianko/slae-exam/blob/master/3-egghunter/egg-hunter.nasm
The C code for the egg hunter can be found here: https://github.com/FatRodzianko/slae-exam/blob/master/3-egghunter/shellcode.c
Any payload for the second stage can be added to shellcode.c by replace the execve shellcode at line 10
All code and notes used for this can be found at: https://github.com/FatRodzianko/slae-exam/tree/master/3-egghunter
SLAE Student Disclaimer
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/onlinecourses/securitytube-linux-assembly-expert/
Student ID: SLAE- 1373