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.data
file 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}