TG:HACK 2019 Forensics Write-Up
On this blog post, I will write about our answers to the Forensics challenges at TG:HACK 2019 where we luckily placed 25th out of more than 700 participating teams and scored our first Forensics first blood for this year!
Now let’s go over our solutions for the challenges!
Intended to be a warm-up challenge, this is the easiest question for this batch.
Downloading the file and running the
file command against it will give you this result:
Let’s mount it using the following command (issue
sudo as you see fit):
mount -o ro store.bin /mnt/<mount_point>
Mounting the file will give us this folder:
And going into the folder will give us this png file with the flag:
Let’s download the
.pcap file and inspect it via Wireshark:
Outright, we can see that most of the packets in this capture is comprised of DNS traffic. We can validate it via the Protocol Hierarchy statistics:
If we look closely, we can see that DNS requests and responses with suspiciously long subdomains were recorded in the packet capture:
An example of the said suspicious request/response:
This is suspicious because behaviors such as these (suspiciously long/non-human readable subdomains) are often considered as indicators of DNS exfiltration activities. For this challenge, we’ll only focus our efforts to the DNS requests since the DNS entries are doubled due to the request and response pairs.
To display all the DNS requests, we can use the display filter:
dns && dns.flags.response == 0
“Well, we can export all these packet data to .csv using Wireshark!”
But that can be too tedious, right? So for this challenge, I decided to use Wireshark’s underrated brother:
To extract all the subdomains, I used the following command:
tshark -Y "dns && dns.flags.response == 0" -T fields -e "dns.qry.name" -r superb-owlput.pcap | cut -d '.' -f1
What this does is that it gets all the DNS queries and only outputs the
cut was used to only get the subdomains. Listed below are the first 10 subdomains:
Now, due to experience, I easily identified this hex blob to be a JPEG file due to the signature
ff d8 ff e0
We can get the jpg file using this one-liner:
tshark -Y "dns && dns.flags.response == 0" -T fields -e "dns.qry.name" -r superb-owlput.pcap | cut -d '.' -f1 | tr -d '\n' | xxd -r -p > owl.jpg
And we’ll get this file as the result:
Yes, it looks broken but a quick
exiftool will show us this:
Decoding the base64 string value on the
Artist description will give us the flag.
We got the first blood for this challenge! I‘d like to give credit to my teammate oR10n for helping me reverse the binary to get the flag.
His in-depth malware reversing write-up for this binary can be found here:
This challenge was pretty much our comfort zone since we do DFIR for our day jobs haha! I’ll give a quick run-down of our analysis process below:
A quick inspection of the packet capture will show us this:
These are pretty much normal traffic until we come across packet 141:
As we can see on the packet capture, SSL is enabled but we can clearly see the executable (due to the
PE signature) on the stream:
Let’s follow this TCP stream and extract the binary within:
Save data as
Raw to properly extract it, and it will leave us with the binary
However, if you open up the binary in a hex editor, we can see that there is an embedded base64 string within:
Decoding the said base64 string will give us another binary — (I decided to name it)
A quick inspection of the binary will reveal a string that we want:
UPX! This binary is UPX encoded so let’s decode it using UPX! It should be that easy, right?
Wrong. Well, not exactly. You see, malware authors modify the section headers so they can deter novice analysts. UPX expects headers named
UPX1 and so on, so modifying the headers — in this binary’s case:
LOL1 — can easily fool UPX to raise an error.
Modifying the said headers:
Will now allow us to unpack the binary:
The main function can be found on address
We can see that the function
0x40101 was called twice, each succeeding variable assignments for
ecx. On usual cases, this often indicates a decryption routine.
Without a debugger readily available, I opted to run a behavioral analysis on the binary using a sandbox:
Hmm, the binary sends a GET request to google.com using the User Agent
secretstringkey. Perhaps the encrypted string was
google.com? I stopped speculating, gathered my findings and asked help from oR10n so we can analyze the binary. Again, the in-depth analysis of this binary can be found on this link:
To summarize our findings, we can use the decryption function at
0x401010 to decode other strings in the binary. Namely,
/get_flag. Sending a GET request to
notc2.tghack.no/get_flag using the User Agent
secretstringkey will give us the following string as the result:
Getting the flag was made trivial by using XOR Brute Force:
Disclaimer: We only solved this problem after the CTF itself. This is the only problem that we didn’t solve, but we learned so much from still trying to solve this stego problem!
Downloading the image will give us this:
A 20MB file for a
.png file? That’s weird.
zsteg -a will give us this:
There’s a base64 string on the following line:
b1,rgb,lsb,xy,prime .. text: "297980:SnVzdCBsZWFybmVkIGFib3V0IHRoaXMgbmV3IHRlcm0gY2FsbGVkIHN0ZXJlb2xpdGhvZ3JhcGh5Li4gUHJldHR5IGNvb2wgY29uY2VwdCF0EQAAAACAPzIxjaTKyVMl5Xu6J74fq0L6fhrBJnG5J3qwqkLVIhnBYFG+J74fq0K2wyPBAAAAAIA/MjGNpMrJUyUMQMEn2JiqQjVCLMGpzrEnTmKpQvYoCsFDbMEnTmKpQjTpL8EAAAAAg"
Decoding the base64 string will give us this:
Just learned about this new term called stereolithography.. Pretty cool concept!<some gibberish here>
Which includes some gibberish at the end because the string was truncated. We can extract it using the following command:
zsteg -E b1,rgb,lsb,xy,prime office.png > extracted
Looking at the extracted data on a text editor will give us this:
Yep, a huge blob of base64 strings. Going further down, we will encounter an
= character, which is often used as padding in base64.
I copied all the characters before the
= sign (including
=) and decoded the file.
Based on the clue we got earlier (stereolithography), a quick Google search will point us to .STL files. They are file formats that contain 3d imagery. I decided to save the decoded base64 file into an .stl file and used an online service: https://3dviewer.net/ for this challenge.
Opening the file using the said service will give us the flag: (I cannot, for the life of me, rotate this so I just typed it out hahaha)
All in all, I was very impressed with the whole CTF. I heard TG:HACK, specifically The Gathering, is a huge thing in Norway every year. I also hope that my team and I can go there to experience it someday and participate on the on-site challenges. Also, the way they run things is actually impressive and we hope that someday, we may be able to organize something just as impressive as the TG event for the Philippines.
Until then, the team and I will keep on working hard and continue learning more so we can get closer to that goal 😁
Hi I’m Mon, and I’m one of the founders of hackstreetboys, a CTF team from the Philippines!
While you’re at it, please like our Facebook page (facebook.com/hackstreetboys)
Follow our Twitter account (https://twitter.com/_hackstreetboys)
Read our writeups on Medium (https://medium.com/hackstreetboys)
Look at our new GitHub page (https://github.com/hackstreetboysph)
Check our website (https://hackstreetboys.ph)