Who is Kimsuky?

The Kimsuky APT is a North Korea-based cyber espionage group operating since at least 2012. Initially, The group targeted South Korean government entities, think tanks, and individuals identified as experts in various fields.

Tracked as: APT43, Black Banshee, Velvet Chollima, THALLIUM, ARCHIPELAGO, and Emerald Sleet

Targets and Objectives: The group primarily targets South Korea, Japan, and the United States, focusing on sectors such as national defense, education, energy, government, healthcare, and think tanks. Their primary objective is intelligence gathering.

Tactics and Tools: Kimsuky employs a variety of tactics, including social engineering, spear-phishing emails, and watering hole attacks. They have developed unique malware for various operations.​

What is TrollAgent Stealer?

Kimsuky began its campaign against significant targets in South Korea in January 2024. By January 24, we found that the compilation times for many samples dated back to December 2023. Based on these and other artifacts, our team at Dark Atlas initiated efforts to track these attacks and investigate the tools used.

Beyond our analysis, we discovered that the TA has registered their installer with digital signatures from “SGA Solutions CO., Ltd.” and “D2innovation CO., LTD.” This is the initial stage of the attack, where the installer is used to deliver and deploy another stage of the malware.

It drops a stealer called TrollAgent, a DLL file written in GoLang and protected using VMProtect3. Additionally, it drops a batch file to remove the initial installer upon dropping the DLL. An executable file named “NXTPKIENTS.exe” is also dropped, which serves as the main file for the SGA package installer.

Then, it writes a file named with the exported function in the TrollAgent DLL to the ProgramData path. The DLL later uses this file to check the execution method.

Attack Chain Overview

Figure 1- TrollAgent attack chain

Technical Analysis

We investigated one of the campaign samples used by Kimsuky, with hash “2e0ffaab995f22b7684052e53b8c64b9283b5e81503b88664785fe6d6569a55e,” and it has a digital signature from “D2innovation CO., LTD.”

Figure 2- Digital Signature

This exe file is dropping a file named \[4\].tmp.bat in the TEMP directory

Figure 3- Created TEMP file

Figure 4- Bat file to delete main installer

This batch script is designed to repeatedly attempt to delete the main installer until it is successfully removed. After the target file is deleted, the script proceeds to delete itself from the system to ensure no residual files are left behind. This process ensures the complete removal of the specified file and cleans up any temporary files created during execution.

It then drop another PE file under C:\Users\\<USER>\AppData\Roaming\Media with the name win-[6].db

Figure 5- Dropped db file

It then drops the main installer, which is NXTPKIE.exe, in the same directory for this process.

Figure 5- Dropped db file

In the ProgramData path, it drops another file with the name of the DLL exported function. The DLL uses this file later to check the execution method. If the file exists, it indicates that the DLL was executed by the main installer, not by a sandbox or analyst.

Figure 6- Dropped Config File

It then creates a process to launch the DLL file, and it calls a specific exported function within the DLL to be executed.

Figure 7- Create Process

TrollAgent Stealer (DLL Analysis)

The DLL file was protected using VMprotect. Unpacking this type of protection is challenging due to its anti-debugging techniques and code virtualization, which make it harder to unpack. However, our team successfully unpacked the sample by attaching a debugger to the process created earlier, editing the creation flags to set it in suspended mode, and then attaching the debugger again. Finding the code’s entry point was difficult due to control flow flattening and obfuscation. Nevertheless, we managed to obtain an unpacked specimen from this DLL file. This DLL was written using Golang and is named TrollAgent.

Figure 8- TrollAgent DLL

Anti-Analysis Techniques

The malware’s main function calls a function named main_anti. Initially, it deletes a scheduled task named “ChromeUpdateTaskMachineUAC” using schtasks.

Figure 9- Deleting a scheduled task

It checks for the configuration file, and if “hai.a” or “oni.a” based on the DLL itself does not exist, it stops the process and deletes itself.

Figure 10- Anti Analysis Check

Then it creates a mutex named “chrome development kit 1.0

Figure 11- Mutex Creation

Building Stealer Configuration

Next, It delves into a function called root_go_s_troll_agent_config_Init which is responsible for Configuration initialization; it sets the version to “gt@2.0,and it also gets the Mac address and then hash it or generates UID for the Mac address

Figure 12- setting version to gt@2.0

Figure 13- Getting Mac address

Then, it sets the C&C servers to be used to communicate with TA; it uses two URLs for that

  1. http://sa[.]netup.p-e[.]kr/index.php
  2. http://dl[.]netup.p-e[.]kr/index.php

Figure 14- Command and Control servers

It then initiates a connection with C2 and marks the request with “init” which is relative to the initialization configuration; it then checks if the response is “ok

Figure 15– sending init data to C2

It then calls two functions, which indicate the core functionality of this stealer:

root_go_s_troll_agent_cmd___CmdGt2__doInfo , root_go_s_troll_agent_cmd___CmdGt2__doWork

Figure 16- main functions

C2 Connection

