Interstellar C2

Challenge Description

We noticed some interesting traffic coming from outer space. An unknown group is using a Command and Control server. After an exhaustive investigation, we discovered they had infected multiple scientists from Pandora's private research lab. Valuable research is at risk. Can you find out how the server works and retrieve what was stolen?

Evidence

  • capture.pcapng

Solution

Analyze the PCAP file

Although this challenge is labeled as medium-level, many people rate it as hard or very hard. As a result, I expected the challenge to be complicated or contain many layers of obfuscation.

First, I will analyze the PCAP file using Wireshark. From my observations, this network capture primarily shows the connection between two IP addresses: 192.168.25.140 and 64.226.84.200. Therefore, it is necessary to examine the TCP stream between these two IP addresses.

TCP stream 0
TCP stream 2

TCP stream 0: A sequence of obfuscated PowerShell scripts was sent from 64.226.84.200 to 192.168.25.140 (our host).

TCP stream 2: The host at 192.168.25.140 sent a GET request to 64.226.84.200:80. After the connection was successfully established, the website returned encrypted data.

Deobfuscate the Powershell script

The deobfuscated Powershell script will be shown below

A quick analysis will follow:

  1. The script attempts to download content from the URL http://64.226.84.200/94974f08-5853-41ab-938a-ae1bd86d8e51 and then saves it to the path $env:temp\94974f08-5853-41ab-938a-ae1bd86d8e51. Based on TCP stream 2 and the variable in these scripts, the data is encrypted by AES algorithm.

  2. The rest of the script attempts to decrypt the file temp\94974f08-5853-41ab-938a-ae1bd86d8e51 using the provided key and IV. Afterward, the decrypted content is saved to the file tmp7102591.exe.

Decrypt the data in TCP stream 2

Now, we will export the data in packet 62 (which contains encrypted data) in Wirshark and save it to a file.

With the encrypted data, key, and IV, we can write a Python script to decrypt the AES-encrypted information from TCP stream 2. The code is shown below.

Analyst tmp7102591.exe (dropper_cs.exe)

After running the code, we will receive a file called tmp7102591.exe. The first thing I do when I have a malicious file is checking it's hash value then put this hash into VirustTotal to gain further infomation.

Generating tmp7102591.exe's md5 hash value

tmp7102591.exe's MD5: D7C582AFE33AF700119CDB818A9E3A68

VirusTotal result

After browsing through VirusTotal, I noticed that the malware is named dropper_cs.exe and is identified as a .NET executable. This means that we can decompile its code into a more readable form using a tool like DNSpy, which is commonly used for analyzing .NET assemblies.

We will take a look at function primer()

Quick analyst:

  1. The function tries to enumerate the environment of the compromised host to gather information such as COMPUTERNAME, PROCESSOR_ARCHITECTURE, etc

  2. This information will be encrypted with a key, which is a hardcoded value, and then used as a cookie

  3. The cookie is used in the connection to the C2 server (/Kettie/Emmie/Anni?Theda=Merrilee?c). During the connection, an encrypted content will be downloaded to the compromised host, which can be seen in TCP stream 3.

  4. The downloaded content will be decrypted by the Decryption() function using the provided key.

  5. After the content is decrypted, the necessary information will be extracted and passed to the ImplantCore() function for further action.

Decrypt TCP stream 3

The data of TCP stream 3 will be shown below

TCP stream 3

With the insight above, we can use the Decryption() function to decrypt the content in TCP stream 2. To do that, we need to examine how the Decryption function works. The code for this function will be shown below.

The Decryption function reveals that the malware uses the AES algorithm for both encryption and decryption. Since AES is a symmetric encryption algorithm, the same key is used for both processes. Based on the details of the function above, I will create a C# script to decrypt the content.

Now, we need to save TCP stream 2 to a file, then use the code above to decrypt it. After decryption, we will obtain a file containing content like the one below:

It’s worth noting that we have a list of URLS and a new key value here: nUbFDDJadpsuGML4Jxsq58nILvjoNu76u4FIHVGIKSQ=. This value will be passed to the ImplantCore() function. As a result, in the next section, we will examine the ImplantCore() function.

Analyze the ImplantCore() function.

The code of this function will be shown below:

