HTB Cyber Apocalypse - Silent Trap


To do this challenge, we had to answer multiple questions :

1. What is the subject of the first email that the victim opened and replied to?
2. On what date and time was the suspicious email sent? (Format: YYYY-MM-DD_HH:MM) (for example: 1945-04-30_12:34)
3. What is the MD5 hash of the malware file?
4. What credentials were used to log into the attacker's mailbox? (Format: username:password)
5. What is the name of the task scheduled by the attacker?
6. What is the API key leaked from the highly valuable file discovered by the attacker?


A critical incident has occurred in Tales from Eldoria, trapping thousands of players in the virtual world with no way to log out. The cause has been traced back to Malakar, a mysterious entity that launched a sophisticated attack, taking control of the developers’ and system administrators’ computers. With key systems compromised, the game is unable to function properly, which is why players remain trapped in Eldoria. Now, you must investigate what happened and find a way to restore the system, freeing yourself from the game before it’s too late.


To do this challenge, we only have a .pcap file. The first thing we can see when we open the file, is a bunch of HTTP packets on some endpoints, and one called email tooks my attention :

Wireshark packets
Figure 1: we can see multiple http packets


To acquire more informations and more context of what are inside these packets, we can follow the conversation :

Wireshark packets
Figure 2: We follow the conversation


It seems that we are dealing with a webmail page, Rouncube. Even if this conversation give us more context, there is no valuable informations :

Wireshark packets
Figure 3: We look at what are inside the conversation


The methodology here is to follow the conversations to have a better understanding of what is happening. After a few scrolls we see the packet 488 which is a POST request :

Wireshark packets
Figure 4: We find the packet 488, which seems interesting


If we follow the conversation of the same packet, we see the content of the request, which is url encoded :

Wireshark packets
Figure 5: We follow the conversation of packet 488


The content looks promising, we need to understand what is the text about, so let’s decode the text :

exegol-forensic /workspace $ urldecode 'token=hiJRTxCbHmwErcJPTYoNEr5QwI1CQINU&_task=mail&_action=send&_id=182422989367bc32a4e3913&_attachments=&_from=6&_to=shadowblade%40email.com%2C&_cc=&_bcc=&_replyto=&_followupto=&_subject=Re%3A+Game+Crash+on+Level+5&_draft_saveid=&_draft=&_is_html=0&_framed=1&_message=Hi+shadowblade%2C%0D%0A%0D%0AThank+you+for+reporting+the+crash+on+Level+5.+We%E2%80%99re+aware+that+this+issue+has+affected+a+few+players%2C+and+our+development+team+is+actively+working+on+a+fix.%0D%0A%0D%0AIn+the+meantime%2C+please+try+launching+the+game+in+%E2%80%9CSafe+Mode%E2%80%9D+%28found+in+the+settings+menu%29+to+see+if+it+bypasses+the+problem+temporarily.+Also%2C+make+sure+your+graphics+drivers+are+up+to+date.%0D%0A%0D%0AAdditionally%2C+we+noticed+that+the+attached+image+may+not+be+related+to+the+issue.+If+the+problem+persists+after+trying+the+suggested+steps%2C+please+send+us+another+email+with+a+clear+screenshot+or+relevant+image+of+the+error.%0D%0A%0D%0AWe+appreciate+your+patience+and+will+update+you+as+soon+as+we+have+a+solution.%0D%0A%0D%0ABest+regards%2C%0D%0ASupport+Team&editorSelector=plain&_mdn=&_dsn=&_priority=0&_store_target=Sen'
token=hiJRTxCbHmwErcJPTYoNEr5QwI1CQINU&_task=mail&_action=send&_id=182422989367bc32a4e3913&_attachments=&_from=6&_to=shadowblade@email.com,&_cc=&_bcc=&_replyto=&_followupto=&_subject=Re:+Game+Crash+on+Level+5&_draft_saveid=&_draft=&_is_html=0&_framed=1&_message=Hi+shadowblade,