It then creates an org file, this file contains the collected data about the victim like MAC address, version, used  URLs, and some extra information, these data are RSA encrypted and then sent to the C2 followed by removing this file.

Figure 17- creating org file in .tmp path

Figure 18- Encrypting file using RSA

This file then is sent to the C2 using root_go_s_troll_agent_npww___Client__FileUP function

Figure 19- sending encrypted data to C2

Stealing function

Next, the malware will start collecting the victim’s data. It can collect SSH sessions and FileZilla, and it can steal sticky notes from the machine.

Figure 20- SSH and FileZilla session collection

After building the full file path it uses a function called io_ioutil_ReadDir to read this file, this function is wrapped with root_go_s_troll_agent_cmd___CmdGt2__getYes function.

Figure 21- Reading files

It then executes a command that collects some information.

Figure 22- executed command

Commands explanation

CommandDescriptionOutput
systeminfoGathers detailed system information.OS version, hardware specs, hostname, domain info
query userProvides details on specific user accounts.Usernames, privileges, account status.
net userLists local user accounts.Usernames, groups, account status.
powershell Get-CimInstance -Namespace root/SecurityCenter2 -Classname AntivirusProductQueries Antivirus status (requires PowerShell).Antivirus software name, status, configuration.
wmic qfeLists installed hotfixes (updates).Hotfix IDs, installation dates.
wmic startup getShows programs configured to run at startup.Program names, locations.
wmic process get Caption, CommandLineLists running processes with their details.Process names, command-line arguments.
tasklistProvides a simpler view of running processesProcess names, PIDs (process identifiers).
ipconfig /allDisplays detailed network adapter informationIP addresses, subnet masks, gateways, DNS servers.
arp -aShows the ARP cache (IP to MAC address mapping).IP addresses, corresponding MAC addresses.
route printLists the routing table for network traffic.Destination networks, gateways, metrics
dir “%programfiles%”Lists contents of the “Program Files” directoryInstalled program files and folders.
dir “%programfiles% (x86)”Lists contents of “Program Files (x86)” (32-bit programsInstalled program files and folders.
dir “%programdata%\Microsoft\Windows\Start Menu\Programs”Lists contents of the Start Menu’s Programs folderInstalled application shortcuts.
dir “%appdata%\Microsoft\Windows\Recent”Shows recently accessed files and applications.List of recently used files.
dir /s “%userprofile%\desktop”Lists all files and subfolders within the user’s Desktop.Complete directory listing of the Desktop
dir /s “%userprofile%\downloads”Lists all files and subfolders within the user’s Downloads.Complete directory listing of the Downloads folder.
dir /s “%userprofile%\documents”Lists all files and subfolders within the user’s DocumentsComplete directory listing of the Documents folder

So now, after collecting the above-mentioned data, each data type is zipped and then encrypted using an RSA key, followed by sending it to C2. It uses a function called root_go_i_gapi_ZipTo to compress the files.

Figure 23- Data Compression

A Table for encrypted file names and it’s purpose

Encrypted File NamePurpose
gcfg@[timestamp].gte1Capturing software configuration data
tcd@[timestamp].gte1Logging data of an unidentified directory or file within the C drive
tfd@[timestamp].gte1Storing FileZilla directory information
tsd@[timestamp].gte1Recording SSH directory details
tnd@[timestamp].gte1Gathering data from Sticky Notes directory
tbd@[timestamp].gte1Saving browser-related information
ccmd@[timestamp].gte1Collecting data via cmd

Figure 24- encrypted file names

Collecting Browser data

TrollAgent can harvest a wide range of browsers’ data like other stealers, its functionality is defined to collect credit card information, cookies, browsing history, and auto-login credentials, it has a dedicated function for each browser type like a function for handling all chromium browsers and another one for Firefox one.

Inside root_go_s_troll_agent_cmd___CmdGt2__procBrowser there is a call to root_go_s_troll_agent_internal_browser_PickBrowser and this function wraps calls to the functions responsible for gripping and collecting data, the function that handles chromium stuff is called root_go_s_troll_agent_internal_browser_pickChromium. The function responsible for Firefox is called root_go_s_troll_agent_internal_browser_pickFirefox

Figure 25- functions to collect browsers data

The function that initializes the file path and type of data collected is called root_go_s_troll_agent_internal_browser_init, it contains all browser configurations for Chrome, Edge, Firefox, Brave, Yandex, OperaX, and many other browsers.

Figure 26- Browsers file configuration

TrollAgent has multiple code blocks for each browser to handle the collection part. Each data type has a dedicated function, such as one for retrieving passwords and another for parsing credit cards. This differentiation is necessary because each browser’s database structure is different, leading to variations in the executed SQLite queries across browsers. Let’s provide an overview of this.

Yandex Browser

For Yandex, it has a function for parsing passwords and another function for parsing credit cards.

The type of database is Sqlite3:

Figure 27- Yandex passwords Database

for parsing the database, it executes a SQLite query

  • Query:

Figure 28- password parsing SQL query

Uninstall and Config Deletion

After sending all data to the C2, TrollAgent clears its configuration and uninstalls itself.

Figure 29 – Clearing Config

Inside the main-uninstall function, it does the same as it did in the main_anti function by deleting a scheduled task with the same name “ChromeUpdateTaskMachineUAC”

Figure 30 – Task Deletion

MITRE ATT&CK

TacticTechniqueMITRE ATT&CK IDDescription (In Context of TrollAgent)
ExecutionCommand and Scripting Interpreter: Windows Command ShellT1059.003Kimsuky drops PowerShell (PS) and batch (BAT) files to potentially perform tasks on the compromised machine
Defense EvasionObfuscated Files or Information: Software PackingT1027.002TrollAgent DLL protected using VMProtect3, a packer that obfuscates code to hinder analysis.
System Binary Proxy Execution: Rundll32
T1218.011Kimsuky abuses rundll32.exe, a legitimate Windows program, to execute the malicious TrollAgent DLL
MasqueradingT1036Kimsuky creates files inside user directory
Indicator Removal: File DeletionT1070.004Kimsuky checks for a file dropped by the initial infection stage. If the file doesn’t exist, it terminates itself and deletes its own files to avoid detection.
Credential AccessCredentials from Password Stores: Credentials from Web BrowsersT1555.003Kimsuky targets browser databases to collect usernames and passwords stored by the user
Steal Web Session CookieT1539Kimsuky steals cookies from web browsers to maintain or hijack active sessions
DiscoverySystem Information DiscoveryT1082Kimsuky uses commands such as: systeminfo, hotfixes to gather information about the infected machine
Process DiscoveryT1057Kimsuky uses the tasklist and wmic process get Capture, CommandLine commands to gather the processes running on the system
Account Discovery: Local AccountT1087.001Kimsuky uses the commands net user to find accounts on the system
Network Information GatheringT1016Kimsuky has used ipconfig/all , arp -a and route print to gather network configuration information
File and Directory DiscoveryT1083Kimsuky has used commands such as: dir "%programdata%\Microsoft\Windows\Start Menu\Programs" and dir /s "%userprofile%\desktop" to enumerate all files and directories on an infected system
Software Discovery: Security Software DiscoveryT1518.001Kimsuky checks for the presence of antivirus software with powershell Get-CimInstance -Namespace root/securityCenter2 – classname antivirusproduct
CollectionData from Local SystemT1005Kimsuky might collect SSH keys and FileZilla FTP sessions stored on the compromised system
Screen CaptureT1113Kimsuky uses kbinani/screenshot Go library to take screenshot of the victim machine
Command and ControlApplication Layer Protocol: Web ProtocolsT1071.001Kimsuky uses HTTP GET and POST requests for C2
ExfiltrationExfiltration Over C2 ChannelT1041Kimsuky exfiltrates data over its C2 channel

Indicators of Compromise

IndicatorTypeDescription
9e75705b4930f50502bcbd740fc3ece1MD5Initial installer
27ef6917fe32685fdf9b755eb8e97565MD5Initial installer
7b6d02a459fdaa4caa1a5bf741c4bd42MD5Initial installer
7457dc037c4a5f3713d9243a0dfb1a2cMD5TrollAgent DLL
c8e7b0d3b6afa22e801cacaf16b37355MD5TrollAgent DLL
2e5f2a154e1b67cd0d6a2f6b5feb6de7MD5TrollAgent DLL
045f28a479ba19a95c0407a663e2f188MD5TrollAgent DLL
a67cf9add2905c11f5c466bc01d554b0MD5TrollAgent DLL
3b596ca429cf1b733f1ff3676189e44aMD5TrollAgent DLL
88f183304b99c897aacfa321d58e1840MD5TrollAgent DLL
hxxp://ar.kostin.p-e[.]kr/index.phpURLC2 Server
hxxp://dl.netup.p-e[.]kr/index.phpURLC2 Server
hxxp://qi.limsjo.p-e[.]kr/index.phpURLC2 Server
hxxp://ol.negapa.p-e[.]kr/index.phpURLC2 Server
hxxp://ai.negapa.p-e[.]kr/index.phpURLC2 Server
hxxp://sa.netup.p-e[.]kr/index.phpURLC2 Server

Yara Rule

rule TrollAgent_Kimsuky_Stealer
{
    meta:
        description = "Detect TrollAgent Stealer"
        author = "Dark Atlas Squad"
        date = "2024-07-14"
        
    strings:
        $ex1 = "rollbackHookTrampoline" wide ascii
        $ex2 = "preUpdateHookTrampoline" wide ascii
        $ex3 = "compareTrampoline" wide ascii
        $ex4 = "doneTrampoline" wide ascii
        $ex5 = "authorizerTrampoline" wide ascii

    condition:
        uint16(0) == 0x5a4d and
        pe.characteristics & pe.DLL and
        all of them and
        pe.number_of_exports > 11 and
        for any i in (0 .. pe.number_of_sections) : (
            pe.sections[i].name == ".vmp0" or
            pe.sections[i].name == ".vmp1"
        )
}