Quick analysis:

  1. Line 1 to 21: The function initializes various components like URL generation, image handling, and sets a decryption key. It also set a time sleep duration and jitter value

  2. Line 24 to 27: In the loops, it checks if the current date has surpassed the "kill date". If the kill date is reached, it stops the execution of implant

  3. Line 36 to 40: the implant receive the command from C2 server via HTTP. The command is decrypt with the new key value (nUbFDDJadpsuGML4Jxsq58nILvjoNu76u4FIHVGIKSQ=)

  4. Line 45 to 108: the implant executes the command via Exec() function

  5. Line 122 to 129: After executing commands, the implant send s the result back to C2 server

Analyze the Exec() function.

This function is responsible for executing the command line. Moreover, it encrypts the output of the command, then obfuscates it by adding it with a random picture. To gain a deeper understanding of how this works, we need to analyze the Program.ImgGen.GetImgData() function.

From the code above, we can see that this function will use the first 1500 bytes for a random picture and a random string. After that, it will append the output of the command to the end of the data. We can observe this data in the TCP stream using Wireshark.

TCP stream 7
TCP stream 20
TCP stream 28

We can observe that these are HTTP POST requests that send data to the URLs we saw in the Setup_Implant.txt. Additionally, we can see that at the beginning of the data, there is an image. However, after that, the data consists of encrypted content, including random strings and the output of the command line. This is exactly what we analyzed in the Program.ImgGen.GetImgData() function.

Decrypt TCP stream 5 (Core.exe and PwrStatusTracker.dll)

We will save the data that the C2 server sent back to the host in TCP stream 5 into a file. Then, we will use the Program.cs from the previous section to decrypt it. This time, we will use key1, so we need to update the code on line 19 to this:

The output should be like below:

We can observe that the data contains in the format

multicmd + Task ID + command line + program data(in base64 format) + !d-3dion@LD!-d

Therefore, we will extract the Base64 format and input it into CyberChef, then save the output to a file. I will call this file malware_2 and malware_3

Cyberchef decoded malware 2
Cyberchef decoded malware 3

Then, I will check the hash value of the files and upload them to VirusTotal.

malware_2 : A4D14345817BA95CB8AB1FFB2140AF0B

malware_3: F4702D36331C71DF5568DBC5BC31DEEE

Malware 2's result in VirusTotal
Malware 3's result in VirusTotal

According to VirusTotal, both of these two malware are written in C#. Therefore, I will use DNSpy to decompile them in order to access the code.

Core.exe's code

We will examine the LoadPowerStatus() function, which is called in TCP_stream_5_decrypted.txt. However, as its name suggests, this function acts as a monitor of the machine's power status, so it will not provide us with any useful information here.

Decrypt the HTTP POST request (TCP stream 8)

Based on the previous information, we know that the first 1500 bytes contain an image and random string. The data containing the output information that we need to extract starts from byte 1501. The image below shows the data we need to extract in TCP stream 8.

TCP stream 8

Copy the highlighted data and paste it into CyberChef to convert it into Base64 format, then save it to a file

Fix line 19 in Program.cs script to this:

Run the Program.cs and we will see the output in plain text:

TCP stream 8 decrypted

Decrypt TCP stream 16 (Mimikatz.exe)

Apply the same technique we used in the previous section with TCP stream 5 to obtain the Core.exe and PwrStatusTracker.dll. After successfully decrypting the data in TCP stream 16, we will receive a file like this:

Now, We can see that the command line was sent from the C2 in plain text. It will run the Mimikatz command within the SharpSploit framework to extract stored or active logon credentials, then the output was sent back to C2 server. We can view the output of this command line by decrypting the data in TCP stream 20.

Decrypt TCP stream 20 (HTTP POST request - credential infiltration)

We will repeat the process used in TCP stream 8. First, we will copy the data from Wireshark and paste it into CyberChef to convert it into Base64 format. Then, we will save the result to a file.

Data in TCP stream 20 need to extract
Converting data to base64 format

Then, we wil run the Program.cs, the output will be shown below

Decrypt TCP stream 28 (HTTP POST request - Picture infiltration)

We will repeat the process used in TCP stream 8. First, we will copy the data from Wireshark and paste it into CyberChef to convert it into Base64 format. Then, we will save the result to a file.

Data in TCP stream 28 need to extract

Then, we wil run the Program.cs. This time the data we receive is in base64 format

Paste this value into CyberChef to decode it. After decoding, we will realize that this is the format of a PNG image.

Save the file and we will find the flag in the image

FLAG: HTB{h0w_c4N_y0U_s3e_p05H_c0mM4nd?}

Last updated