venerdì 25 novembre 2016

Come violare 18app per avere il Bonus Cultura infinito (responsible disclosure)

Essendo nato anch'io nel '98 come molti altri adolescenti, ho potuto avere accesso al tanto aspettato "Bonus Cultura" promesso dal governo Renzi nell'ultima legge di Stabilità per il quale sono stati stanziati 290 milioni di euro complessivi e prevede per i neo-maggiorenni l'accesso a 500 euro da investire in biglietti, libri e molto altro. 


La modalità di erogazione del bonus avviene tramite l'accesso ad un sito web creato ad hoc in seguito all'autenticazione della propria identità digitale (SPID) per la conferma dell'idoneità. Infatti, al contrario delle aspettative, non si tratta effettivamente di un' "app" come appunto potrebbe suggerire anche il nome del programma, ma, come già detto, di un sito web perfettamente accessibile anche dai dispositivi mobili.

Tralasciando tutte le critiche mosse contro questa iniziativa, derivate fondamentalmente dai ritardi nell'attivazione del portale e dalla complessità della richiesta dello SPID, finalmente sono riuscito anch'io ad effettuare il primo accesso al sito. La grafica appare subito intuitiva e veramente user-friendly, infatti la navigazione all'interno del portale avviene senza alcuna minima difficoltà.

Il mio interesse si è spostato subito sulle parti "cruciali" dell'applicazione, in particolare il modulo di creazione dei "bonus", che consente di "partizionare" i 500 euro per spenderli nei vari servizi previsti.

Ho provato a creare un buono dal valore di 50 euro così da poter intercettare la richiesta:

Com’è possibile osservare, i parametri della richiesta, codificati in JSON, sono i seguenti:
  • idBeneficiario: l’ID del “mio” account;
  • annoRif: l’anno in cui è stata spedita la richiesta (il Bonus Cultura è spendibile fino al 2018);
  • idAmbito: la categoria del servizio (cinema, concerti, libri ecc…);
  • idBene: la sotto-categoria del servizio (nel caso dei libri: audiolibro, ebook o cartaceo);
  • importoRichiesto: l’importo da assegnare al buono;
La risposta del server, in figura opportunamente censurata per motivi di privacy, contiene alcuni dati sull’esito della richiesta (data, eventuale errore…), sul buono generato (numero, codice qr ecc…) e i dati personali del beneficiario, tra cui il codice fiscale, gli indirizzi di nascita e di residenza, email, numero di cellulare e molto altre informazioni private.

La prima vulnerabilità risiede nel parametro idBeneficiario, infatti tale valore è modificabile e viene accettato senza alcun tipo di controllo della sessione. In altre parole, è possibile creare buoni utilizzando un account altrui. In più, facendo ciò, nella risposta non troveremo più i nostri dati personali, ma quelli dell’account utilizzato, creando cosí un enorme problema di sicurezza e della privacy dell’utente.

Un’altra vulnerabilità del tipo “Broken Access Control” la troviamo invece nella richiesta relativa all’annullamento dei buoni creati:

La richiesta GET in questione si trova nel seguente formato:
https://www.18app.italia.it/BONUSWS/rest/secured/gestioneVoucher/annullaVoucherOnline/ID
L’ID del buono, evidenziato sopra, tranquillamente ottenibile leggendo la risposta della generazione del voucher. La falla risiede nella possibilità di modificare tale parametro, che potrebbe portare a risultati disastrosi per il portale, quale appunto la cancellazione di tutti i buoni di tutti gli utenti.

Infine ho trovato ben altre tre richieste che permettono di trovare informazioni sensibili (anagrafica, disponibilità del bonus ecc..) di altri utenti registrati, semplicemente avendo il loro codice fiscale (CF):
  • https://www.18app.italia.it/BONUSWS/rest/secured/18enne/beneficiario/CF
  • https://www.18app.italia.it/BONUSWS/rest/secured/18enne/listaVoucherDaSpendere/CF
  • https://www.18app.italia.it/BONUSWS/rest/secured/18enne/borsellino/CF
