Art of Shellcoding: 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/
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:
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:
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:
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:
Egg Hunter in Action |
The Final code for the demo implementation of the shellcode is as follows:
Files for this tutorial can be found at:
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
No comments: