Art of Shellcoding: Cracking Eggs with EggHunters

Shellcode Research Nipun Jaswal todayJanuary 16, 2018 3

Background
share close

Legacy research restoration. Originally published on 16 January 2018 as part of the SecurityTube Linux Assembly Expert programme under student ID SLAE-1080. The original technical sequence, images, code references and publication date have been preserved.

Cracking Eggs with EggHunters

Dear Readers, thank you for your overwhelming response to the previous post on reverse TCP shellcode. Last time, we wrote one of the smallest reverse TCP shellcodes of all time. This post advances onto an interesting concept called the Egg Hunter Shellcode. So, what is an egg hunter shellcode? For those interested in exploit development, they often come across a problem of limited space for the shellcode to execute. I remember the first exploit i wrote was a POC for SamSpade tool. Yeap, the good old samspade which allows us to fingerprint the targets. I wanted to exploit the same, but space was limited. It was only 7-8 bytes of space, and no shellcode would fit into it. The same sort of problems is addressed by egg hunter shellcodes. This means small shellcodes would allow jumping to the more substantial shellcodes in memory. However, 7-8 bytes is still something which is always tough.

Note: I created one of the smallest egghunter shellcode after i wrote this post and is published on exploit-db.com: https://www.exploit-db.com/exploits/43910/

The beauty of an egghunter shellcode lies in the fact that you don’t need to hardcode any addresses or calculate an exact offset to make a jump while executing the staged payload. In fact, its just a small program which will scan through the entire address space of the program and find a specific keyword, once the keyword is found, it directly jumps right next to it(start of the shellcode). We call this keyword an “egg.” So let’s get started with our egghunter shellcode as follows:

Original source code: Open the archived GitHub Gist

As we can see that the first line of code is the for the page alignment in case, invalid regions of memory are encountered. Next, we just increment the value of ECX and validate this address using sigaction syscall, denoted by 0x43. We now issue the interrupt and compare the value returned by sigaction syscall in EAX to 0xf2 which is the lower bytes of EFAULT (Denotes Bad Addresses/ Invalid Addresses). This means that on every EFAULT, page alignment will happen since the Zero Flag gets set by the CMP instruction. However, if the memory region is valid, the jump to page alignment is not taken, and our EGG value which is 0x50905090 is moved to EAX register while our valid address is transferred to EDI from ECX. But why did we move from ECX to EDI? This is because we will be using  SCASD instruction which compares the string held at the address pointed to by the EDI register with the contents of EAX register [This is precisely where our egghunter hits the WORD version of the EGG if it finds it for the first time]. However, if it doesn’t hit the egg[Denoted by ZF flag],  it jumps to increment the address and perform the same steps of the next valid memory region.

In cases where the first SCASD instruction sets the ZF flag, another SCASD instruction is followed, but why?

This is because we have an 8-byte version of the EGG which means when the EGG 0x50905090 is compared, a correct match will occur on the following sequence of bytes which is “\x90\x50\x90\x50\x90\x50\x90\x50”. We use the 8-byte version of the EGG to provide a real uniqueness to the EGG. Coming back to why we used SCASD again, we used it because on the very first SCASD instruction, the SCASD instruction along with the comparison also increments the value of EDI by four and the next four bytes at EDI are nothing but the next half of the 8-byte EGG. The memory address in ECX completing both the SCASD operations successfully will yet again increment EDI by four which will bring us to the start of the shellcode. We merely have to jump to this address to execute our shellcode successfully.

Let’s see some action as follows:

Cracking Eggs with EggHunters
Just Before Jumping to EDI

As we can see from the above screenshot, right before jumping to the address pointed by EDI, Zero Flag was set (Due to SCASD and it also increments EDI by 4) and we are led to the shellcode by EDI. Examining the address in EDI, we have the following output:

Cracking Eggs with EggHunters
116 Bytes starting at the address pointed to by EDI

This is nothing but our shellcode 😉 which will get executed and provide us with a beautiful looking bind shell when connected.

Let’s see the program in action as follows:

Cracking Eggs with EggHunters
Egg Hunter in Action

The Final code for the demo implementation of the shellcode is as follows:

Original source code: Open the archived GitHub Gist

Files for this tutorial can be found at:

https://github.com/nipunjaswal/slae-exam/tree/master/ASSGN-3

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student-ID: SLAE-1080


2026 archival context

This article documents historical 32-bit Linux exploit-development research and tooling. Modern systems commonly add architectural, compiler and operating-system protections that change build and execution behaviour. The material is retained for controlled labs, defensive understanding and the historical research record.

Authorisation notice: Test only on systems you own or are explicitly authorised to assess.

Written by: Nipun Jaswal

Rate it
Previous post

Similar posts