Le vulnerabilità appena documentate pongono la piattaforma ad un livello di rischio relativamente alto dato che un malintenzionato potrebbe impossessarsi dell'intero bugdet assegnato al Bonus Cultura (ovviamente quello non ancora usufruito) semplicemente combinando le richieste appena trattate.

Questa attività di ricerca risale al 14 Novembre 2016 a cui è seguita subito una collaborazione con il CERT Nazionale e SOGEI, la società che gestisce il sistema informativo del MEF e che ha curato la pubblicazione del sito 18app.italia.it, per permettere la risoluzione delle problematiche segnalate. Ringrazio Paolo Stagno, fondatore del progetto italiano VoidSec per avermi messo in contatto con questi due enti che mi hanno autorizzato la pubblicazione del Responsible Disclosure.

giovedì 10 marzo 2016

Un primo approccio al watermark: gli EPUB di Macrolibrarsi

La continua ricerca di nuove frontiere che consentano alle case editrici di tutelare i propri interessi sta portando alla scoperta di nuovi meccanismi di protezione più o meno sofisticati quali il DRM e il watermarking. Quest’ultimo, la cui prima implimentazione è più recente, consiste nell’applicare un “sigillo” alla copia digitale di un libro, contenente tutte le informazioni identificative del “proprietario”.
Dal punto di vista della sicurezza, esistono tre tipi di watermark: fragile, semifragile e robusto.
In questo articolo analizzeremo un watermark molto fragile, cercando di rendere evidente la quantità di informazioni che potrebbe contenere un prodotto digitale.
Ho dunque acquistato regolarmente un ebook (in formato .epub) sul sito di Macrolibrarsi, dopo ovviamente aver verificato che contenga una protezione watermark:


…e ho subito ricevuto il link di download via e-mail:


L’ho quindi scaricato e ho subito proceduto con l’estrazione dei file presenti all’interno del file .epub utilizzando il noto software “unzip”…


…ottenendo così due cartelle: META-INF e OEBPS. Nella prima troviamo un singolo file “container.xml” che non contiene informazioni particolarmente interessanti; i contenuti dell’ebook, quali immagini e testi, li troviamo invece nella seconda cartella:


Il file “_license0.xhml” è il primo che ho scelto di analizzare ed effettivamente contiene la nostra prima traccia di watermark:


Passando in rassegna gli altri file, si può dedurre che TUTTI i file .html contengono queste informazioni pericolose, quindi il nome dell’acquirente, l’indirizzo e-mail, la data di acquisto e il numero dell’ordine.


Ma il watermark non si trova necessariamente sotto forma di “testo”, infatti nella cartella “img” troviamo l’immagine “_img_license0.png”, la quale, una volta aperta, si presenta in questo modo:


Per essere sicuri che nessun altro file sia stato “marchiato” con altre tecniche, un mio amico, che ha contribuito a questa “ricerca” e che ringrazio moltissimo, mi ha fatto notare che da una semplice analisi della data di modifica dei file è possibile determinare quali file sono stati modificati il giorno dell’acquisto (ovvero il 9 marzo 2016) e da ciò si può dedurre nell’aggiunta arbitraria di informazioni identificative. Con un semplice comando si conferma la nostra ipotesi:


Infatti, come abbiamo potuto verificare, gli unici file a cui è stato aggiunto il watermark, sono il file _license0.xhtml, tutti gli .html e l’immagine _img_license0.png. È opportuno quindi, per ulteriore sicurezza, durante la rimozione del watermarking, modificare la data di modifica, specialmente nel caso in cui viene effettuata questa operazione nello stesso giorno dell’acquisto dell’ebook.
Ho provveduto a raccogliere tutte le informazioni riguardo la posizione del watermaking negli ebook EPUB di Macrolibrarsi, riuscendo così a creare un semplice (e buggato) script che effettua per noi questa procedura di rimozione.

venerdì 19 febbraio 2016

Estrarre i PDF da MEbook (attraverso iflipit)

