giovedì 15 dicembre 2011

Protostar Net2 writeup

Questo livello fa capire quanto importante siano le tuple... Imparate ad usarle perchè mi servivano per il livello zero di Vortex, questo tuple sono molto importanti negli script per la comunicazione... Spesso i dati sono inviati proprio come tuple, quindi saper identificare una tupla è molto importante... Infatti in un primo momento non capivo dove fossero gli altri 2 valori da sommare, che fine avessero fatto... Questo perchè avevo poco studiato il codice di Net2... Infatti non mi ero molto soffermato sul fatto che ci fosse una tupla definita dentro al codice C:

Da questo codice troviamo la porta sulla quale è in ascolto il servizio ed appunto la tupla... E troviamo la condizione da soddisfare, quell'if(result == wanted)... Io mi appoggio sempre a python per scrivere del codice, perchè è veloce... Anche se potevo decisamente migliorarlo... Ma non riesco ad assegnare una variabile al nome dentro ad un ciclo for... Piccoli problemi... Il codice tramite un ciclo for sarebbe stato più corto, ma insomma, io non ho mai studiato python... Questo il codice:

Questo codice fa largo uso di tuple... Nel primo dato ricevuto, salviamo solo la prima posizione, essendo comunque composto da un solo dato questa tupla... Nel secondo dato, salviamo i 3 dati della tupla... Poi assegnamo questi 3 valori a tre variabili(qua volevo mettere l'if, oppure usare la tupla direttamente senza passare per altre variabili, ma vabbè) e poi si somma tutto... Ho dato un print per avere un'idea della somma ed ho inviato i dati alla macchina sempre utilizzando struct... Per ultimo ho ricevuto il messaggio di successo... Questo livello mi è piaciuto...

mercoledì 14 dicembre 2011

Protostar Net1 writeup

Questo livello è praticamente identico al precedente... L'unica differenza trovata sta nella funzione strcmp(). Questa funzione effettua una comparazione di stringhe, quindi ho inviato il dato come stringa... Nulla di più... Ma ho risolto il problema da remoto, così da sfruttare geany, il mio editor preferito... Infatti presenta quella tab 'terminale' che mi consente di avere sotto il codice un terminale, così da non dover passare dall'editor al terminare vero e proprio esterno... Questo il codice del livello da cui ricavare la porta... L'indirizzo ip della macchina remota potrebbe essere diverso, ma penso di non doverlo nemmeno dire...

Appunto si legge che la porta sulla quale è attivo il servizio è la 998, e che l'if controlla due stringhe... strcmp() ritorna 0 se le stringhe sono uguali... Si legge benissimo nella pagina dedicata a strcmp()... Io ho usato sempre python, perchè consente, a chi non lo conosce, di poterlo sfruttare molto.. Ed ho usato le tuple... Per chi non ricorda cos'è una tupla, rimando alla pagina relativa al primo livello del wargame Vortex presente su OverTheWire, lì ho spiegato bene perchè alla fine di unpack() aggiungo [0]... Quindi questo il codice:

Provo a spiegare questo script... Alla settima riga si connette all'indirizzo della macchina remota sulla porta 2998, salva il primo dato, lo stampa sulla shell(io stampo tutto :D ) poi tramite struct lo spacchetta salvando solo il primo dato della tupla, mi stampa sulla shell il valore, salva questo valore come stringa, lo invia alla macchina e stampa il messaggio di invio corretto... Penso che sia abbastanza semplice e questa volta non presenta problemi...

Sicuramente si può ottimizzare, saltando un paio di passaggi ed un paio di print... Ma io gradisco i print per vedere se qualcosa va storto... E si poteva saltare il passaggio separato dell'unpack inserendolo dentro alla funzione str, sempre che questa accetti il dato... Non ho provato, perchè secondo me va bene così...

Protostar Net0 writeup

Mi sono bloccato al livello 5 della stessa macchina, devo ben capire come iniettare la shellcode... Per non fermarmi, e visto che di solito i primi livelli sono molto semplici, ho deciso di procedere con questo livello... Io l'ho fatto in locale questa volta, ma si poteva fare benissimo in remoto... Non cambia nulla, solo l'indirizzo della macchina... Visionando il codice del livello:

si capisce molto bene come procedere... Vogliamo soddisfare la condizione presente nell'if(i == wanted) per ottenere il messaggio corretto... Anche se wanted è un numero random, ci viene fornito dal primo printf()... Quindi non dobbiamo fare altro che leggere il dato ed inviarlo alla macchina, ovviamente come little endian 32 bit int...

Al solito mi affido al python... Molto semplice da utilizzare, e risolviamo tramite il modulo struct. Questo modulo ci permette con un semplice passaggio di inviare i dati in little endian... Prima di risolvere questo wargame si deve lanciare l'applicazione tramite il comando /opt/protostar/bin/net0... Poi in /tmp/ mettiamo il codice python e lo avviamo... Finiremo così il livello... Questo il codice:

Provo a spiegare come funziona lo script, anche se è semplicissimo... Alla settima riga si connette alla porta 2999(definita dal codice C), memorizza i dati inviati nella variabile dato, che per mia maggior comprensione stampa sulla shell... Da questa riga estrae il numero inviato random, lo stampa di nuovo sulla shell, lo converte poi come intero e lo passa alla funzione pack(), dove i simboli hanno chiaro significato se si è sbirciato il link precedente di struct... Lo invia alla macchina e riceve il messaggio di risposta dalla macchina...

Piccola pecca dello script... A volte la macchina manda un numero con un carattere in meno, quindi il codice salva anche l'apice che si trova alla fine del numero... In questo caso si ottiene un errore da parte della funzione num()... Niente di preoccupante, si riavvia lo script tante volte finchè il numero non è composta da 10 caratteri... Purtroppo non ho così esperienza da estrarre un numero da una stringa di caratteri... Avevo provato con il modulo re, ma quel 32bit finale non mi permette di utilizzare una sostituzione di caratteri... Quindi anche se non è la soluzione più bella, questa è una soluzione funzionante quando il numero inviato è di 10 caratteri... L'importante è finire...

sabato 10 dicembre 2011

Protostar Stack4 writeup

Il quarto livello degli stack overflow è praticamente identico al terzo livello, fatta eccezione che per sovrascrivere l'eip si ha bisogno di scrivere molto di più oltre al buffer, perchè come suggerisce anche il livello stesso negli hint, l'eip potrebbe non essere subito dopo il buffer... Ma in questo caso, con l'aiuto di un tool fornito dal pacchetto metasploit, si trova facilmente quante A scrivere per arrivare al buffer... Alla fine è completamente identico... Qui il codice del livello:

Il codice è comprensibilissimo anche per chi non conosce il C, l'obiettivo è richiamare una funzione, win(), che è inutilizzata durante il main()... Questi i comandi da dare per arrivare alla soluzione:

I due comandi pattern* vanno dati sulla macchina attaccante, e di solito i tools di metasploit si trovano in /opt/metasploit-4.1.4/msf3/tools/... Con pattern_create si realizza una stringa di caratteri da utilizzare quanto sovrascrivere prima di arrivare all'eip, quanto passare per ottenere la segmentation fault... Mentre con pattern_offset si ottiene proprio il valore che viene usato per scrivere, di solito la lunga serie di A...

Si ottiene che l'offset è di 76 char, poi abbiamo i 4 byte da assegnare all'eip, reindirizzandolo dove vogliamo, cioè alla funzione win(), come fatto nel livello precedente... Ecco il codice python da usare:

Come sempre gli indirizzi saranno diversi da macchina a macchina... Quindi il mio
0x63413563 sarà dverso, come pure l'indirizzo che io ho assegnato a shellcode dentro al codice python... Che è stato ribaltato per tenere conto del fatto che la macchina è in little endian... Quindi il byte più rappresentativo è all'ultimo posto... Io in questo modo ottengo il messaggio code flow successfully changed, ma anche il segmentation fault... Non sono riuscito ad eliminarlo, ma l'importante è ottenere il messaggio...

venerdì 9 dicembre 2011

Protostar Stack3 writeup

Era da un po' che non effettuavo un buffer overflow leggermente complesso... Questo è si facile, ma sicuramente su un livello superiore rispetto agli altri 3 livelli precedenti... Non mi ricordavo assolutamente niente... Quindi ho riguardato il mio video sul mio primo buffer overflow:



Quindi riguardando questo video mi è venuto di nuovo tutto in mente... Quello che cerchiamo è una "Segmentation fault" , quell'errore che ci permette di controllare l'eip, l'instruction pointer e rimandarlo dove più ci piace... La macchina, come già sappiamo, riceve i dati in little endian, quindi tutti gli offset vanno invertiti, dal byte più significativo all'ultimo, mentre gdb ce li restituisce in little endian... Alla fine si tratta solo di capovolgere l'offset...

In questo caso poi non ho usato il pattern_create di metasploit... Abbiamo il codice sorgente che ci informa del buffer, quindi stampiamo 64 A e abbiamo riempito il buffer... Ne aggiungiamo altre 4 per controllare che possiamo sovrascrivere l'eip, e fatto questo sempre con gdb troviamo l'offset della funzione win presente nel codice a cui ricollegarci... Il codice di questo livello è:


Qui si legge perchè io vado a cercare la funzione win, perchè così è definita dentro al codice sorgente. Ecco i comandi per gdb:


Il programma non mi accettava dentro python... Non so come mai... Ma tanto cambia poco... Con i r vediamo che l'eip è stato sovrascritto e con disassemble win troviamo il valore dell'ebp a cui ricollegarci... Per ogni macchina i valori sono diversi... Quindi i valori qui riportati potrebbero essere diversi, ma cambia poco... Dalla schermata di disassemble win prendere il primo valore in alto, quello con scritto accanto... Io riporto il mio codice a cui cambiare solo l'offset... Ovviamente in python:
Otteniamo così la frase code flow successfully changed...

mercoledì 7 dicembre 2011

Protostar Stack2 writeup

Oggi ho risolto questo livello... Solo uno per oggi... Questo livello presentava questo codice:

Il codice si comprende abbastanza... E' molto chiaro... La funzione getenv() chiama una variabile d'ambiente, e se non esiste ci ritorna il primo messaggio d'errore... Il nostro compito è effettuare uno stack overflow ed assegnare a modified il giusto valore... Come al solito il buffer è definito in alto di 64 caratteri... Quindi ho provato un po' fino ad ottenere, grazie all'aiuto di andrewg che si trova nella chat di overthewire, la soluzione al problema...

La mia soluzione avrebbe funzionato sul mio sistema attaccante(lubuntu 11.10 modificato) ma sul sistema protostar non funzionava... Non perchè errata, ma perchè export non accetta quello che gli passavo... Non mi era assolutamente passato in mente di definire la variable e poi assegnarla tramite export... Non pensavo che così l'avrebbe accettata, pensavo che l'errore sarebbe rimasto... Invece così funziona... Non so assolutamente perchè... O l'accetti sempre o non l'accetti mai... Ed io che pensavo che la mia soluzione fosse sbagliata... Ecco qui il codice:

Poche righe anche questa volta... Io uso sempre python per la sua semplicità... E perchè si capisce al volo... In pratica stampiamo 64 A seguite dal valore della variabile modified che vogliamo sovrascrivere... Otteniamo il messaggio di successo... Ho dato solo uno sguardo a stack3.... Non ho mai trovato prima d'ora una variabile con gdb e objdump... Ogni aiuto è ben accetto...

martedì 6 dicembre 2011

Protostar Stack1 writeup

Questo livello è un po' più divertente... Questi sono old style hack... Oggi difficilmente si troveranno nella vita reale... Questo il codice del livello 1:

Qui si nota la funzione strcpy()... Famosissima insieme alla funzione gets() per essere vulnerabile... Però dobbiamo anche ricordarci, come dicono pure le istruzioni del livello, che la macchina opera in little endian... Quindi la nostra variabile ha il byte più significativo per ultimo... Io ho risolto il livello con l'uso di gdb, perchè altrimenti non riuscivo a passare il livello... Non so... Alla fine cambia poco, il livello lo si passa ricevendo la frase di esecuzione riuscita... Quindi faccio:

Quello che si va è passare al programma 64 A più il codice richiesto in little endian... Infatti il 64 prima è nella parte finale invece nel codice è il primo dato, per la regola che il byte significativo in little endian è l'ultimo...

Protostar Stack0 writeup

Visto che sono bloccato(penso di aver trovato la vulnerabilità, ma non riesco a sfruttarla) al livello9 del Nebula CTF, ho deciso di dedicarmi un po' al Protostar CTF... Per scaricare l'immagine basta andare su sito di exploit-exercises e seguire le indicazioni... Questa prima release potrebbe avere bugs... Ma procediamo con il primo semplicissimo livello... Stack0... E' forse il più semplice caso, quello che si incontra sempre... Quello che viene sempre preso come esempio di buffer overflow... Il codice è semplice:

Tutto il problema sta nella funzione gets()... Questo ci permette appunto di sovrascrivere il buffer e cambiare la variabile... Io uso il python, perchè è abbastanza semplice ed immediato... Questo il comando usato:

python -c 'print "\x41"*65' | ./stack0

Questo comando passa al programma 65 A... Quindi sovrascriviamo il buffer di 64 byte... Ok, per spiegarmi meglio rimando al sempre bello articolo di phrack Smashing The Stack For Fun And Profit_by_Aleph1 che è sempre bene leggere. Qui finisce il livello zero... Otteniamo infatti la frase:
you have changed the 'modified' variable

sabato 3 dicembre 2011

Nebula level08 writeup

Questo livello richiede di analizzare un file pcap... Cosa semplice se si analizza in locale con wireshark... Quindi mi sono segnato la posizione del file e l'ho copiato con scp... Ho avviato wireshark, aperto il file, cliccato sulla prima comunicazione con il tasto destro, selezionato "Follow TCP Stream" ed ottenuto il codice... Questa password non funziona da nessuna parte, probabilmente perchè è per un'altra macchina... Ma alla fine il lavoro è fatto... Ecco il comando con il codice che si ottiene:

La password è contenuta qui "Password: backdoor...00Rm8.ate"... Strano che la comunicazione non sia criptata per dare un tocco più carino al livello...

Nebula level07 writeup

Questo livello ha una vulnerabilità nel codice perl, perchè non controlla i parametri passati come Host... Quindi si può passare qualsiasi cosa che il codice comunque prenderà per buona... Ci serve un solo comando per l'exploit...
http://nebula:7007/index.cgi?Host=x%0agetflag
Come si legge dal file thttpd.conf lo script ha i permessi di flag07, quindi ci permette di lanciare getflag... Ovviamente otterremo così il codice di successo...

Nebula level06 writeup

Questo livello proprio non l'ho capito... Non saprei perchè si è fatta una cosa del genere... La password di flag06 è mostrata in chiaro dentro a /etc/passwd... Non ci resta che copiarla, crackarla con john e loggarci tramite ssh con l'accout flag06... Avviare getflag che ci infermerò del successo... Molto veloce...

L'uso di john è immediato se già altre volte lo si è usato, ed ho preso una wordlists contenuta nel pacchetto di metasploit... Livello semplice e veloce...

Nebula level05 writeup

Questo livello era basato sulle deboli impostazioni dei permessi di un file... Infatti il file che ci interessava era un backup presente in una cartella nascosta con permessi -rw-rw-r-- ... Significa che il nostro permesso era solo in lettura(read)... Ma abbastanza per copiarlo ed estrarlo nella cartella /tmp, e leggerne il contenuto... Anche in questo livello niente getflag... Dopo l'estrazione si ottiene la cartella .ssh, con 3 file importantissimi...Ecco i comandi:

Il livello finisce così... Si passa al livello 06...

giovedì 1 dicembre 2011

Nebula level04 writeup

Anche questo livello è stato molto semplice... Io però ho trovato un problema... Che ho risolto sempre grazie a Steven che si presta sempre ad aiutare... Lo potete trovare nella chat di overthewire... Il mio problema era dovuto all'uso improprio di ln -s... Perchè il link del file sorgente e del file destinazione devono avere gli indirizzi completi, estesi... Io sbagliavo quello...

Come sempre leggere le istruzioni del livello porta notevoli vantaggi... Dal codice risulta la funzione strstr(), che ci vieta di aprire il file token, che è il nostro obiettivo... Se l'argomento passato contiene token allora la funzione è diversa da NULL, se invece la condizione non è soddisfatta si ottiene NULL... Più informazioni qui...

Quindi creiamo un link simbolico al token, chiamandolo in modo diverso, così da bypassare il controllo:


Questi sono i comandi... Si ottiene un certo codice contenuto dentro al token...

Nebula level03 writeup

Questo livello si risolve abbastanza facilmente... Non otterremo una shell interattiva, ma un file di log che ci indica che il nostro obiettivo è stato raggiunto... Qui le info del livello:
Check the home directory of flag03 and take note of the files there.
There is a crontab that is called every couple of minutes.
Importante capire lo script bash che viene eseguito in crontab ogni 2 minuti... Infatti lo script, per ogni elemento presente nella cartella writable.d, esegue il comando bash -x $i... Quindi noi creiamo un file dentro questa cartella, e poi leggiamo il log che inseriremo in /tmp... Non ho ben capito perchè apre il file invece di eseguire il nome del file... Però funziona... Infatti dentro al file di log dentro /tmp troveremo la frase di successo... Ecco i comandi da dare... Ovviamente prima di leggere il log bisogna aspettare il crontab...

Qui finisce il livello 03...

Nebula level02 writeup

Non so se questa è la soluzione corretta, ma getflag mi da il solito successo, quindi credo che almeno sia accettabile... Chiederò se questa soluzione va bene... Comunque seguendo in linea di principio il livello precedente, sono andato a modificare con il comando export la variabile d'ambiente USER... Ho usato un solo comando e poi ho lanciato il programma...
export USER="level02;getflag"
/home/flag02/flag02
Credo che sia tutto qui...