Thank+you+for+reporting+the+crash+on+Level+5.+We’re+aware+that+this+issue+has+affected+a+few+players,+and+our+development+team+is+actively+working+on+a+fix.

In+the+meantime,+please+try+launching+the+game+in+“Safe+Mode”+(found+in+the+settings+menu)+to+see+if+it+bypasses+the+problem+temporarily.+Also,+make+sure+your+graphics+drivers+are+up+to+date.

Additionally,+we+noticed+that+the+attached+image+may+not+be+related+to+the+issue.+If+the+problem+persists+after+trying+the+suggested+steps,+please+send+us+another+email+with+a+clear+screenshot+or+relevant+image+of+the+error.

We+appreciate+your+patience+and+will+update+you+as+soon+as+we+have+a+solution.

Best+regards,
Support+Team&editorSelector=plain&_mdn=&_dsn=&_priority=0&_store_target=Sen


Here we have our first flag ! Now, we have a better understanding of what is happening. The conversation is about a problem with a videogame. Also, at the end of the the same packet (488), we can see some contacts, meaning we are potentially from a point of view of the victim, the support team of the game :

Wireshark packets
Figure 6: List of emails


Let’s continue our investigation, we find the packet 524 which is an other GET request. If we follow the conversation, we find two interesting mail, and the one of the potential victim, devteam@koptech.net :

Wireshark packets
Figure 7: We find two new emails


In the same packet, we can see the content of the email from proplayer@gmail.com :

Wireshark packets
Figure 8: The content of the email from proplayer


We saw that there is a zip file as an attachment. Also, proplayer plays on the urgency of the situation to induce the victime to make an action, which is something that attackers loves to do when they send malicious emails. There is no more doubt, we have our malicious file.
Since we know the file is a zip archive, we can use wireshark to filter all HTTP packets by length, because the lenght of the packet containing the zip file should be higher than other ones :

Wireshark packets
Figure 9: We find the zip file


Wireshark has one useful built in function to export file, so let’s use it to retrieve it. You need to go to File -> Export Objects -> HTTP :

Wireshark packets
Figure 10: Exporting the file

Then, we can retrieve the zip file between all the contents :

Wireshark packets
Figure 11: Exporting the file


Let’s retrieve the MD5 hash of the file, for our flag :

exegol-forensic silentTrap $ md5sum suspect.zip                         
cfe9f2109fee272e3826e90dee5b688a  suspect.zip


Since the archive is protected with a password, we can use 7z to unarchive it with the password we foud previously eldoriaismylife :

 exegol-forensic silentTrap $ 7z e suspect.zip 

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs LE)

Scanning the drive for archives:
1 file, 7898 bytes (8 KiB)

Extracting archive: suspect.zip
--
Path = suspect.zip
Type = zip
Physical Size = 7898

    
Enter password (will not be echoed):
Everything is Ok                           

Size:       18944
Compressed: 7898

exegol-forensic silentTrap $ file Eldoria_Balance_Issue_Report.pdf.exe 
Eldoria_Balance_Issue_Report.pdf.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows, 3 sections


We have in our hand a Portable Executable file. One interesting thing here, the attacker added .exe extension after .pdf, he tried to let the victim think it is a pdf file. Now, let’s see if we are lucky and if the program was programmed using .NET, meaning we could decompile it with dnSpy :

exegol-forensic silentTrap $ strings Eldoria_Balance_Issue_Report.pdf.exe | grep -i .net
<PrivateImplementationDetails><5ceda002-b6a9-4e52-b13e-d38ba653d933_netmodule>
System.Net.Sockets
.NETFramework,Version=v4.5
.NET Framework 4.5


For the next steps of this challenge, I moved to a windows machine to decompile the program with dnSpy :

dnSpy view
Figure 12: Our file in dnSpy


Now it’m time for an analysis of this potential malware. The first two things that jumps out at me are the functions Encrypt and xor :

dnSpy view
Figure 13: The encrypt function


The Encrypt function uses a xor encryption to encrypt datas. In the xor function we can see the key used to encrypt :

dnSpy view
Figure 14: The xor function


