CSCBE21: Vault (reversing)
Introduction
This reversing challenge was part of the qualifiers for CSCBE21. In this writeup I will explain in a beginner friendly way how we managed to reverse a statically linked Golang binary in order to discover an encrypted flag.
Initial analysis
Running file vault
gives us the following output:
1
vault: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header
We are dealing with a 64 bit executable which is statically linked. It’s interesting that there is no section header available, which is rather unusual.
We can run strings
on the executable to obtain more info possibly:
1
2
3
4
5
6
7
8
9
10
11
└──╼ $strings vault | head -n 10
UPX!<
N;(x
hxr
BNmN
TCC5IlGEw1l2JBlS6xEX/
pkFD7O2sKWI1dP0cQOYu/k8M2hCnLPjC
6LwOAlngV/IYBCrHtezHI7AaDq9FEC
@D$ &
,%T/
fZ.L
(For those that are familiar with this, UPX
is a packer which compresses our binary. This is an indicator that you need to unpack this first using upx -d vault
.)
strings
contains alot of junk, with nearly no useful data. However, running the following command shows us yet again UPX!
:
1
2
3
4
5
6
7
8
9
10
11
└──╼ $strings vault | tail -n 10
RptS
-Zsum#B
Base
~fix1Int#
pXYZbZ,
F##H
sgU%
Use4
UPX!
UPX!
Here we can see UPX!
yet again. To see which other lines contain UPX
, we run the following command:
1
2
3
4
5
6
7
└──╼ $strings vault | grep UPX
UPX!<
$Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 3.95 Copyright (C) 1996-2018 the UPX Team. All Rights Reserved. $
UPX!u
UPX!
UPX!
This is a clear indicator that we need to decompress the binary first (which can be done using upx -d
). It also makes sense now that our section header was ‘missing’.
Running the executable results in the following output:
1
2
3
4
└──╼ $./vault
Enter the master password to access the vault:
hello
Invalid password!
We are asked to input our password, and if we supply a bad password it will exit the process.
Disassembly
Opening up the binary in IDA, we notice alot of libraries and other junk. This is due to the statical link, which compiles all your libraries into your binary. With some quick googling, we can identify that this binary is made using Golang.
Navigating to main_main
(our main function for our binary), we can start analysing the binary
First we see “Enter the password…” string appearing like we saw before. It’s being moved onto the stack, so that it can be called by println
.
Afterwards, we notice scanln
, which reads our input.
Next, we notice our input is being compared to the following "2lOwaJDmIVBwPBZFPORYss8TW4m6s".
As expected, this is the master password.
1
2
3
4
5
6
7
8
9
10
└──╼ $./vault
Enter the master password to access the vault:
2lOwaJDmIVBwPBZFPORYss8TW4m6s
Correct password!
Which password would you like to retrieve?
1) Flag
2) GitHub
3) Discord
1
//to do: retrieve flag from vault
Selecting 1)
, the flag, results in output mentioning “to do: retrieve flag from vault”. Lets dive deeper onto what’s happening there.
Moving onto the next interesting step in our program, is selecting which password we want (I skipped the code inbetween in this writeup, it’s not really relevant. Do however take a look at it to get a full understanding if needed).
In this block, we are prompted for the password we want to retrieve. When selecting ‘1’, we get redirected to the following block:
We instantly notice a couple of weird looking strings including this one:
This looks like a base64 encoded string, so let’s try to decode it.
1
2
──╼ $echo 'Ly90byBkbzogaW1wbGVtZW50IGEgc3Ryb25nZXIga2V5OiAweEM=' | base64 -d
//to do: implement a stronger key: 0xC
Seems like we got a key! This looks like a typical key we can use to XOR a string. Spoiler alert: it won’t work right away.
In the beginning of the block, we notice an append
function is being called. Right before this call, it seems these 2 strings are being pushed onto the stack which will serve as arguments.
Now you could look at the append
function, to verify whether or not its actually appending. To make the writeup a little bit shorter, we assume it does.
Flag
Let’s try to append these strings together, and XOR it with the key, and voila!
FLAG: CSCBE{W41t_tH15_15_N0t_Th3_PP455w0rd?!}