Exploitation 101
Buffer Overflow
Par Israël Hallé
Adapté par Olivier Arteau
Plan de la présentation
- Concept de base
- Exploitation d'un « buffer overflow »
- Remote Code Execution (RCE)
- Outils et trucs pouvant aider au reversing ou à l'exploitation d'un programme
Concept Important
- Registre du CPU
- Appel de fonction
- Structure de la pile
Registre du CPU
- Instruction Pointer (EIP)
- Stack Pointer (ESP)
- Base Pointeur (EBP)
- General Purpose Register (EDI, ESI, EAX, et cie)
- 64 bits: RDI, RSI, RAX, RBX, RCX, RDX
- 32 bits: EDI, ESI, EAX, EBX, ECX, EDX
- 16 bits: DI, SI, AX, BX, CX, DX
- 8 bits: AL, AH, BL, BH, CL, CH, DL, DH
call, ret
- call fn
- push $eip
- jmp fn
- ret
- pop $eip
Appel de fonction (C)
int hello(int a, int* b, int c) { int hello_var = 0xdeadbeef; return 0xf00; } int main() { int main_var = 0x0; int result = hello(main_var, &main_var, 0x123456); return 0; }
Appel de fonction (x86)
main
hello
Appel de fonction (Pile)
Buffer Overflow
int main() { int some_var = 0; char buffer[12]; fgets(buffer, 9001, stdin); return 0; }
Stack avant fgets
Stack après fgets
Shellcode
-
In computer security, a shellcode is a small piece of code used as the payload in the exploitation of a software vulnerability.
Exploitation avec Shellcode
- Insérer Shellcode en zone mémoire exécutable
- Est-ce que la stack est exécutable?
- Autre segment exécutable?
- mmap PROT_EXEC?
-
Pointer EIP vers le shellcode
-
Adresse de retour
-
Virtual Table (C++)
-
Call ou Jmp sur registre
-
GOT
-
Shellcode courant
- Source:
- Base de donnée http://shell-storm.org/shellcode/
- Plusieurs OS et Architecture
- pwnlib.shellcraft.*
- Base de donnée http://shell-storm.org/shellcode/
- Utilisation
- Reverse TCP
- /bin/sh
- dup
Reverse TCP
- Plus courant lors des CTFs
- Avantage:
- Ne dépends pas de stdin et stdout
- Fonctionne pratiquement partout
- Désavantage:
- Requiert que le service exploité puisse se connecter à un serveur de l'attaquant
- Shellcode un peu plus long et compliqué
Reverse TCP
- Exemple: http://shell-storm.org/shellcode/files/shellcode-883.php
- Utilise Netcat comme serveur
- nc -lvp 31337
- Une fois l'exploit envoyé, le serveur devrait recevoir une connexion. Cette connexion peut maintenant être utilisée comme remote Shell
-
cat ./flag.txt
-
exec /bin/sh
- Un peu moins utilisé lors des CTFs
- Avantage:
- Shellcode généralement très court et ne requiert aucune modification
- Utilise la connection déjà instaurée
- Désavantage:
- Dépend de l'utilisation de stdin et stdout
exec /bin/sh
- Exploitation à partir d'un script:
- Ex: http://shell-storm.org/shellcode/files/shellcode-851.php
- Envoie l'exploit
- Envoie une commande Bash
- Reçoit le résultat
-
p.send(exploit) p.send('cat flag.txt\n') print p.recv(1024)
dup
- Permet de rediriger un file descriptor vers un autre
- Utile pour rediriger stdout vers une connexion déjà ouverte.
- Généralement on utilise :
- dup + /bin/sh
- reverse_connect + dup + /bin/sh
x86-64
- Registre 64 bits:
- RIP, RBP, RSP, RDI, RSI, RAX, RBX, RCX, RDX, R10, R8-15
- Appel de fonction (Linux)
- Arguments passé via registre:
- RDI, RSI, RDX, RCX, R8, R9, stack
- Arguments passé via registre:
- Pointeur 8 bytes
Structure courante d'un challenge
- setuid, setguid
- Besoin d'un utilisateur pour les tests
- set sigalarm
- Kill process after X seconds...
- configure socket
- bind() socket on X port
- accept() + fork()
- challenge!
- Return to 3
GDB Tips
- Use gdbinit file
- ~/.gdbinit
- gdb -x gdbinit
- Use intel syntax (Same as IDA)
-
set disassembly-flavor intel
-
- Set memory breakpoint
- b *0x804020
- Follow child fork
- set follow-fork-mode child
- Stay attached to parent on fork
- set detach-on-fork off
GDB Tips
- List debugged thread and attach to X thread
- info thread
- thread X
- Execute next instruction
- si, ni, c
- Print register or memory value
- x/x $ebp
- x/4gx 0x7ffff40
- x/s $ebp - 0x10
- Display instruction after each step
- display/i $eip
- Display return address
- info frame
Readelf
- Lister les segments et leurs propriétés
-
readelf -l program
-
Win!
Python struct
- Mdule python pour convertir des nombre en bytes ou
vice-versa en spécifiant le type de donnée - Ex:
-
struct.pack("<I", 0x1234)
-
b"\x34\x12\x00\x00"
-
-
struct.unpack("<I", b"\x34\x12\x00\x00")
-
(0x1234, )
- Retourne un tuple
-
- https://docs.python.org/2/library/struct.html#format-characters
-
- Format courant :
- <I = 32 bits
- <Q = 64 bits
pwntools
- Suite d'outils en python très complète fais spécialement pour les CTFs et l'exploit
- https://github.com/Gallopsled/pwntools
pwntools
- Code de base
from pwn import *
context(arch = 'amd64', os = 'linux')
r = remote('192.168.4.178', 1239)
data = r.readline() # Réception
r.send(data) # Envoie
r.interactive() # Le terminal devient l'entrée et la sortie
Exploitation 101 - Formation
By Olivier Arteau
Exploitation 101 - Formation
- 1,714