A differenza degli altri lettori web di documenti digitali che ho avuto modo di testare, MEBook presenta un DRM un po’ più sofisticato, introducendo una semplice cifratura “a sostituzione”.
Ecco come appare l’interfaccia dell’applicazione:


Ho subito proceduto con l’analisi del traffico, arrivando ben presto ad intercettare una richiesta particolarmente interessante. L’ho subito “riprodotta” utilizzando il plugin Live HTTP Headers, ottenendo questo strano risultato:





A colpo d’occhio è possibile stabilire con una certa sicurezza che si tratta del contenuto di un’immagine, passato come secondo argomento alla funzione viewer.imgl. Purtroppo, già dall’header si può notare che alcuni byte risultano manomessi, come, per fare un esempio, quel segmento “JBIF” dovrebbe essere “JFIF”.

Così prima di poter procedere con un minimo di reverse engineering ho dovuto cercare il sorgente della funzione, che non tardò ad arrivare, parzialmente offuscato:


Tralasciando le parti che non ci interessano, partendo dalla funzione _imgl, il contenuto dell’immagine “criptata” viene passato alla funzione d_i che, servendosi della funzione d_s, esegue delle semplici operazioni di sostituzione di caratteri nell’header dell’immagine e infine, tornando alla funzione principale, il risultato viene convertito in base64 e copiato nel parametro “src” di un tag <img> che ne consentirà la visualizzazione. Ho provveduto subito a sistemare e tradurre il codice in Python, così da poterlo utilizzare successivamente per scaricare e decriptare automaticamente le pagine e unirle in un unico file PDF. Questo è il risultato:
def decrypt(data,page):
    data=data.replace('viewer._imgl('+str(page)+',"','')
    data=data.replace('");\nviewer._imgl('+str(page)+');','')
    data=data.decode('string_escape')
    m="fb69218f41737d7da84b1e39a949dbc2"
    arr=list(data)
    for j in range(3):
        for i in range(95,-1,-1):
            newpos=ord(m[i % 32]) % 96
            f=arr[i]
            s=arr[newpos]
            arr[i]=s
            arr[newpos] = f
    data=''.join(arr)
    return data
In conclusione, ho inserito la funzione in uno script che rende più semplice l’estrazione dei vostri libri acquistati su MondadoriEducation; lo potete trovare qui, insieme ad un video dimostrativo che illustra brevemente il procedimento:

mercoledì 3 febbraio 2016

Estrarre i PDF da Scuolabook (attraverso la webapp)

Qualche settimana fa ho avuto la necessità di scaricare un ebook regolarmente acquistato su Scuolabook per poterlo consultare in assenza di connettività. Se con l’applicazione Desktop il login avesse funzionato, probabilmente avrei potuto eseguire il download del mio libro (ovviamente protetto dal DRM di Scuolabook e quindi consultabile soltanto con il suo software) direttamente dal programma e la cosa sarebbe finita qui. Purtroppo dopo diversi tentativi che la password mi veniva segnalata come errata, ho deciso di provare ad analizzare l’applicazione web.
Collegandosi al sito dell’applicazione, effettuata la procedura di login, ci si trova davanti alla propria libreria. Da qui è sufficiente cliccare sul libro interessato e l’interfaccia caricherà l’immagine della copertina consentendoci, attraverso le frecce direzionali di sfogliare (abbastanza) comodamente il libro.
Il mio fantastico libro di greco.
Purtroppo, a causa della sua natura, non è possibile consultare la webapp senza connessione Internet, e questo crea non pochi problemi. Ho così deciso di provare a superare l’implimentazione DRM dell’applicazione (successivamente rivelatosi praticamente inesistente).
Ciò che mi interessava particolarmente è il meccanismo che ci stava dietro al caricamento delle pagine.
Già da subito infatti ho notato delle richieste interessanti, derivate dal click su una delle due freccette:


La richiesta in questione è:
 https://webapp.scuolabook.it/books/4353/pages?pages[]=6
