python pwntools CTF exploit sicurezza binary pwn

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+D o 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

MetodoDescrizione
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

Nota etica: pwntools deve essere utilizzato esclusivamente in ambienti autorizzati (CTF, laboratori, sistemi propri). L’accesso non autorizzato a sistemi informatici è illegale.