SOLUZIONE HiB CTF 2017 Spring Edition

HackInBo Lab Edition
Dalle 23:59 del 31/03/2017 alle 23:59 del 02/04/2017 è stato possibile partecipare alla CTF di HackInBo, organizzata da Voidsec e dagli amici di Hacktive Security.
I primi 45 in classifica avranno la possibilità di accedere ai LAB di HackInBo il 7/05/2017, infatti per la 3° volta, nella sua edizione primaverile, HackInBo durerà 2 giorni, il primo con diversi talk e una tavola rotonda conclusiva, mentre durante il secondo i vincitori della CTF si potranno cimentare in alcuni laboratori tenuti dai relatori e da altri esperti di vari settori legati al mondo della Sicurezza Informatica.

Descrizione

Il nostro team ha partecipato alla CTF e siamo lieti di condividere con voi passo per passo come abbiamo risolto le varie challenge.
La CTF era studiata per rispecchiare uno scenario realistico, ovvero non con l’approccio jeopardy, di conseguenza non si poteva “scegliere” quale challenge fare, ma esisteva un percorso abbastanza (lo vedremo più avanti) ferreo che passava per passaggi obbligati.
Ai partecipanti veniva fornito unicamente un link ad un sito web, che era il punto di partenza della CTF: http://ctf-hib.thesthack.com

Home Page CTF

Flag

It’s Not that hard Flag

Per trovare la prima flag è stato sufficiente visualizzare il sorgente della home page e decodificare il base64 contenuto nel commento HTML.

it's not that hard flag

 

Oh, did I get banned Flag

La CTF era configurata per bannare chi facesse eccessivo utilizzo di tool automatici di scansione (es. Acunetix) e reindirizzava questa tipologia di tentativi verso la pagina 403.php.
Analizzando il sorgente di questa pagina è stato possibile trovare la seconda flag.

Oh, did I get banned Flag

 Tgialli’s User’s Session

Questa flag ha bloccato la maggior parte dei partecipanti alla CTF, infatti era necessario sfruttare una SQL Injection molto difficile da scovare data la posizione insolita e i filtri applicati.
Dopo aver fuzzato tutti i campi disponibili abbiamo provato a lavorare con il cookie settato dalla pagina (PHPSESSID).
Questo cookie normalmente viene impostato alla creazione di una sessione PHP e viene utilizzato per tenere attiva la sessione degli utenti e riferirsi alla variabile $_SESSION lato server in cui vengono normalmente inseriti i dati di sessione di un utente. Dopo aver provato una serie di Payload abbiamo identificato la presenza di una SQL Injection Blind Time Based, tuttavia la presenza di una serie di filtri non permetteva di sfruttarla ed è stato necessario sostituire gli spazi con i commenti di MySQL /**/ e i caratteri <> con la keyword di MySQL BETWEEN.
Malgrado queste accortezze, impostando gli accorgimenti in fase di detection, con sqlmap risultavano dei falsi positivi, di conseguenza è stato necessario effettuare la fase di detection senza utilizzare alcun tamper e la fase di exploitation con i tamper space2comment e between.

Salvando quindi la richiesta ad una delle pagine vulnerabili (es. search.php) in un file req_search.txt e lanciando il seguente comando è stato possibile far riconoscere la vulnerabilità a sqlmap.

Lanciando successivamente questo comando è stato possibile ottenere lo user di MySQL in uso.

Una volta dumpato il database markito_db è stato possibile trovare nella tabella aact il PHPSESSID dello user tgialli, ovvero la flag.

User Flag

Ottenuto il cookie di sessione di tgialli è stato sufficiente impostarlo nel nostro browser per poter accedere come tgialli e recarci in user.php, dove analizzando il sorgente è stato possibile trovare una nuova flag.

User Flag

Admin’s session

Nella pagina user.php abbiamo notato la possibilità di inviare una richiesta di supporto all’amministratore del sito.

Richiesta supporto

Abbiamo innanzitutto provato a mandare una Question con il seguente contenuto, per verificare la possibilità di inserire codice HTML e il fatto che qualcuno (o qualcosa) controllasse le richieste.

Visualizzando gli access.log del nostro server abbiamo visto una richiesta da parte dell’IP del server della CTF con come refferer: http://ctf-hib.thesthack.com/support/support_inquiry_gerijhgrw545427hgt2hjgg8u398.html
Visitando tale pagina abbiamo trovato il nostro payload e questo ci ha dato la possibilità di vedere se e quali caratteri venissero filtrati dall’applicativo. Dopo alcuni tentativi abbiamo scoperto che script, alert e altri caratteri venivano rimossi, quindi abbiamo scritto un payload che rispettasse tali regole con lo scopo di identificare il cookie dell’amministratore, non essendo presente nel DB appena dumpato.

