UTCTF 2019 - Rogue Leader
Andrew Quach
Tags
Problem Description
Our once-venerable president has committed the unspeakable crime of dine-and-dashing the pizza during our own club meetings. He’s on the run as we speak, but we’re not sure where he’s headed.
Luckily, he forgot that we had planted a packet sniffer on his laptop, and we were able to retrieve the following capture when we raided his apartment: [pcap].
He’s too smart to email his plans to himself, but I’m certain he took them with him somehow. Can you help us figure out which country he’s fleeing to?
Reconnaissance
Loading the file in Wireshark, we can clearly see that it is a USB packet capture. First thing is first, let’s figure out which devices were connected to the machine.
So, device 2 (with bus id 1) is a flash drive. Other notable devices include a gaming mouse (device 9, bus id 2), a keyboard (device 5, bus id 2), and a tablet (device 4, bus id 2).
Dumping the Flash Drive
Let’s try to find any files that have been transferred in/out of the flash drive. These packets will be rather large and have the URB_BULK in/out flags set. Filtering just by size nets us one of these packets.
We can dump this data (File > Export packet bytes). This file turns out to be GPG encrypted data.
$ file raw.out
raw.out: GPG symmetrically encrypted data (AES256 cipher)
Now that we have the encrypted file, a natural thing to look for is the password. We can try to get this password from the packets storing data about keyboard presses.
Recovering Key Presses
We can filter for packets with information about keyboard presses.
The “Leftover Data Capture” looks something like this.
00000a0000000000
0000000000000000
0000130000000000
These 8 bytes include the scan code of the keyboard presses. Keyboard modifiers (ctrl, alt, shift) are stored in the first byte. Other key presses are stored in the third byte to the last byte.
[MODIFIER] [RESERVED] [KEY PRESS x6]
Let’s use tshark to dump out all the keyboard data. Note that we’ll filter out empty data.
$ tshark -r capture.pcapng -Y "((usb.transfer_type == 0x01) && !(usb.capdata == 00:00:00:00:00:00:00:00) && (usb.device_address == 5) && (usb.urb_type == 67))" -e "usb.capdata" -Tfields > keyboard.data
$ head keyboard.data
00:00:0a:00:00:00:00:00
00:00:13:00:00:00:00:00
00:00:0a:00:00:00:00:00
00:00:0a:2c:00:00:00:00
00:00:2c:00:00:00:00:00
00:00:2d:00:00:00:00:00
00:00:06:00:00:00:00:00
00:00:2c:00:00:00:00:00
00:00:09:00:00:00:00:00
00:00:09:0f:00:00:00:00
We can use a python script to decode the key presses. I found a script online that does most of the work for me. I only changed it a little to fit my needs (e.g. adding more scan codes).
# Original Source: https://bitvijays.github.io/LFC-Forensics.html
# More Scan Codes: https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2
usb_codes = {
0x04:"aA", 0x05:"bB", 0x06:"cC", 0x07:"dD", 0x08:"eE", 0x09:"fF",
0x0A:"gG", 0x0B:"hH", 0x0C:"iI", 0x0D:"jJ", 0x0E:"kK", 0x0F:"lL",
0x10:"mM", 0x11:"nN", 0x12:"oO", 0x13:"pP", 0x14:"qQ", 0x15:"rR",
0x16:"sS", 0x17:"tT", 0x18:"uU", 0x19:"vV", 0x1A:"wW", 0x1B:"xX",
0x1C:"yY", 0x1D:"zZ", 0x1E:"1!", 0x1F:"2@", 0x20:"3#", 0x21:"4$",
0x22:"5%", 0x23:"6^", 0x24:"7&", 0x25:"8*", 0x26:"9(", 0x27:"0)",
0x2C:" ", 0x2D:"-_", 0x2E:"=+", 0x2F:"[{", 0x30:"]}", 0x32:"#~",
0x33:";:", 0x34:"'\"", 0x36:",<", 0x37:".>", 0x38:"/?", 0x4f:">",
0x50:"<"
}
lines = ['']
pos = 0
for x in open("keyboard.data","r").readlines():
x = x.split(':')
code = int(x[2], 16)
if code == 0:
continue
# 0x51 -> Keyboard Down
# 0x28 -> Enter;
if code == 0x51 or code == 0x28:
pos += 1
if pos > len(lines)-1:
lines.append('')
continue
# 0x52 -> Keyboard Up;
if code == 0x52:
pos -= 1
continue
# Shift modifier
if int(x[0],16) == 2:
lines[pos] += usb_codes[code][1]
else:
lines[pos] += usb_codes[code][0]
for x in lines:
print(x)
The output of this is:
$ python decode.py
gpgg -c fflaagss.ppng
utNOTflag{try_haardeer}
utNOTflag{try_hardeer}
cp flaggs.png.gpg /media/usserr/USB/
Although there are some duplicated letters, we can still see the password is utNOTflag{try_harder}. We can now decrypt the file we found before.
$ gpg -o flags.png -d raw.out
<type utNOTflag{try_harder} twice>
$ file flags.png
flags.png: PNG image data, 112 x 163, 8-bit/color RGBA, non-interlaced
And we get flags.png!
Last Steps Before (getting the flag)
Now that we have flags.png, perhaps the flag is hidden with some steganography techniques. After fiddling around with it, we find that another image is hidden in the LSB of flags.png. Using an online tool, we get the hidden image.
Flag: utflag{t3x45_1s_my_f4v0r1te_c0untry}