TISC 2020

STAGE 1

In stage 1, nc fqybysahpvift1nqtwywevlr7n50zdzp.ctf.sg 31081 was given for the player to access. Once accessed a link to the zip file was given.

http://fqybysahpvift1nqtwywevlr7n50zdzp.ctf.sg:31080/063f703813b566487d0165f89420f535.zip

Other hints were given such as the transactional diagram, an screenshot of the superuser post and the script used to trick the victim into download the malware.

Diagram

Script

Stackoverflow post

From the diagram and problem description given, it is hinted that the malware is zipped and has several layers of encoding and compression used and a password is used to encrypt the zip file. From the script several compression libraries can be seen being used such as lzma, gzip and bzip2 . The password is hinted to be only 6 characters and made up of hexadecimal characters. This means the characters used are only either lower or uppercase alphabets and digits.

This means that a simple bruteforce tool to find the password is sufficient. The fcrackzip tool was used to bruteforce the password.

fcrackzip -b -v -l 6 -u -c a1 063f703813b566487d0165f89420f535.zip

The password is de6744.

After unzipping, another compressed file was retrieved where gunzip was used. The second layer was hexadecimal encoded and so on…

After manually going through a few layers it was discovered through that further compression and encoding methods was used such as base64 and zlib. From that point a script was written to detect the first few bytes of the byte array to determine which compression library was being used. If none were being used, it could only be encoded in hexadecimal or base64.

Solution

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
import lzma, gzip, bz2, base64, binascii, zlib

f = open('temp.mess', 'rb')
d = f.read()
round = 0

while(True):
round += 1
print("round {0}".format(round))
print("==================================")
print(d)
print("==================================")
if (d[0:3] == b'\x1f\x8b\x08'):
print("check gzip")
d = gzip.decompress(d)
continue
elif (d[0:3] == b'BZh'):
print("check bzip2")
d = bz2.decompress(d)
continue
elif (d[0:6] == b'\xfd7zXZ\x00'):
print("check lzma")
d = lzma.decompress(d)
continue
elif (d[0:2] == b'x\x9c'):
print("check zlib")
d = zlib.decompress(d)
continue
else:
print("check hexadecimal")
try:
d = binascii.unhexlify(d)
except binascii.Error as err:
print(err)
print("check base64")
d = base64.b64decode(d)

After running the script, this string containing the flag was produced.

{"anoroc": "v1.320", "secret": "TISC20{flag}", "desc": "Submit this.secret to the TISC grader to complete challenge", "constants": [1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221], "sign": "cRDUg3miqsZ0LjHcnIV5f-KQ"}

STAGE 2

In stage 2, a zipped file with the malware and a dockerbuild file was presented along with contents that were encrypted by the malware. The first step is to build the docker and install the necessary tools for analysis such as binutils, gdb and peda etc. After setting up, the malware can be analysed.

At first glance, the anorocware binary is an ELF 64-bit executable. However, upon further inspection it can be seen that the binary is packed using UPX therefore the binary needs to be unpacked before anymore analysis.

1
2
3
4
5
6
7
8
9
10
11
$ file anorocware
anorocware: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
$ strings anorocware | grep UPX
8UPX!
$Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 3.96 Copyright (C) 1996-2020 the UPX Team. All Rights Reserved. $
UPX!u
UPXq
UPX!
UPX!
$ upx -d anorocware -o anorocware-u

The next step is to use a debugger or decompiler to further analyse the binary and its inner workings. Binary Ninja was used for analysis. In the challenge description, the public key is stated to be encoded using base64 hence it gives a hint as to where to hunt for the embedded string in the binary. The binary would have to use a function to decode the string before being able to use the public key. The call to decode the string can be seen in address 0x662175.

Using gdb, it is possible to set a breakpoint anywhere near or after the call to decode the string is made, the encoded key would be stored in one of the registers or can be found in the stack. The address 0xc00058f000 can be seen to contain a partial string that looks like a part of an encoded string and in the registers the public key can been seen clearly.

After locating the address where the encoded key is stored, the encoded key can be copied and hashed with sha256 to get the flag.

CLOCKOUT

At this point, I ran out of time to complete the other challenges. I wasted quite alot of time trying to manually unzip the files at the first stage when I should have started with a script earlier. Silly me!