Nei nostri access.log abbiamo ricevuto queste richieste.

Stored XSS

Il cookie dell’amministratore era la nostra flag.

Double Rainbow Challenge

Utilizzando il cookie appena ottenuto è stato possibile accedere alla sezione amministrativa del sito administrator.php (questa pagina è stata ottenuta effettuando una scansione con dirsearch: dirsearch --url "http://ctf-hib.thesthack.com/" -e php).

Administrator.php

Navigando le varie sezioni disponibili abbiamo identificato la pagina settings.php come unica con parametri dinamici, nello specifico caso abbiamo notato la presenza di un cookie editor con il seguente contenuto.

Una volta effettuata una base64_decode abbiamo identificato il seguente oggetto PHP serializzato.

Nella pagina in questione era presente una textarea contente il file asset.css, lo stesso a cui si fa riferimento nella variabile filepath dell’oggetto StyleEditor, di conseguenza abbiamo provato a modificare tale path con quella di altri file, ottenendone il sorgente.

Unserialize File Read

Arrivati a questo punto abbiamo scaricato il sorgente dei file collegati a settings.php, così da poter scoprire se fosse possibile ottenere una Remote Command Execution sul server attraverso la unserialize.

Appena ottenuto il codice un sorriso ci ha coperto i volti, essendo lo stesso codice utilizzato durante la nostra CTF Hands Off My Money.
Fondamentalmente settings.php effettuava una unserialize dell’oggetto presente nel cookie, instanziando 2 oggetti PHP (StyleEditorSecurityCheck) di cui potevamo controllare tutte le variabili pubbliche.
Al __wake_up della classe StyleEditor veniva effettuata una sostituzione nella variabile fullpath dei caratteri presenti nell’array attacks con la stringa presente nella variabile replace, a patto che questa non contenesse nessuna delle stringhe presenti nell’array badwords.
Tale sostituzione veniva fatta dalla funzione preg_replace di PHP, la quale, in presenza del modifier /e nel primo parametro, esegue il codice PHP presente nel secondo argomento.
Di conseguenza inserendo nel nostro oggetto serializzato una stringa presente in fullpath all’interno di attacks, seguito da un /e e del codice PHP in replace, a patto che questo non fosse presente in badwords, questo codice veniva eseguito.

cookie phpinfo()

phpinfo()

Tuttavia per ottenere RCE sul server era necessario bypassare i controlli presenti nelle badwords, per farlo abbiamo utilizzato la funzione assert, la quale svolge la medesima azione di eval; al suo interno abbiamo inserito una str_replace, che sostituiva gli spazi all’interno della parola s y stem, infine all’interno della system abbiamo inserito $_GET['a'], ottenedo di fatto che la pagina eseguisse system($_GET['a']) e che il controllo delle badwords fosse bypassato.
Il payload finale pertanto è il seguente.

Unserialize to RCE

Dalla precedente scansione con dirsearch era stato possibile identificare la pagina http://ctf-hib.thesthack.com/invoker/JMXInvokerServlet/ con il seguente contenuto.

Double Rainbow

Abbiamo quindi provato ad effettuare una cat del file /var/www/CTF/invoker/JMXInvokerServlet/index.php e abbiamo trovato la flag al suo interno.

Double Rainbow Flag

 PCI Zone Flag

Arrivati a questo punto potevamo eseguire comandi arbitrari sulla macchina target, abbiamo quindi provveduto ad effettuare una reverse shell per semplificare l’interazione con il server e, ricordandoci la presenza di un riferimento all’IP 10.0.0.165 nel file settings.php proprio in merito ad una PCI Zone, abbiamo controllato quali interfacce di rete fossero presenti.

 

Ottimo! Ecco il nostro IP nella medesima /24 del server PCI, non avendo a disposizione nmap sul server target abbiamo provveduto a scriverne un mini sostituto in bash, sfruttando netcat per vedere le porte aperte del server PCI.

Avendo la porta 80 aperta abbiamo provato con curl a vedere se fosse presente un webserver e se fosse esposta qualche pagina.

Pivoting Web

Provando ad effettuare una curl su /server siamo entrati in possesso del binario esposto sulla porta 65099 del server 10.0.0.165.

Scaricato il binario in locale abbiamo provveduto ad analizzarlo.

server

Il file in questione era un eseguibile a 32-bin linkato dinamicamente e utilizzava libc. Analizzandone il comportamento con strace abbiamo identificato che all’avvio bindava la porta 65099 e forkava un processo, il quale rimaneva in ascolto di eventuali connessioni.

strace server

Aprendo il binario in gdb abbiamo provato ad inviare una stringa composta da 1000 A per vedere come si comportava.

