Post

Forensics - Chips and Dip Redux - USCG 2024

A forensics and reverse engineering challenge developed by tsuto for Season IV of the U.S. Cyber Open.

Description

The threat actors from last season are back at it again with a new and improved implant that they used to steal the flag. See if you can figure out how to crack it….

Solution

Two files were provided with this challenge.

  1. pid.657970.core - A core dump of an application
  2. chips_and_dip.pcapng - A PCAP containing information about the implant

Summary:

  1. Analyzing the PCAP allowed me to discover the binary, system_update, that was downloaded onto the victim’s computer.
  2. Reverse engineering the binary in Ghidra revealed that system_update was sending and receiving encrypted data.
  3. I was able to obtain the encryption key in GDB using the core dump.
  4. Analyzing the PCAP again, I recovered all the encrypted messages.
  5. Using the key from the core dump, I was able to decrypt all of the messages, revealing the flag.

Analyzing the PCAP

Upon opening the PCAP, the first thing I noticed was an HTTP request to /system_update.

Wireshark

Inspecting this request clearly reveals that a binary file is being downloaded.

Wireshark

I was able to save the binary file by Navigating to File > Export Objects > HTTP in Wireshark.

Running the file command on the exported binary confirms that it is an executable. Additionally, running file on the core dump shows that it was generated from system_update, confirming that system_update is the implant.

1
2
3
4
5
6
[[email protected]]╾─╼[chips-and-dip-redux]
 ▶ file system_update
system_update: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=yG_qz3gz2zrZ4zMo9_wL/cfRliiw7fIg0hQz7vvzu/oGwnV4HK9oKIi8UgGM5G/72tGbi3yBsO3P5NQzwek, with debug_info, not stripped
[[email protected]]╾─╼[chips-and-dip-redux]
 ▶ file pid.657970.core
pid.657970.core: ELF 64-bit LSB core file, x86-64, version 1 (SYSV), SVR4-style, from './system_update'

Reverse Engineering system_update

Reverse engineering the binary is pretty easy because debugging symbols aren’t stripped. Opening the binary in Ghidra and viewing the disassembly for main.main reveals 5 primary actions of the binary.

  1. A random key is generated and saved to main.salsa_key.
  2. The key is encrypted using an embedded public key in main.EncryptWithPublicKey.
  3. The encrypted key is then sent to the remote server via an HTTP request.
  4. The function main.GetC2Command is used to retrieve encrypted commands from a C2 server which are then decrypted and executed.
  5. The function main.SendC2Output encrypts command output and sends it back to the server.

Because a core dump was provided for system_update, and system_update still has symbols, it is easy to recover main.salsa_key in GDB.

1
2
3
4
[[email protected]]╾─╼[chips-and-dip-redux]
 ▶ gdb ./system_update ./pid.657970.core
gef➤  print main.salsa_key
$1 = "E2FAC8A39573F1F416A8C6834BF49216"

Decrypting Traffic

To decrypt the messages it is first necessary to extract all the encrypted messages from the PCAP.

1
2
tshark -nr ./chips_and_dip.pcapng -Y "tcp.stream eq 1" -T fields -e http.file_data |\
xxd -r -p | sed 's/}/}\n/g > messages.txt'

Decrypting the messages is easy using the following Python script.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Cipher import Salsa20
from base64 import b64decode
import json

f = open('./messages.txt', 'r').readlines()

for line in f:
    line = json.loads(line.strip())
    
    try:
        nonce = b64decode(line['Nonce'])
        ciphertext = b64decode(line['Msg'])

        c = Salsa20.new(key=b'E2FAC8A39573F1F416A8C6834BF49216', nonce=nonce)
        plaintext = c.decrypt(ciphertext)
        print(plaintext)
    except:
        pass

Flag: SIVUSCG{b4ck_f0r_an0ther_d1p}

This post is licensed under CC BY 4.0 by the author.