Writeup: INS'hAck 2018 - Take a look inside
Information
- category: Forensics
- points: 400
Description
I acquired some information about my PC because I think someone messed up with it…
You can find everything attached.
Please find out what’s wrong about these captures.
Have fun!
Source: takealookinside.zip
Writeup
This challenge was resolved as an exercise during a weekly meeting and after the end of the CTF.
Analysis
We have a memory dump and a pcap.
PCAP
Two endpoints:
192.168.56.1 and 192.168.56.101 doing TCP traffic (a lot).
Recreating the TCP Stream is a way too long task for wireshark but we can see that IP .101 is sending a lot of data to IP .1 (1 sends only ACKs); filtering only packets with useful data (data.len > 4) from 101 to 1 (data will be in HEX encoding) should be easy with tshark:
tshark -r taking-a-look-inside.pcap -T fields -e data -Y 'ip.src == 192.168.56.101 && data.len > 4' > taking-a-look-inside.out
Using xxd in possibile to convert the HEX data to ASCII.
xxd -r -p taking-a-look-inside.out > taking-a-look-inside.b64
-r reverse operation: convert (or patch) hexdump into binary. If not writing to stdout, xxd writes into its output file without truncating it. Use the combination -r -p to read plain hexadecimal dumps without line number information and without a particular column layout.
Now we have the complete payload and we can see a pattern:
SCN|- a base64 payload
NCS|- goto
1
cat taking-a-look-inside.b64 | sed "s/SCN|\||NCS/\n\n/g" > taking-a-look-inside.txt
In taking-a-look-inside.txt now there are only base64 payload separated with two new lines. Let’s take a look at the first payload:
cat taking-a-look-inside.txt| rg "^$" -A 1 -m 2 | base64 -d > first.datafile fist.data: first.data: data => GARBAGE!
rg is RipGrep (alternative written in Rust to grep): https://github.com/BurntSushi/ripgrep
Memory Dump
Fist we need to identify the memory dump profile to use with volatility.
volatility -f taking-a-look-inside.dmp imageinfo should return the correct profile…no results after some time.
Alternative method for unknown profiles (if is unknown is probably Linux):
strings taking-a-look-inside.dmp | rg -i boot_image
Response: /boot/vmlinuz-4.9.0-6-amd64; a quick Google search will lead us to identify the machine as a Debian with kernel 4.9.0 (64-bit).
But we need a volatility profile to work with, two ways:
- Install Debian 9.4 x64 in a VM and follow this steps: https://github.com/volatilityfoundation/volatility/wiki/Linux#creating-a-new-profile
- Find a profile: https://github.com/volatilityfoundation/profiles/pull/52
Now is possibile to use volatility:
volatility --plugins=../ -f taking-a-look-inside.dmp --profile=LinuxDebian94x64 linux_pstree
1 | olatility Foundation Volatility Framework 2.6 |
The zsh processes took our attention: python3, gimp, insmod and tshark.
Using:
`volatility –plugins=../ -f taking-a-look-inside.dmp –profile=LinuxDebian94x64 linux_enumerate_files | rg -i zsh_history``
and
volatility --plugins=../ -f taking-a-look-inside.dmp --profile=LinuxDebian94x64 linux_find_file -i 0xffff97e9c78883e8 -O zsh_history
we recovered the zsh history file and some interesting commands:
1 | : 1522658873:0;./goggles --host=192.168.56.1 |
Since 192.168.56.1 is the target of our traffic we should focus on the script goggles and his log in /tmp/goggles.log.
1 | volatility --plugins=../ -f taking-a-look-inside.dmp --profile=LinuxDebian94x64 linux_find_file -L | rg -i goggls |
But exporting those files will lead us to a dead end.
./goggles script take a --host= as a paremeter so we can expect to find the same string in memory (if the script is in memory).
Also no strings matching INS{ (better safe than sorry!).
Findings
strings taking-a-look-inside.dmp| rg -i "\-\-host" -A 5
1 | ]2;./goggles --host=192.168.56.1 |
But no others clues…
Wait…goggles is a python script so we can search for a classic python string as import or print(.
For import (with space) and 3 lines after:
1 | import hashlib |
1 | from builtins import property as _property, tuple as _tuple |
1 | from Crypto.Cipher import AES |
Found something interesting!
Maybe the traffic in the pcap is generated with an AES cypher!
Let’s try to recover all the script and/or the key and/or the AES method used.
In zsh_history we saw pip install -r requirements.txt but other hints.
strings is our friend:
strings taking-a-look-inside.dmp | rg "AES" we found something:
[mAES_KEY = [25;5Hcipher = AES.new(AES_KEY, AES.MODE_ECB)
>>> cipher = AES.new(key, AES.MODE_CFB, iv)
maybe the script is using AES in ECB or CFB mode and, also, with a variable AES_KEY or key as encryption key.
strings is such a good friend!!!
strings taking-a-look-inside.dmp| rg "AES_KEY =" -A 3
1 | [mAES_KEY = |
We found a key! d3Adb3Efc4Feb4Be and the first candidate is AES.MODE_ECB due to the function above; we need a script to decrypt the traffic in taking-a-look-inside.txt.
Good old deadbeef cafebabe!
Decryption
1 | import sys |
Decrypting each row in the txt files and using file to detect the file type we got 36 PNGs; these images are screnshoots from the execution of goggles and a tmp.xcf opened in GIMP with the flag.

No way to dump the xcf file from volatility…
Flag
INSA{aa80467558a76019b99ecec7b4f6d0c7}