server_gdb_normal_exit

Successivamente abbiamo provato con 2000 A, ottenendo una sovrascrittura di EIP e un crash del programma.

server_gdb_2000_segfault_exit

A questo punto era chiaro che fosse presente un buffer overflow che ci permetteva di aver controllo di EIP. Quindi con checksec abbiamo analizzato le restrizioni presenti per l’exploitation.

checksec

Come si può vedere NX risultava abilitato, di conseguenza non era possibile scrivere uno shellcode nello stack ed eseguirlo, proprio perché era NX (Not Executable), per l’exploitation era necessario quindi effettuare una ROP chain. Non essendo però presenti gadget utili nel binario stesso era necessario utilizzare una ret2libc e sfruttare le funzioni incluse in libc (es. system).
Per prima cosa è stato necessario trovare la corretta versione di libc. Questo era possibile attraverso la versione del kernel e del sistema operativo presenti nel changelog.txt, tuttavia anche con questi dati non era one-shot la scelta, quindi durante la CTF è stato fornito l’address della system come hint ( (gdb) p system $1 = {} 0xb7e643e0 <__libc_system>).

Avendo l’indirizzo della funzione system, sapendo che ASLR era disabilitato e avendo individuato il buffer overflow è stato possibile scrivere un exploit che facesse le seguenti cose:

  1. Scrivesse un comando sullo stack (bind shell con netcat)
  2. Riempisse lo stack fino a prima di EIP
  3. Sovrascrivesse EIP con l’indrizzo della system
  4. Scrivesse 8 byte di padding (indirizzo di ritorno dopo la system)
  5. Scrivesse l’indirizzo dello stack dove era pesente il nostro comando (argomento della system)

Il problema di questo exploit è che non potevamo sapere con certezza la posizione del comando nello stack dell’eseguibile sul server target, tuttavia un bruteforce era possibile in quanto l’indirizzo era compreso tra 0xbfffe000 e 0xbfffffff.
Di conseguenza l’exploit finale è il seguente.

Lanciandolo veniva eseguita una bind shell sul server 10.0.0.165 sulla porta 4647, alla quale era possibile collegarsi ed eseguire comandi arbitrari sul server target.

server 2 owned

Effettuando un cat del file flag.txt è stato possibile ottenere la flag.

ECB Padding Flag

Avendo ottenuto RCE sul server della PCI è stato possibile recuperare la flag di questa challenge.

ecb padding

Il file php completo è il seguente.

Per una descrizione completa di questa challenge ecco 2 writeup molto ben fatti:

  1. http://codezen.fr/2013/08/05/ebctf-2013-web400-cryptoaescbchmac-write-up/
  2. http://resources.infosecinstitute.com/cbc-byte-flipping-attack-101-approach/

Credit Card n° 6666 Flag

Avendo compromesso il primo server è stato possibile dumpare il database e ottenere i dati della carta 6666 ('6666','7cLGMYqWY2bGgYPIDlE+CODHAwwLJiAMIUSghfke+QgCMNrEQyj7TlnqU4nNuZFTLsVvVWQ15jH3JYsgvwq6/CcaQczRD/0csxB7rqiR3DQ='), tuttavia era presente un campo token con una stringa cifrata, sapendo però che sul secondo server era presente il decrypter in php è stato sufficiente settare un cookie pci_crypt contente il token, per ottenere in risposta la versione decifrata.

decrypt_token

Effettuando un md5 della stringa decifrata si otteneva la flag.

C Source Flag

Questa flag purtroppo non era accessibile in quanto era stata impostata in una costante del codice C del server, ma non era utilizzata nello stesso, di conseguenza al momento della compilazione è stata rimossa dai processi di ottimizzazione di gcc.

Conclusione

Speriamo che il nostro writeup sia di aiuto per chi si fosse bloccato durante la CTF e speriamo di vedervi tutti ad HackInBo il 6 Maggio.

Per chi volesse leggere un altro writeup il team di JBZ, di faccio orgogliosamente parte (smaury) e i cui membri sono stati gli unici a completare tutta la CTF, ne ha pubblicato uno: https://jbzteam.github.io/web/crypto/reversing/HackInBo17-SpringEdition

Su richiesta degli organizzatori sono stati rimossi i sorgenti della CTF. Nel caso non siate riusciti a partecipare e/o vogliate provare con mano ad exploitare le varie vulnerabilità contattate direttamente Hacktive Security.

Abdel Adim Oisfi

Sono Abdel Adim Oisfi, conosciuto nella rete come "smaury". Lavoro: Co-CEO, Security Researcher, Web Developer, Penetration Tester presso Shielder Srl. Passioni: Hacking, Autostop, Tuffi e Ginocchia Sbucciate.