La Libreria pwntools di Python
pwntools è una libreria Python progettata per semplificare il processo di scrittura di exploit e l’interazione con servizi remoti e file binari durante competizioni di sicurezza informatica come le CTF (Capture The Flag).
Installazione
pip install pwntools
Funzionalità principali
- Interazione con processi: avvia e interagisci con processi locali
- Connessioni remote: connettiti a servizi via TCP o UDP
- Costruzione di payload: facilita la creazione di payload per exploit
- Manipolazione di dati binari: strumenti per lavorare con dati binari e formati specifici
- Debugging e disassemblaggio: integrazione con debugger come GDB
Connessione a un servizio remoto
from pwn import *
# Imposta il livello di log (debug mostra tutti i dettagli)
context.log_level = 'debug'
# Connessione TCP remota
conn = remote('example.com', 1234)
# Riceve una riga dal servizio
welcome_message = conn.recvline()
print(welcome_message)
# Invia dati al servizio
conn.sendline('Hello, server!')
conn.close()
Ricezione di dati
recvuntil() — legge fino a una stringa specifica
from pwn import *
conn = remote('example.com', 1337)
# Legge tutti i dati fino a 'Username:'
data = conn.recvuntil(b'Username:')
print(data.decode())
# Invia la risposta
conn.sendline(b'mario_rossi')
recvuntil() è il metodo più usato nelle CTF: legge continuamente fino a quando non trova la stringa cercata, poi si ferma.
recvline() — legge una riga alla volta
from pwn import *
conn = remote('example.com', 1337)
while True:
line = conn.recvline()
print(line.decode())
if b'Password:' in line:
break
conn.sendline(b'super_secret')
Utile quando non si sa esattamente in quale riga apparirà il prompt atteso.
recvn() — legge un numero esatto di byte
from pwn import *
conn = remote('example.com', 1337)
# Riceve esattamente 1024 byte
data = conn.recvn(1024)
print(data.decode())
Modalità interattiva
Dopo aver automatizzato una parte dell’interazione, interactive() cede il controllo all’utente:
from pwn import *
conn = remote('example.com', 1337)
# Automatizza l'autenticazione
conn.recvuntil(b'Username:')
conn.sendline(b'mario_rossi')
conn.recvuntil(b'Password:')
conn.sendline(b'super_secret')
# Passa il controllo all'utente
conn.interactive()
In modalità interattiva:
- tutto l’input da tastiera viene inviato al servizio
- l’output del servizio viene mostrato in tempo reale
- per uscire:
Ctrl+Do chiudendo la connessione lato server
Esempio completo
from pwn import *
context.log_level = 'debug'
conn = remote('example.com', 1337)
# Legge il messaggio di benvenuto
welcome_message = conn.recvline()
print(welcome_message.decode())
# Autenticazione automatizzata
conn.recvuntil(b'Username:')
conn.sendline(b'mario_rossi')
conn.recvuntil(b'Password:')
conn.sendline(b'super_secret')
# Attende la conferma di accesso
conn.recvuntil(b'Access Granted')
# Passa alla modalità interattiva per esplorare
conn.interactive()
Gestione dei timeout
from pwn import *
conn = remote('example.com', 1337, timeout=5)
try:
data = conn.recvuntil(b'Command:', timeout=5)
except EOFError:
print('Il servizio ha chiuso la connessione.')
except TimeoutError:
print('Timeout raggiunto senza ricevere il prompt.')
Pattern matching con expect()
Quando il servizio può rispondere con output variabili, expect() permette di aspettare uno tra diversi pattern:
from pwn import *
conn = remote('example.com', 1337)
patterns = [b'Option 1', b'Option 2', b'Option 3']
index = conn.expect(patterns)
if index == 0:
print('Ha ricevuto Option 1')
conn.sendline(b'risposta_1')
elif index == 1:
print('Ha ricevuto Option 2')
conn.sendline(b'risposta_2')
else:
print('Ha ricevuto Option 3')
conn.sendline(b'risposta_3')
expect() restituisce l’indice del pattern corrispondente nell’elenco fornito.
Riepilogo metodi principali
| Metodo | Descrizione |
|---|---|
remote(host, port) | Apre una connessione TCP remota |
process(cmd) | Avvia un processo locale |
recvline() | Legge una riga (fino a \n) |
recvuntil(pattern) | Legge fino alla stringa specificata |
recvn(n) | Legge esattamente n byte |
recv(n) | Legge al massimo n byte |
sendline(data) | Invia dati seguiti da \n |
send(data) | Invia dati senza \n |
interactive() | Cede il controllo all’utente |
expect(patterns) | Attende uno dei pattern, restituisce l’indice |
close() | Chiude la connessione |
Risorse
- Documentazione ufficiale: docs.pwntools.com
- Repository GitHub: github.com/Gallopsled/pwntools
Nota etica: pwntools deve essere utilizzato esclusivamente in ambienti autorizzati (CTF, laboratori, sistemi propri). L’accesso non autorizzato a sistemi informatici è illegale.
EC