Ok, we know that this program encrypt some datas, but we don’t know what datas at this point. To have a better understanding of this malware, let’s analyz our main function to see the flow of execution. First, this malware execute a whoami command :

dnSpy view
Figure 15: The main function


The execute function uses a bunch of other function, but here we can see that the program is trying to connect to a remote server :

dnSpy view
Figure 16: The execute function


Here is the connect function where we can definitly see a tcp connection :

dnSpy view
Figure 17: The connect function


In the execute function, we saw a variable named cred, it can maybe contains the credentials used to connect to the remote server, let’s go to it :

dnSpy view
Figure 18: The creds variable


We retrieved the creds used by the attacker to connect to his malicious server, which are proplayer@email.com:completed ! Also, it seems that the program connect to a mail server, we can deduce that because the port used is 143 (IMAP), and also the name of the serveur is mail.korptech.net. Finally, we can see that the malware also use a function called cmd to execute command on the victim machine :

dnSpy view
Figure 19: The function used to execute commands


I tried to make a scheme of the flow of this program to have a better understanding :

schme of the flow of the malware
Figure 20: The flow of the malware


Since we know that IMAP is used for the communication between the remote server and the victim machine, we can filter to only see these packets. We can see that some datas that seems to be encrypted :

Wireshark packets
Figure 21: IMAP packets with encrypted datas


Now, we need to decrypt these datas. Thanks to the malware, it’s using xor to encrypt the datas, and we know the key. We can then use the function used by the malware to decrypt the datas. Let’s build a program in .NET using visual studio :

using System;
using System.Text;

namespace EncryptionExample
{
    public static class Exor
    {
        // The function to encrypt the datas
        public static byte[] Encrypt(byte[] pwd, byte[] data)
        {
            int[] array = new int[256];
            int[] array2 = new int[256];
            byte[] array3 = new byte[data.Length];
            int i;

            // Initialize arrays
            for (i = 0; i < 256; i++)
            {
                array[i] = (int)pwd[i % pwd.Length];
                array2[i] = i;
            }

            // Scramble the arrays
            int num;
            for (i = (num = 0); i < 256; i++)
            {
                num = (num + array2[i] + array[i]) % 256;
                int num2 = array2[i];
                array2[i] = array2[num];
                array2[num] = num2;
            }

            // Perform the encryption
            int num3;
            num = (num3 = (i = 0));
            while (i < data.Length)
            {
                num3++;
                num3 %= 256;
                num += array2[num3];
                num %= 256;
                int num2 = array2[num3];
                array2[num3] = array2[num];
                array2[num] = num2;
                int num4 = array2[(array2[num3] + array2[num]) % 256];
                array3[i] = (byte)((int)data[i] ^ num4);
                i++;
            }

            return array3;
        }
    }

    public class Program
    {
        public static byte[] xor(byte[] data)
        {
            // Here is our key
            return Exor.Encrypt(new byte[]
            {
                168, 115, 174, 213, 168, 222, 72, 36, 91, 209, 242, 128, 69, 99, 195, 164, 238, 182, 67, 92,
                7, 121, 164, 86, 121, 10, 93, 4, 140, 111, 248, 44, 30, 94, 48, 54, 45, 100, 184, 54, 28, 82,
                201, 188, 203, 150, 123, 163, 229, 138, 177, 51, 164, 232, 86, 154, 179, 143, 144, 22, 134, 12,
                40, 243, 55, 2, 73, 103, 99, 243, 236, 119, 9, 120, 247, 25, 132, 137, 67, 66, 111, 240, 108,
                86, 85, 63, 44, 49, 241, 6, 3, 170, 131, 150, 53, 49, 126, 72, 60, 36, 144, 248, 55, 10, 241,
                208, 163, 217, 49, 154, 206, 227, 25, 99, 18, 144, 134, 169, 237, 100, 117, 22, 11, 150, 157,
                230, 173, 38, 72, 99, 129, 30, 220, 112, 226, 56, 16, 114, 133, 22, 96, 1, 90, 72, 162, 38, 143,
                186, 35, 142, 128, 234, 196, 239, 134, 178, 205, 229, 121, 225, 246, 232, 205, 236, 254, 152, 145,
                98, 126, 29, 217, 74, 177, 142, 19, 190, 182, 151, 233, 157, 76, 74, 104, 155, 79, 115, 5, 18, 204,
                65, 254, 204, 118, 71, 92, 33, 58, 112, 206, 151, 103, 179, 24, 164, 219, 98, 81, 6, 241, 100, 228,
                190, 96, 140, 128, 1, 161, 246, 236, 25, 62, 100, 87, 145, 185, 45, 61, 143, 52, 8, 227, 32, 233,
                37, 183, 101, 89, 24, 125, 203, 227, 9, 146, 156, 208, 206, 194, 134, 194, 23, 233, 100, 38, 158, 58,
                159
            }, data);
        }

