domenica 21 dicembre 2008

Format String Overflow: Completamento al 50%

Sono giunto alla metà abbondante del capitolo format string overflow. E' interessante come ci siano degli usi poco noti di questa tecnica. Solitamente si tende a sovrascrivere un puntatore nel GOT o nella sezione DTORS per eseguire uno shellcode. Nelle vecchie distribuzioni potevi anche alterare la sezione PLT o il punto in cui veniva mappata la funzione _fini(). Oggi comunque entrambi quest'ultimi vengono mappati in aree eseguibili ma non modificabili (basta elencarle con readelf per accorgersene). Un qualsiasi tentativo di scrittura causerà quindi un crash dell'applicazione.

Per fortuna esistono ancora molte distribuzioni (Slackware, Debian ed Ubuntu tanto per fare qualche nome ) che permettono di copiare uno shellcode in aree scrivibili (non executable quindi) ma che una volta accedute dal GOT (o da qualsiasi altra zona "puntatore") permettono di eseguire lo shellcode. Le cose si complicano notevolmente comunque in presenza di distribuzioni con funzionalità simili ad Exec Shield (Fedora/RHEL o quelle distro hardenizzate con GrSecurity). L'exploiting diventa assai difficile ma non impossibile.

Per non parlare poi delle applicazioni compilate con FORTIFY_SOURCE. Questa è una bella bestia che rende impossibile l'utilizzo dell'operatore "%n" in zone di memoria su cui si potrebbe scrivere, ma ne parlerò magari in un altro intervento del blog.

A presto

venerdì 5 dicembre 2008

Enter The Format String Overflow

Ho completato il capitolo che ho già dettagliato nel precedente post. Adesso passerò ai format string overflow. Oggi ho anche definitivamente abbandonato l'idea di lanciare il mio libro per il periodo natalizio. Non ci arrivo. Ogni tanto mi distraggo e lavoro :P

Forse è meglio così. Il 2008 è stato un anno difficile (non parlo della crisi economica, ma proprio a livello personale). Magari il 2009 porterà più fortuna. Una considerazione poi va indubbiamente alla frequentazione di questo blog. In effetti comincio a temere di essere l'unico a leggerlo :<

domenica 30 novembre 2008

Off-by-one / Off-by Few e blocchi di memoria adiacenti

Ho terminato il capitolo sull'Address Space Layout Randomization da una settimana. Purtroppo impegni di lavoro mi hanno tenuto impegnato più del dovuto ed ho potuto lavorare al mio libro solo negli orari notturni in cui solitamente sono meno lucido. Non riesco più a fare come un tempo, a passare intere nottate davanti al PC...quindi fino a qualche giorno fa ho svolto principalmente un lavoro di revisione del pregresso.

Ho cominciato il capitolo sugli Off-by-one / Off-by-few da poco quindi.

In merito agli off-by-one gli scenari più importanti che sto descrivendo sono due. Il primo è quando, all'interno di una funzione, il buffer che viene sovrascritto di un byte oltre le sue reali capacità di contenimento si trova in testa alla funzione stessa. In questo caso l'overflow può alterare il byte meno significativo (che nei sistemi little-endian si trova prima in memoria) dell'indirizzo del frame della funzione chiamante salvato nello stack. Nelle distribuzioni Linux più recenti però, il compilatore gcc aggiunge del padding e dilata la distanza in memoria tra il buffer ed il frame pointer, quindi solitamente si può arrivare ad alternarne l'indirizzo con un off-by-few.

Il secondo scenario tratta i blocchi di memoria adiacenti. In alcuni casi, giocando sul comportamento di alcune funzioni libc che non terminano le stringhe con il carattere NULL (ad esempio nel caso di strncpy() se source non è minore di len) si può rendere due blocchi di memoria contigui un unico blocco. Ciò può causare problemi più avanti nel codice dell'applicazione. Non si tratta di un off-by-one nel vero senso della parola ma mi è sembrato il giusto capitolo in cui inserire questo scenario.

domenica 16 novembre 2008

Capitolo su ASLR quasi terminato

Tra oggi e domani penso che completerò il capitolo sull'Address Space Layout Randomization. Ho analizzato tutti gli scenari possibili ed immaginabili (RET2ESP, RET2RET, RET2EAX e RET2REG in generale). Adesso mi rimane solo da presentare la parte relativa a Return into Libc coadiuvata da un'attacco bruteforcing. Se in un sistema con ASLR osservate infatti come cambia durante l'esecuzione ripetuta di un programma lo spazio di indirizzamento dello stack e degli indirizzi libc , noterete un notevole mutamento. Ma se ad essere in esecuzione in memoria è un servizio (processo parente) che ad ogni connessione di un client genera un processo figlio per gestire la risultante richieste, bhe l'organizzazione dello stack e gli indirizzi in memoria di funzioni importanti come system() o execl() rimarranno sempre gli stessi da figlio a figlio (almeno fino a quando il parente non verrà riavviato). Ciò spalanca le porte ad un possibile scenario di brute-forcing che necessita di un numero di tentativi limitato prima di concludersi con successo. E' proprio l'ultima parte che sto trattando in questo capitolo.

Bau!

mercoledì 12 novembre 2008

Capitolo ASLR quasi terminato

Sono quasi giunto al termine del capitolo che parla dell'Address Space Layout Randomization. Mi manca un'ultima parte. Nel frattempo ho buttato su carta l'organizzazione del capitolo 4 "Off by one / Off by few". Ora che ci penso non ho mai descritto quali categorie di buffer overflow sto esaminando nel mio libro:

- Stack Overflow
- Off by one / Off by few Overflow
- Format String Overflow
- Heap Overflow
- Integer Overflow

Dicevo che prossimamente mi cimenterò nel capitolo degli off by one/off by few overflow. Qui mi trovo ad un bivio. Alcuni off by one si manifestano nello stack, altri invece nell'heap. Poiché intendo trattare gli heap overflow nei capitoli 8 (basic) e 15 (advanced), credo che dovrò dividere la trattazione sugli off by one/ off by few anche su due capitoli diversi.

domenica 9 novembre 2008

Organizzazione del libro

L'organizzazione del libro ce l'ho già in testa da un pò. Ho buttato una bozza dei capitoli presenti ma per adesso mi soffermerò più su linee generiche. Il book sarà suddiviso in due parti. Nella prima(composta da dieci capitoli) affronterò le basi per chi ha solo un'infarinatura di questi argomenti alternando un capitolo teorico ad uno o più pratici. Ovvero, se dovrò orientarmi sugli Heap Overflow, il capitolo prima sarà immancabilmente una trattazione su cosa è l'heap, le operazioni che vi si possono condurre, i controlli, etc.. Idem con patate per lo Stack. Se devo parlare di format string overflow, prima è doveroso capire cosa sono le sezioni GOT e PLT di un file ELF, così come prima di parlare di integer overflow vi sarà un capitolo che tratterà la parte teorica, ovvero come il sistema effettua i calcoli sugli interi e roba simile.

Immancabilmente i capitoli teorici saranno molto più brevi di quelli pratici. Ad esempio ho già terminato quelli su Stack Overflow. Il teorico (capitolo 2) è venuto 9 pagine, il pratico (capitolo 3) sono 45 pagine. Ho anche terminato il teorico su Global Offset Table e Procedure Linkage Table (capitolo 5) ed è venuto di 16 pagine.

La seconda parte del libro (per il momento altri 5 capitoli) parlerà degli argomenti più avanzati, principalmente di tutte quelle migliorie introdotte nei kernel 2.6. La prima parte si può invece considerare più orientata alle installazioni con kernel 2.4 (che sono ancora numerosissime in rete). Al momento stavo lavorando sul capitolo 11 della seconda parte del libro (Address Space Layout Randomization). Penso di essere verso la metà dell'argomento e sono già a 26 pagine.

Ovviamente gli scenari che sto trattando sono sia locali che remoti ed in ogni capitolo pratico, alla fine, sto mettendo anche casi di exploit reali, insomma non semplicemente quei programmini di esempio con strcpy() utilizzato a minchia tanto per far vedere come un buffer viene sovrascritto (non fraintendetemi, all'inizio sono importanti ma poi per far pratica bisogna pur elevarsi con casi reali).

Se 15 capitoli vi sembrano una cosa da poco considerate che il target dell'argomento è solo Linux. Inoltre questo è un libro specifico sui buffer overflow e non un calderone dispersivo su altri temi, come spesso sono invece organizzati altri testi.

sabato 8 novembre 2008

Perchè un altro libro sui buffer overflow

Ultimamente mi è capitata tra le mani la seconda edizione di Shellcoder's Handbook, un libro inglese edito da Wiley, che aspira a fare luce su alcune classiche tematiche hacking fra le quali i buffer overflow. Il tizio che me lo ha mostrato durante un mio intervento sulla sicurezza in un convegno a Roma organizzato da un cliente per cui lavoravo, era tutto felice e non stava più nella pelle per l'uscita di questa nuova edizione. In realtà sfogliando il testo ne sono rimasto profondamente deluso. Avendo acquistato la prima edizione nel 2004, ho notato che da allora non è stato aggiunto molto materiale (a parte qualche capitolo di rintoppo qua e là come quello sugli apparati di rete Cisco). Ad esempio, le tecniche di buffer overflow descritte sono rimaste esattamente quelle di 4 anni fa, quando ancora la pressocché assenza in quasi tutte le distribuzioni Linux di meccanismi di protezione come ASLR e Propolice (tanto per citarne un paio) permetteva di piazzare uno shellcode ovunque in memoria ed eseguirlo. Mi verrebbe da dire però a Litchfield, Koziol, Aitel e compagni che siamo già nel 2008. Oggi non puoi pensare che Exec Shield non si incazzi quando provi a fare ritornare una funzione verso un'indirizzo dello stack o che la macro unlink() sia così stupida da non fare un controllo di base per capire se l'heap è corrotto o meno. Shellcoder's Handbook seconda edizione si limita invece solamente a dare qualche consiglio e fare qualche accenno sui moderni "ostacoli". Nessuna nuova tecnica, nessun esempio pratico, nessuna sessione di debugging! Solo vaghi riferimenti sul web. Al momento inoltre non esiste, a mio parere, nella letteratura esistente, un buon testo che discuta su questi temi anche prendendo in considerazione gli ultimi meccanismi di protezione implementati dalle recenti distribuzioni Linux. E' per questo che ho deciso di iniziare a scrivere un libro sull'argomento buffer overflow. Ci sto già lavorando da circa un mese e nei prossimi giorni approfitterò di questo blog per informare sullo "stato di avanzamento lavori", sulle modalità di pubblicazione, sugli argomenti trattati ed ovviamente rimarrò sintonizzato sui commenti ed i pareri degli utenti della rete. Per i tempi di rilascio non so ancora dire nulla di certo. L'auspicio è di riuscire a pubblicarlo prima di natale.