TISC20
Stage 1
We're given an encrypted zip file and told that the password is a hex string. Generating a wordlist and feeding it to fcrackzip
solves this.
import itertools
with open("hex_wordlist.txt", "w") as f:
for c in itertools.product("0123456789abcdef", repeat=6):
pw = "".join(c)
f.write(pw + "\n")
$ fcrackzip -D -p hex_wordlist.txt stage1.zip -u -v
found file 'temp.mess', (size cp/uc 39970/ 39943, flags 3, chk 37bc)
checking pw 98967f
PASSWORD FOUND!!!!: pw == 9ea08c
Unzipping the file reveals...more archives. We're given temp.mess
- manually unzipping and decoding the file got too tedious. Another script solves this quickly:
import magic
import zlib
import base64
import binascii
import lzma
import bz2
with open("temp.mess", "rb") as f:
data = f.read()
try:
while True:
typ = magic.from_buffer(data)
if "gzip" in typ or "zlib" in typ:
# https://stackoverflow.com/a/6124315
data = zlib.decompress(data, 15 + 32)
elif "XZ" in typ:
data = lzma.decompress(data)
elif "bzip2" in typ:
data = bz2.decompress(data)
elif "ASCII text" in typ:
unique_chars = set(data.decode("utf8"))
if len(unique_chars) > 16:
# base64
data = base64.b64decode(data)
else:
data = binascii.unhexlify(data)
elif "JSON" in typ:
print(data.decode("utf8"))
break
else:
print(f"unable to handle {typ}")
print(data[0:10])
break
except:
print("error!")
with open("stop", "wb") as f:
f.write(data)
This gets us the flag for stage 1: {"anoroc": "v1.320", "secret": "TISC20{q1_946324372636474e071b767f4a567bb2}", "desc": "Submit this.secret to the TISC grader to complete challenge", "constants": [1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221], "sign": "KQ4QYnHLM_4"}
Stage 2
We're asked to extract a public key from a Golang binary. Opening it in Ghidra, we find something interesting in main.main
:
We see two large chunks of data get passed to main.EncryptDecrypt
- I wonder what's inside? Carving out the data and reimplementing the decryption algorithm in Python gets us our key:
coronaware = open("anorocware", "rb").read()
i = coronaware.find(b"\x4e\x5b\x37\x76")
data = coronaware[i:i+0x7c4]
i = coronaware.find(b"\x02\x08\x04\x03")
key = coronaware[i:i+0x64]
out = ""
for i, c in enumerate(data):
out += chr(c ^ key[(i * i) % 0x64])
print(out, end="")
$ python3 decrypt_full.py | base64 -d
-----BEGIN PUBLIC KEY-----
MIIEIDANBgkqhkiG9w0BAQEFAAOCBA0AMIIECAKCBAEAm99b2pvtrViW+jN/3NFf
w8g36dQR6iJr+cyRe+k8XFzuHUO4LN3tk76tFS8DbaCcYFiuf8GsugcRmQDErPZf
qgkvXZpufffTfjTB+je/Wi43bwLqtw0W4cXoPW33uGVaWZX0oLzKC/Axg7kwItmG
xnn321TAjEZgTbL+OaNkcHzfQ7UzwaEp9UPtT8pGYoNJHlX3fkFq2iVy77uI4gRK
Mf8ujTfkIHHjQ7BEzgEgk8kqxGaSPlINQs65P4tvOpihqpwUVpAjPLNBTt9Hz1F/
fR+aDsJQRKZNMrWRLuMYiO2Mx9cZBnwzL9KuFRvHelO7BWayU9f0XOpg/zybEQOL
ux+jmsUsTsQbjK9cB67Ma21D+XJHyKgKuP9u14mVCZgCBk9lybS1bxdvFDQPgkyc
M3z9vuucCU1Eu2D0lhFmJ3FQfZkAY++XHUpiwui9NO3A9UG7amyXbOSclF2X9kRq
0CwmqOtBRBEWISe5rdzc/ATOP3PqDjGwySXxWZDCH8rrgnzWpv2LriYQTnf2cE0G
/iI8RwjYoGLWzeLVRr1hhZ8Y5s4R/sR497WenkRcpOLOkDVge7MusTOWh4eNi4go
PldsiYTqTndA1wV67r09ujpp8VvpdLuo+4h+7p/pfpXMsx8dALom4sfkYcJHhObk
xt5CpNCkVXh5tsGheFb7v85GiNFy17zualMda32BinPeEbFrqKwD2Z4R5QgQuB8u
IwjqSTgNo9Uvvch6lWCbj9e+80ugV4o7jHCd/56FkuvhCqiINdZDUU4ZB37hdelf
eE9NbxDjKG8V7aCdwqJJDYGiz/3jmuCfB/k5FkoHSANgbLE0A5Smk3T8tuv8Sz+f
v4rrPxmpn8X2Sm1Foz+U0BWzP+VLmpLnnyXkrOHyn8lJFbn/U5NWGRLn+ev2CSkw
AI/TfHALqTvjqlGQxTTaY7Znkn5i+D1LztK8cpSZXdDVoRh+/vMIEiNuk8++/s6a
HNd7wuFkY/Z8jjJ1jH/csF37mGYAUxp32nRk5wRp/c6eWZPM+zGibfEnmFW5yUEU
YbX4hzzGr5Q6f/sysuzhaylWi3XCvIrH6LBjFNu3UJ0VIzcJN0kxaABaXY8JUDYX
tXULipvUOqkttOqJSxOXWg72SWKLKv/QvfDRVXedUk066k7RL1okpbMnwYlfYg7J
mpZZR2CNNwbMkQm2TmrA/MZudvqtsX9PpkgJI+ZWjUwVtGRUTdDMxZWx4H3neJiy
8m8udk42RN0j3n0wVXsWt6Qmy7bQsHYXIHUgkBXYzdy/u+NodKAjhdVpiJbzIncz
SdolXiniKwNULW8VjjS9KTSRwidqeOkkpNeIqiRnWT3TTMAMzb5j0jEGF7L3DOMP
6QIBAw==
-----END PUBLIC KEY-----
Reflections
This is where I stopped due to time constraints (and the lack of patience to RE the Golang binary). It turns out that I placed 11th - perhaps I should have stuck around for longer...
Other Far More Detailed Writeups:
- Calvin (First place) - https://blog.idiot.sg/2020-09-18/tisc-ctf-2020/
- Jeremy (Third place) - https://nandynarwhals.org/tisc-2020-writeups/
- Eugene (Sixth place) - https://spaceraccoon.dev/beat-the-clock-the-csit-infosecurity-challenge