        static void Main(string[] args)
        {
            // Here we put the encrypted datas
            string dataString = "VGiPTdHXQGP876EbMX2FJhm3ZazpvA8aO8jT1uC8xPhDZq/Np5oZQnHUpKxc36FHBznusaFRsSPtnJzlC4qyGNxcWMCIs1qdVzygFbDj0se4vntsvpU9rKvQPLcPERIjLB36+ws5PVmzVsnuxNmgUPegSj+VPrRfrcHkaE0VL2hOwFIfT8iFNsaVDmnmTwc4DwNxqVqvTfOSr5YCFzLYZhlGMKbBYwhRks/IUuS31pSyoY02zA2T/8MtRORCihusuiBB6lfwkOSDyvxAAS2eTNoqirpJX4oJpFo3HRzFiGt7Tf/hYDvgs4HhXNNUHiBTgR/ckAwJHX0PoBDbTYvxQCtWNytjzQFjF8ir6ihZqFEEUibY3Enkx73tO7zgG5MDXHNRxF6dk7NdM6hcR3RNywIGvr09k/HumgOhs6MgvrHuNauqVWR5t0N52Pf21A6gTNGVtkRfBdnH/vMwOY7egIIxRNR7BlDnaeBlOfmE4aPu5C7BjLhQkwQUcC2mtMa0Sy7vtm+oqIn5po/BFqKsfdreOrYrX3XZ+98F1KC+RVKLPH9pBKd0kH9jHbAMY19YPKl5dok4ls491gXmpv+tb9aPq6PAPkHtAj0ftml7fg==";
            // The first step is to decode the data, which is base64 encoded
            byte[] data_decoded = Convert.FromBase64String(dataString); 
            // The second step is to decrypt the datas, using the same function that encrypted them
            byte[] result = xor(data_decoded);
            // Then, we print the result
            Console.WriteLine(Encoding.UTF8.GetString(result));
        }
    }
}


To complete this challenge, we need to retrive the name of the task created by the attacker. as we know, the program log to the server before sending the output of the commands, so after each login we should find encrypted datas :

Wireshark packets
Figure 22: IMAP packets with encrypted datas


The command used to create the task can be found inside the conversation of the packet 1321 :

Wireshark packets
Figure 23: encrypted command for task creation


Let’s put the data into our program and decrypt it to reveal the name of the task :

visual studio program
Figure 24: plain text command for task


The last task is to retrieve the API key, which can be found in the last imap packet, the 3621 :

Wireshark packets
Figure 25: IMAP packets with encrypted datas


Again, we use our program to decrypt the data and see the decrypted api key

visual studio program
Figure 26: The content of credentials.txt


Let’s do a quick recap of the chain used by the attacker.

An attacker sent an email to the support of a video game and said that he found a bug. To prove what he said, he added an attachment to this mail, a zip file. But, once the file unarchived, the attacker used a double extension, the file is called name.pdf.exe . By doing that in explorer the file has the logo of a pdf, but in reality it’s an executable file ! Once executed, the program added himself to the Startup folder and created a new task as a persistence technique. The attacker was then able to execute a bunch of commands and found a lots of credentials in credentials.txt !