Provando a ri-produrre la richiesta ho ottenuto una pagina JSON contenente il link dell’immagine della pagina numero 6. Soddisfatto del risultato, ho voluto effettuare alcuni test che mi avrebbero successivamente consentito di facilitare il lavoro dello scaricamento del libro completo.
Innanzitutto ho fin da subito intuito che il numero “4353” presente nella richiesta sopracitata corrisponde all’identificativo del libro (purtroppo modificando questo parametro non è possibile scaricare un’altro libro di cui non si è in possesso) . Ma ben più importante è il fatto che posso “concatenare” più parametri “pages” al fine di ottenere in un’unica pagina più immagini. Ecco come si presenta la nuova richiesta GET:
 https://webapp.scuolabook.it/books/4353/pages?pages[]=6&pages[]=7&pages[]=8
Qui il risultato:


E per concludere, ho provato ad aprire un link (sostituendo opportunamente i caratteri encodati in HTML come ad esempio &amp;):


Et voilà, questo è l’indice del mio libro di Storia :P
Dopo aver raccolto tutte le informazioni possibili, ho provveduto a scrivere uno script che semplificasse il lavoro di download dell’ebook. Lo potete trovare nella repo di GitHub. Ho infine pubblicato al pubblico dominio nel forum della comunità di TNTVillage un semplice tutorial che spiega esaustivamente come far funzionare lo script.


mercoledì 30 dicembre 2015

“IP disclosure” di un’applicazione MyBB sotto cloudflare/tor/proxy

Questa procedura sfrutta un evento non previsto, in particolare una richiesta HTTP viene effettuata dall’applicazione verso un server remoto, causando il “disclosure” (o “leak“) dell’indirizzo IP. La gravità di questa vulnerabilità dipende dal contesto in cui si trova l’applicazione web: per ovvi motivi aumenterà nei casi in cui MyBB fosse installato in un hidden-service tor, rendendo di fatto possibile determinare la corrispodenza dell’.onion con il rispettivo IP, violandone l’anonimità. Nei casi più estremi è possibile aggirare Clouflare, il server proxy, il firewall e altri.

Passando all’analisi concreta della vulnerabilità, la richiesta HTTP avviene nel momento in cui un utente registrato desidera impostare come avatar un’immagine remota attraverso il proprio pannello di controllo.

Vediamo prima cosa succede nel dettaglio: andiamo a vedere il codice sorgente di MyBB, presente nella rispettiva repository su GitHub. In particolare, ci interessa la pagina del pannello utente “usercp.php”:


Sostanzialmente, come è possibile notare, quando si inserisce un link all’immagine (remota) dell’avatar, il server effettua tre passaggi:
  1. verifica l’estensione del file tramite un’analisi regex del link; 
  2. scarica l’immagine attraverso la funzione fetch_remote_file;
  3. salva l’immagine su un file in locale e verifica che le dimensioni dell’immagine siano inferiori alla soglia stabilita nel file di configurazione;
La funzione fetch_remote_file, definita nel file functions.php, consiste in una richiesta HTTP attraverso cURL o, se non fosse installato, attraverso fsockopen. Da qui, come già detto, deduciamo la nostra vulnerabilità.

L’attacco pertanto può essere organizzato in questo modo:
  1. Creiamo uno script in PHP, rinominato in formato .PNG, che salvi l’indirizzo IP del visitatore su un file locale;
  2. Aggiungiamo una direttiva nel file .htaccess che permetta al server l’interpretazione dei file .PNG come PHP. Ad esempio "AddType application/x-httpd-php .png";
  3. Cambiamo l’immagine dell’avatar e controlliamo il file di log.
Per fixare la problematica consiglierei di modificare opportunamente il codice riguardante la funzione fetch_remote_file facendo passare le richieste sotto un proxy o, se proprio necessario, disabilitare la funzionalità.

Edit: dopo un esame della funzione get_extension, sono giunto alla conclusione che l’analisi del link per stabilire l’estensione è alquanto “buggata”: infatti è possibile aggirare l’eventuale blocco aggiungendo come prefisso “?.png”, “?.jpg” ecc…

Ho realizzato inoltre un video che illustra velocemente il Proof of Concept, utilizzando come obiettivo un hidden service: