Go to Top

Go to Top

1% blind spots, 100% risk.
Protect your business with white-hat hackers.

1% blind spots, 100% risk. Protect your business with white-hat hackers.

Identify vulnerabilities that could lead to data leaks from the attackers perspective,
and strengthen your security posture in advance.

Identify vulnerabilities that could lead to data leaks from the attackers perspective, and strengthen your security posture in advance.

Identify vulnerabilities that could lead to data leaks from the attackers perspective,and strengthen your security posture in advance.

The choice of security-first
enterprises: Enki WhiteHat.

The choice of security-first
enterprises: Enki WhiteHat.

With extensive project experience across industries,
we provide customized security solutions tailored to your business environment and needs.

With extensive project experience across industries,
we provide customized security solutions tailored to your business environment and needs.

With extensive project experience across industries, we provide customized security solutions tailored to your business environment and needs.

Large Enterprises

Financial Institutions

IT & Security Companies

Military / Public Sector Organizations

Large Enterprises

Financial Institutions

IT & Security Companies

Military / Public Sector Organizations

Large Enterprises

Financial Institutions

IT & Security Companies

Military / Public Sector Organizations

Unidentified hacks and relentless breaches

Unidentified hacks and relentless breaches

Unidentified hacks and relentless breaches

uncertainty keeps building up, while the burden of responsibility falls entirely on security teams.

uncertainty keeps building up, while the burden of responsibility falls entirely on security teams.

uncertainty keeps building up, while the burden of responsibility falls entirely on security teams.

With data breaches continuing to occur, is your company truly safe?

With data breaches continuing to occur, is your company truly safe?

With data breaches continuing to occur, is your company truly safe?

Uncontrolled IT Assets

Uncontrolled IT Assets

Uncontrolled IT Assets

Sophisticated Attacks

Sophisticated Attacks

Sophisticated Attacks

Frequent Feature Updates

Frequent Feature Updates

Frequent Feature Updates

Frequent Feature Updates

Increasing Vendor Connections

Increasing Vendor Connections

Increasing Vendor Connections

Cloud & Remote Work

Cloud & Remote Work

Cloud & Remote Work

AI Service Adoption

AI Service Adoption

AI Service Adoption

AI Service Adoption

Shortage of Security Personnel

Shortage of Security Personnel

Shortage of Security Personnel

Stricter Regulatory Requirements

Stricter Regulatory Requirements

Stricter Regulatory Requirements

Stay one step ahead of attackers.

Stay one step ahead of attackers.

Stay one step ahead of attackers.

Stay one step ahead of attackers.

Stay one step ahead of attackers.

Stay one step ahead of attackers.

Enterprise security must be meticulous.
Attackers exploit even the smallest 1% of blind sots— It’s time to think like them,
and adopt proactive, preventive security measures.

Enterprise security must be meticulous.
Attackers exploit even the smallest 1% of blind sots— It’s time to think like them,
and adopt proactive, preventive security measures.

Enterprise security must be meticulous.
Attackers exploit even the smallest 1% of blind sots— It’s time to think like them,
and adopt proactive, preventive security measures.

We uncover critical vulnerabilities that threaten your enterprise.

We uncover critical vulnerabilities that threaten your enterprise.

We uncover critical vulnerabilities that threaten your enterprise.

Ethical white-hat hackers simulate attacks from the attacker’s perspective to
identify issues that could lead to financial loss, data breaches, or service disruptions.

Ethical white-hat hackers simulate attacks from the attacker’s perspective to
identify issues that could lead to financial loss, data breaches, or service disruptions.

Ethical white-hat hackers simulate attacks from the attacker’s perspective toidentify issues that could lead to financial loss, data breaches, or service disruptions.

Server Takeover &
Privilege Escalation

Server Takeover &
Privilege Escalation

서버 보안을 상징하는 열쇠 아이콘

Validate potential for root-level server access remotely

Validate potential for root-level server access remotely

Identify server takeover scenarios via unused ports and vulnerable services

Identify server takeover scenarios via unused ports and vulnerable services

Detect internal server access paths through service vulnerability analysis

Detect internal server access paths through service vulnerability analysis

Malicious Activity

Malicious Activity

악성 행위를 상징하는 위험 신호 표시 아이콘

Simulate duplication of e-currency/points and fraudulent payments

Simulate duplication of e-currency/points and fraudulent payments

Prove feasibility of creating and distributing malicious apps

Prove feasibility of creating and distributing malicious apps

Validate privilege escalation through vulnerabilities (XSS, data exposure, etc.)

Validate privilege escalation through vulnerabilities (XSS, data exposure, etc.)

Verify potential bypass routes via external staff/employee devices

Verify potential bypass routes via external staff/employee devices

Data Exfiltration

Data Exfiltration

자료를 상징하는 폴더 아이콘

Confirm risk of sensitive data leaks (customer PII, internal documents, etc.)

Confirm risk of sensitive data leaks (customer PII, internal documents, etc.)

Demonstrate external data exfiltration via arbitrary command execution

Demonstrate external data exfiltration via arbitrary command execution

Validate customer data access after admin privilege hijacking

Validate customer data access after admin privilege hijacking

Assess data extraction risks from bypassing existing security solutions

Assess data extraction risks from bypassing existing security solutions

Reproduce external data transmission via SSH tunneling scenarios

Reproduce external data transmission via SSH tunneling scenarios

Enki Products

Enki Products

OFFen

OFFen

OFFen

No more waiting,
Vulnerability assessments

No more waiting,
Vulnerability assessments

more

more

more

ASM

ASM

ASM

Visualize every hidden threat in your asset network—no blind spots.

Visualize every hidden threat in your asset network—no blind spots.

Checklist/Offensive PT

Checklist/Offensive PT

Checklist/Offensive PT

Optimized for ISMS-P certification
Assess only what you need—specific websites, apps, or systems

Optimized for ISMS-P certification
Assess only what you need—specific websites, apps, or systems

Red Team

Red Team

Red Team

End-to-End security assessments by professional white-hat hackers through real-world attack scenarios

End-to-End security assessments by professional white-hat hackers through real-world attack scenarios

Enki Products

Enki Products

CAMP

CAMP

CAMP

A security capability growth platform that enhances your team’s practical skills and strengthens internal response—even in critical moments.

A security capability growth platform that enhances your team’s practical skills and strengthens internal response—even in critical moments.

more

more

more

Training

Training

Training

Build solid security capabilities from the ground up through practice-driven learning in digital forensics, incident response, malware analysis, web hacking, and security device operations.

Build solid security capabilities from the ground up through practice-driven learning in digital forensics, incident response, malware analysis, web hacking, and security device operations.

Wargame

Wargame

Wargame

Strengthen core skills by solving domain-specific challenges, share high-quality write-ups, and boost motivation with a ranking system.

Strengthen core skills by solving domain-specific challenges, share high-quality write-ups, and boost motivation with a ranking system.

CTF (Capture the Flag)

CTF (Capture the Flag)

CTF (Capture the Flag)

Easily set up in-house CTF environments using diverse content—even for non-specialists—and assess team-wide security capabilities.

Easily set up in-house CTF environments using diverse content—even for non-specialists—and assess team-wide security capabilities.

Attack-Defense Exercises

Attack-Defense Exercises

Attack-Defense Exercises

Strengthen organizational collaboration with real-time attack and defense drills in a virtual infrastructure that mirrors the enterprise environment, using real-world cases (TTPs, vulnerabilities, scenarios).

Strengthen organizational collaboration with real-time attack and defense drills in a virtual infrastructure that mirrors the enterprise environment, using real-world cases (TTPs, vulnerabilities, scenarios).

Enki Service

Enki Service

Offensive Security Assessments

Experienced white-hat hackers with advanced technical expertise conduct comprehensive assessments across your IT infrastructure. They identify and validate threats that could lead to financial loss, data breaches, or service disruptions, and provide actionable defense strategies.

more

Red Teaming

Compliance Audits

Penetration Testing

Remediation Checks

Cyber Threat Intelligence

Backed by the analysis of over 20,000 malware samples from North Korea, China, Russia, and beyond, our experts deliver refined threat intelligence and tailored response strategies. During incidents, we trace attacker behaviors, infiltration paths, and impact scope to eliminate root causes and strengthen defenses.

more

Malware Analysis

Digital Forensics

Security Training & Exercises

As Korea’s #1 cyber defense competition operator, we provide high-quality, real-world challenges that simulate actual incidents. With extensive penetration testing and global competition experience, we deliver the latest cybersecurity training and customized practice environments designed to equip professionals with immediately applicable skills.

more

Hands-on Training

CTF Operations

Phishing Simulations

Offensive Security Assessments

Experienced white-hat hackers with advanced technical expertise conduct comprehensive assessments across your IT infrastructure. They identify and validate threats that could lead to financial loss, data breaches, or service disruptions, and provide actionable defense strategies.

more

Red Teaming

Compliance Audits

Penetration Testing

Remediation Checks

Cyber Threat Intelligence

Backed by the analysis of over 20,000 malware samples from North Korea, China, Russia, and beyond, our experts deliver refined threat intelligence and tailored response strategies. During incidents, we trace attacker behaviors, infiltration paths, and impact scope to eliminate root causes and strengthen defenses.

more

Malware Analysis

Digital Forensics

Security Training & Exercises

As Korea’s #1 cyber defense competition operator, we provide high-quality, real-world challenges that simulate actual incidents. With extensive penetration testing and global competition experience, we deliver the latest cybersecurity training and customized practice environments designed to equip professionals with immediately applicable skills.

more

Hands-on Training

CTF Operations

Phishing Simulations

Offensive Security Assessments

Experienced white-hat hackers with advanced technical expertise conduct comprehensive assessments across your IT infrastructure. They identify and validate threats that could lead to financial loss, data breaches, or service disruptions, and provide actionable defense strategies.

more

Red Teaming

Compliance Audits

Penetration Testing

Remediation Checks

Cyber Threat Intelligence

Backed by the analysis of over 20,000 malware samples from North Korea, China, Russia, and beyond, our experts deliver refined threat intelligence and tailored response strategies. During incidents, we trace attacker behaviors, infiltration paths, and impact scope to eliminate root causes and strengthen defenses.

more

Malware Analysis

Digital Forensics

Security Training & Exercises

As Korea’s #1 cyber defense competition operator, we provide high-quality, real-world challenges that simulate actual incidents. With extensive penetration testing and global competition experience, we deliver the latest cybersecurity training and customized practice environments designed to equip professionals with immediately applicable skills.

more

Hands-on Training

CTF Operations

Phishing Simulations

Check out the latest
threat insights and reports.

Check out the latest
threat insights and reports.

Check out the latest
threat insights and reports.

more

more

more

Threat Intelligence

In-Depth Analysis of the APT Down - The North Korea Files leak

This section analyzes the malware discovered in the actor's VMware dump and the spear-phishing and infrastructure operations identified in the VPS dump. Notably, the rootkit and backdoor found in the tomcat20220420_rootkit and tomcat20250414_rootkit_linux234 directories are linked to a past incident at a South Korean financial institution investigated by our team.1.1. tomcat20220420_rootkit1.1.1. BackdoorThe backdoor source code is located in the work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/work directory. The backdoor's primary functions are to execute malicious commands or to act as a proxy for relaying network traffic. It is always executed by the rootkit and does not run as a standalone process.The backdoor's execution arguments are described in the table below.caption - Command-line optionsWhen the proxy flag is enabled, the command-handling logic is bypassed, and the backdoor waits to receive an AES-256-CBC encrypted "__step2__".caption - Data validation logic in master.cThe AES key and IV are as follows:AES key: 603deb15153a715e2b73aef3857d758b1f552c573e6158d72d9811a33914defeIV: 603deb15153a715e2b73aef3857d758b1f552c573e6158d72d9811a33914defeTo masquerade its traffic, the backdoor can wrap its socket communication in one of the following protocols, as defined in install_common.h:HTTPHTTPSSSLTCPSMTPcaption - Protocol definition in install_common.hAll data, including command codes, is encrypted and decrypted using a multi-byte XOR operation with the key "1101link". The implementation of this logic results in an operation equivalent to a single-byte XOR with the value 1.caption - EncodeDecode function in encrypt.cThe supported commands are listed below.caption - Backdoor command descriptions1.1.2. syslogk rootkitThe file work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/main.c contains the source code for the syslogk rootkit. This rootkit hides the directory containing the backdoor and related malware to evade detection. It also ensures the backdoor only runs when triggered by a specific magic packet from the actor.The rootkit hooks three functions to hide processes, ports, and directories.caption - Function hooksThe hooked functions use strstr to compare target entries against predefined strings (process names, paths, ports) and remove any matches before returning the results.The rootkit then uses nf_register_hook to register callback functions at two Netfilter hook points:NF_INET_LOCAL_IN: Intercepts packets just before they are delivered to a local process.NF_INET_LOCAL_OUT: Intercepts packets just before they are sent from a local process.caption - Netfilter hook registration logic in hkcap.cThis allows the rootkit to monitor all traffic and execute malicious actions upon receiving a magic packet.The NF_INET_LOCAL_IN callback function inspects incoming TCP packets, decrypts the payload, and checks if it matches specific conditions. The decryption keys are listed below.caption - Decryption keysThe conditions and corresponding actions are detailed below.caption - Conditions and actionsAt the NF_INET_LOCAL_OUT hook point, the callback function changes the source port of packets originating from the backdoor to a non-listening port.After registering the Netfilter callbacks, the rootkit removes itself from the system's module list to evade detection by tools like lsmod.caption - hide_module functionThe hidden rootkit can be made visible again by writing the value of MAGIC_DRBIN (defined in install.h) to a specific file controlled by the rootkit.caption - proc_write function logic1.1.3. Backdoor ClientThe file work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/work/tcat.c contains the source code for the backdoor client. This tool was likely run by the actor on their C&C server.The client accepts several command-line options, which are detailed below.caption - Command-line optionsCommands can be delivered to the backdoor in four ways:single cmd: Sends a single command to the backdoor for execution.single daemon cmd: Sends a command to be executed in a new process on the backdoor host.input loop: Enters an interactive loop, accepting commands until exit is entered.kernel cmd: Sends a command to be executed by the kernel module without returning output.Except for the input loop, the client terminates after sending the command. The commands available in the input loop are listed below.caption - Backdoor client command descriptionsAll communication is encrypted with the XOR key "1101link". For each message, the client computes a SHA512 hash of the password combined with the GENERAL_MODULE and GENERAL_PROTOCOL values defined in common.h. This hash is prepended to the message before transmission. Communication with the backdoor can be configured to use one of the following protocols:TCPHTTPOLD HTTP (A variant of HTTP that does not use cookies)1.2. tomcat20250414_rootkit_linux2341.2.1. BackdoorThe directory work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/work contains the source code for the 2025 version of the backdoor. This is an upgraded version of the 2022 backdoor, with new features such as password verification for delayed callbacks, configurable callback timers, and rate-limiting for file transfers. Its command-line options are listed below.caption - Command-line optionsIn addition to the existing password, this version introduces a master password. When a client connects, the backdoor computes a SHA512 hash of the master password and connection settings. The master password, !@nf4@#fndskgadnsewngaldfkl, is defined in common.h. While the hash is stored in a global variable and checked during SSL communications, it is not actively used. The client's provided password is then hashed in the same manner and verified.caption - passcheck_check function in encrypt.cThe password is Miu2jACgXeDsxd. Configuration settings, including the password, can be modified in config.sh and are applied at build time.caption - Default settings in config.shThe communication protocols are the same as the 2022 version:HTTPHTTPSSSLTCPSMTPWhile the original XOR key is still present, five new XOR keys and corresponding encryption/decryption functions have been added.caption - All XOR keys found in encrypt.cThis version adds several new commands and modifies the behavior of commands with "TRANSFER" in their names. The newly added command codes are:CMD_NEW_UPLOADCMD_NEW_DOWNLOADCMD_LISTEN_PROXY_TRANSCMD_TRANSFERCMD_PROXY_TRANSFERCMD_SOCKS_PROXY_TRANSFERCMD_SOCKS_PROXYCMD_NEW_SINGLE_CMDThe command behaviors are detailed in the table below. (new or significantly modified commands are grouped with an asterisk).caption - Backdoor command descriptions1.2.2. syslogk rootkitThe file at work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/main.c is the 2025 version of the rootkit. Like its predecessor, it registers callbacks at Netfilter hook points, but it features significant changes to its function hooking, module hiding, and Netfilter implementation.While the 2022 rootkit used the udis86 library for function hooking, the 2025 version uses the khook library.caption - Left: 2022 rootkit (udis86). Right: 2025 rootkit (khook).This version hooks a total of five functions, up from three in the 2022 version.caption - Function hooksThe number of Netfilter hooks has increased from two to four.NF_INET_LOCAL_IN: Before a packet is delivered to a local process.NF_INET_LOCAL_OUT: Before a packet is sent from a local process.NF_INET_PRE_ROUTING: Immediately after a packet enters the network stack.NF_INET_POST_ROUTING: Just before a packet is placed on the wire, after routing.caption - Netfilter hook registration logic in hkcap.cThe NF_INET_PRE_ROUTING callback performs two main actions. First, it checks for a magic packet to execute the backdoor, similar to the NF_INET_LOCAL_IN hook in the 2022 version. However, the condition is simpler: it only checks for a TCP SYN packet where the ID and sequence number are present in the id_list and seq_list.If the condition is met, the packet's window value is used to determine which masquerade protocol to use when launching the backdoor.caption - Masquerade protocolsThe method for executing the backdoor has also changed significantly. Instead of /bin/sh -c, this version uses call_usermodehelper to launch the backdoor on a random port between 3000 and 8000.caption - kernel_run function in hkcap.cThe second action of the PRE_ROUTING hook is to change the destination port of any packet from the C&C IP to the randomly generated backdoor port. This allows the actor to communicate with the backdoor without knowing the randomly assigned port in advance.caption - Code to change packet destination in hkcap.cThe NF_INET_LOCAL_IN callback function then changes the packet's destination port again, from the random port to the actual port the backdoor is listening on. This two-step redirection appears designed to obscure the backdoor's true listening port.caption - Code to change packet destination to the backdoor port in hkcap.cThe NF_INET_LOCAL_OUT callback changes the source port of outgoing backdoor packets from the listening port to an arbitrary port.The NF_INET_POST_ROUTING callback then changes the source port from the arbitrary port to the actual C&C port.caption - Code to change packet destination to the actor's port in hkcap.cThe rootkit's hiding mechanism has been enhanced to remove the module from sysfs in addition to the standard module list.caption - Module hiding code in hkmod.cThe sysfs-related functions are taken directly from the kv_hide_mod function of the KoviD rootkit.caption - kv_hide_mod function in the KoviD rootkitWhile writing a specific string to the rootkit still unhides it, this version adds the ability to dynamically configure the ports used by the Netfilter hooks by writing other specific strings.caption - Port configuration code in hkcap.cAll strings written to the rootkit, except for the unhide command, are first decrypted with AES-256-CBC. The key and IV are as follows:AES key: d03deb92153a71458973aef3857d75b27e552cc63e6158a8339811873994de47IV: efa3c987532cc0bdac533845ad8df5eaThe actions triggered by writing to the rootkit are listed below.caption - Strings and triggered actions1.2.3. Backdoor ClientThe file work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/work/tcat.c contains the source code for the 2025 backdoor client. Compared to the 2022 version, the primary change is the removal of the kernel command (kc) option. A new LLL option for specifying a log file path has been added. The full list of options is below.caption - Command-line optionsWith the removal of the kernel command feature, commands are delivered in three ways:single cmd: Sends a single command to the backdoor for execution.single daemon cmd: Sends a command to be executed in a new process on the backdoor host.input loop: Enters an interactive loop, accepting commands until exit is entered.While the 2022 client only accepted simple commands, the 2025 client allows options to be specified for each command, enabling more precise control. The number of top-level commands has decreased, but their functionality is more sophisticated. The commands available in the input loop are listed below.caption - Backdoor client command descriptionsA full analysis of the new features was not possible, as key functions for the new commands (e.g., tcat_new_send_file, tcat_new_recv_file) were not defined in the provided source code.Unlike the 2022 client, which sent a SHA512 hash of the password with every communication, the 2025 client sends it only once during the initial connection.All communication is still encrypted with the XOR key "1101link". However, the available communication protocols have changed. The "OLD HTTP" option has been removed, and HTTPS and SMTP have been added. The supported protocols are:TCPHTTPHTTPSSMTP1.3. Cobalt Strike1.3.1. Cobalt Strike LoaderA Rust-based loader designed to decrypt and execute embedded shellcode was found at the following paths:work/mnt/hgfs/Desktop/New folder (2)/DboRrmSS.exework/mnt/hgfs/Desktop/New folder (2)/m01QzOfI.exework/mnt/hgfs/Desktop/New folder (2)/voS9AyMZ.tar.gzwork/home/user/.cache/vmware/drag_and_drop/0pkbW4/3Powwovv.exework/home/user/.cache/vmware/drag_and_drop/gWMDML/GnAN3FhY.exework/home/user/.cache/vmware/drag_and_drop/QqiN9h/DboRrmSS.exework/home/user/.cache/vmware/drag_and_drop/rM0FG0/m01QzOfI.exeThe loader dynamically resolves Windows APIs using djb2 hashing. It then decrypts the shellcode with AES-256-CBC and executes it in memory.caption - API hashing functionThe AES keys and IVs for each loader instance are listed below.caption - Cobalt Strike Loader AES keys and IVs1.3.2. ShellcodeThe shellcode executed by the Cobalt Strike Loader decrypts and runs the final Cobalt Strike Beacon payload in memory. This shellcode was also found as standalone files at the following paths:work/home/user/.cache/vmware/drag_and_drop/5wdgDr/payload.binwork/home/user/.cache/vmware/drag_and_drop/6bX9mm/Black.x64.exework/home/user/.cache/vmware/drag_and_drop/NDBu65/payload.binwork/home/user/.cache/vmware/drag_and_drop/yf91yD/payload.binwork/home/user/.cache/vmware/drag_and_drop/zlLWeR/payload.binThe file work/home/user/.cache/vmware/drag_and_drop/6bX9mm/Black.x64.exe is a compiled executable but is functionally identical to the other shellcode files.caption - DIE result for Black.x64.exeLike the loader, the shellcode dynamically resolves Windows APIs using djb2 hashing. The embedded Cobalt Strike Beacon is decrypted using RC4 and executed in memory.caption - RC4 ksa functionThe RC4 keys used by each file are listed below.caption - Shellcode RC4 keysNotably, the Cobalt Strike Beacons deployed via this shellcode patch ETW and AMSI functions to evade detection. The encrypted beacon configuration was truncated, preventing a full analysis of its contents.1.3.3. Cobalt Strike BeaconThe source code for a Cobalt Strike Beacon was found under work/mnt/hgfs/Desktop/111/beacon. Upon execution, it decrypts its configuration using a single-byte XOR key (0x2e). A portion of the decrypted configuration, as parsed by CobaltStrikeParser, is shown below.caption - CobaltStrikeParser outputAlthough the configuration contains a C&C server address and endpoint, the beacon ignores these and uses hardcoded values instead.caption - send_Metadata function in comm.cppAfter parsing the configuration, the beacon generates metadata to send to the C&C server. Key values are listed below.caption - Metadata fieldsAfter sending the initial metadata, it begins polling for commands from the C&C server via HTTP GET requests every 5 seconds and sends the results back via HTTP POST. The supported command ids are listed below.caption - Cobalt Strike Beacon commandsThe majority of commands are either unimplemented or disabled, suggesting this is an incomplete version of the beacon.1.3.4. C# LoaderThe directory work/home/user/Desktop/0128.zip contained a C# loader (ok.dll), its source code (ok.cs), and a runner script (ok.sct) designed to inject a Cobalt Strike Beacon into another process.The frequent use of the word "test" in function names and arguments suggests this tool was experimental.ok.htaThe ok.hta file is an HTML Application that downloads a script from hxxp://192.168[.]123.200/ok.sct and calls its Fuk method.caption - ok.hta contentThe downloaded script is presumed to be the ok.sct file found in the same archive.ok.sctThis script deserializes an embedded byte array into a C# object and invokes its Work method. This object is presumed to be the ok.dll loader.caption - deserialization code in C# LoaderThe C# loader injects a Cobalt Strike Beacon into a conhost.exe process. The beacon payload is stored as a zlib-compressed and Base64-encoded string.caption - Cobalt Strike Beacon decode functionBelow is a portion of the beacon's configuration, extracted using CobaltStrikeParser.caption - CobaltStrikeParser output1.4. Ivanti Connect Secure1.4.1. BRUSHFIREThe zip file at work/mnt/hgfs/Desktop/ivanti-new-exp-20241220.zip contains Python scripts that leverage an Ivanti Connect Secure RCE exploit to deploy a backdoor.The script crafts a clientCapabilities value to trigger CVE-2025-0282 and achieve RCE.caption - exploit in exp*.pyCVE-2025-0282 has been exploited by UNC5221, a suspected China-nexus threat actor.Multiple versions of these scripts were found, all functionally equivalent with minor variations in function offsets and service endpoints. The command-line arguments accepted by the scripts are listed below.caption - Command-line optionsThe script establishes a random 3-byte magic value and a random 4-byte key for each host. It uses the RCE exploit to execute plugins/install, which overwrites the legitimate ssl_read function with the backdoor from plugins/ssl_read. During communication, when the backdoor receives a payload starting with themagic value, it XOR-decrypts the rest of the payload with the key and executes it as shellcode.caption - shellcode execution code in ssl_readThe script generates and uploads different shellcode payloads to the target server based on the provided options. It uses the replace method to patch the shellcode, adapting hardcoded placeholder values for the target environment. The table below details the options that deploy shellcode from the plugins directory and the purpose of each payload.caption - Options and corresponding shellcodeThe plugins/ssl_read backdoor and its associated file paths match the description of the BRUSHFIRE malware used by UNC5221, as detailed in this report.1.4.2. SPAWN Family ClientThe zip file at work/mnt/hgfs/Desktop/New folder/203.234.192.200_client.zip was found to contain a tunneling script, an SSH client, and an SSH private key. The included readme.txt file contains instructions for using client.py and controller.py to connect to 203.234[.]192.200, an IP address belonging to the South Korean news organization Hankyoreh.caption - content of readme.txtclient.py uses a SOCKS5 proxy to tunnel network traffic and accepts the following options:caption - Option descriptionsclient.py initializes values for client_hello and client_key_exchange packets, which are used as follows:client_hello: Before transmission, random data is written to client_hello[15:43], the CRC32 checksum of this data is written to client_hello[11:15], and a random 32-byte sessionid is included in the message.client_key_exchange: Before transmission, a random 256-byte value is written to the premaster field, and a random 32-byte value is written to the enc_handshake_msg field.The initial hardcoded value of client_hello is identical to the magic packet in the SPAWNMOLE sample detailed in this UNC5221 report. The runtime modification—writing random data and its CRC32 checksum—is consistent with the behavior of the SPAWNCHIMERA sample described in JPCert's report.Like SPAWNMOLE, SPAWNCHIMERA was deployed by UNC5221 using CVE-2025-0282 as an initial access vector.controller.py is an SSH client that uses the SOCKS5 proxy established by client.py for communication.caption - SSH client code in controller.pySPAWNMOLE was discovered alongside SPAWNSNAIL, which is capable of running an SSH server. SPAWNCHIMERA also includes SSH server functionality. Therefore, controller.py is likely a client for the SSH server component of either SPAWNSNAIL or SPAWNCHIMERA.1.4.3. ROOTROT ClientThe script at work/mnt/hgfs/Desktop/ivanti_control/main.py functions as a client for a webshell. Depending on the options provided, it generates a Perl script fragment, Base64-encodes it, sets a cookie to the encoded value, and sends an HTTP GET request. The options and their corresponding scripts are listed below.download {file_path}{command}Both Perl scripts Base64-encode their output and wrap it in HTML comments. The main.py client then extracts the content of the last comment in the HTTP response, Base64-decodes it, and prints the result.caption - The function that sends the request and decodes the responseROOTROT, as described in this UNC5221 report, is a Perl-based web shell that Base64-decodes a cookie value before executing it with eval. It then sends the Base64-encoded results back within HTML comments. This behavior confirms that main.py is the client for the ROOTROT web shell.Like the other UNC5221 malware mentioned, ROOTROT has been found in attacks targeting Ivanti Connect Secure vulnerabilities.1.5. Phishing Attacks1.5.1. Naver AitM AttackFiles related to an Adversary-in-the-Middle (AitM) attack targeting Naver credentials were found in work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing. The file work/mnt/hgfs/Desktop/New folder/readme.txt contains a configuration guide written in Chinese.caption - content of readme.txtBelow is a machine translation of readme.txt:The script work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing/cipherginx.py acts as a proxy between Naver and the victim. When the victim accesses Naver through this proxy, their headers, cookies, username, and password are saved to the cookies directory under the following filenames:{nid_id}.headers{nid_id}.cookieaccounts.txtcaption - accounts.txt writer in cipherginx.pyThe configuration file work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing/naverconfig.py contains a malicious JavaScript payload. The proxy injects this payload into the Naver login page to capture and exfiltrate user credentials.caption - Naver credential exfiltration code in naverconfig.pyScripts using the exfiltrated credentials to steal the victim's email, contacts, account details, and other data were found at the following paths:caption - File descriptions1.5.2. Kakao Login Phishing AttackThe file vps/var/www/html/kakao-login.php is a phishing page that spoofs the Kakao login portal. The HTML template for this page is located at vps/var/www/html/templates/kakao.html.On a GET request, kakao-login.php checks if a cookie named ft is set. If the cookie exists, it redirects the user to https://mail.daum.net.caption - GET request handlerIf the ft cookie is not set, the script displays the fake Kakao login page. When a user attempts to log in, the form submits the entered credentials via a POST request.Upon receiving a POST request, the script saves the credentials to log/password_log.txt and sets the ft cookie to no.caption - POST request handlerAlthough password_log.txt contains 14 entries, all but one appear to be test data (e.g., (123123, 1212121212), (ttttt222, 2323232323).1.5.3. Email Phishing AttackWeb server code for generating phishing emails and managing victim logs was found under vps/var/www/html.The web server scripts save logs, and all except generator.php use a common format.For parameters, only the xml parameter is treated specially, as detailed in the request.php section. Log files are saved with the format {name}.txt.{%Y%m%d}.generator.phpvps/var/www/html/generator.php is a page for generating phishing emails. Its behavior depends on the value of the cookie HnoplYTfPX and the request method.caption - Execution logicThe phishing email generation form contains the following fields.caption - Phishing email generation form fieldsThe generated phishing email components are displayed as follows.The value under content: is presumed to be the email body. Each generation is logged to log/generator_log.txt.{%Y%m%d} in the format below.caption - Generated phishing email componentsIf the victim's email client is configured to load external resources, the img tag triggers a request to request.php.request.phpvps/var/www/html/request.php logs victim system information to log/request_log.txt.{%Y%m%d}.If the request URI contains .png, the script returns a randomly colored image. Otherwise, it returns a page containing JavaScript to gather information about the victim's system and sends the results as URL parameters.caption - JavaScript files and collected informationThe script then redirects to response.php?i={b64encode(email)}&{results}.response.php The script at vps/var/www/html/response.php inspects the victim's IP address, user-agent, and locale. If these attributes meet specific criteria, the script Base64-decodes the i parameter and logs the result to log/response_log.txt.{%Y%m%d}. The conditions are as follows:The locale is on a whitelist.The IP address and user-agent are not on a blacklist.The locale whitelist includes:usjpjakrkoThe user-agent blacklist includes:botspidercrawltrendsymantecvirusspamsecureThe IP blacklist is detailed below.caption - IP blacklistA summary of the log files, their corresponding scripts, and activity statistics is provided below.caption - Summary of all logs and actual victim logs1.6. Yonsei University Email Exfiltration MalwareThe script at vps/var/www/html/js/chks.js is designed to exfiltrate emails from Yonsei University's webmail service (mail.yonsei.ac.kr).The script first collects user information from the endpoint https://mail.yonsei.ac.kr/common/json/agent.do. It then adds cimoon185@daum.net to the account's list of forwarding addresses.caption - Forward function in chks.jsAfter setting up the forwarding rule, it exfiltrates all emails dated since 2017-10-01 from the ent_{user} and TOTAL mailboxes. The emails are sent to https://service.navers.org/emuy.php?i={user} via POST requests. Notably, the script manually constructs the multipart/form-data request bodies instead of using the standard FormData API.

EnkiWhiteHat

Sep 22, 2025

Threat Intelligence

In-Depth Analysis of the APT Down - The North Korea Files leak

This section analyzes the malware discovered in the actor's VMware dump and the spear-phishing and infrastructure operations identified in the VPS dump. Notably, the rootkit and backdoor found in the tomcat20220420_rootkit and tomcat20250414_rootkit_linux234 directories are linked to a past incident at a South Korean financial institution investigated by our team.1.1. tomcat20220420_rootkit1.1.1. BackdoorThe backdoor source code is located in the work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/work directory. The backdoor's primary functions are to execute malicious commands or to act as a proxy for relaying network traffic. It is always executed by the rootkit and does not run as a standalone process.The backdoor's execution arguments are described in the table below.caption - Command-line optionsWhen the proxy flag is enabled, the command-handling logic is bypassed, and the backdoor waits to receive an AES-256-CBC encrypted "__step2__".caption - Data validation logic in master.cThe AES key and IV are as follows:AES key: 603deb15153a715e2b73aef3857d758b1f552c573e6158d72d9811a33914defeIV: 603deb15153a715e2b73aef3857d758b1f552c573e6158d72d9811a33914defeTo masquerade its traffic, the backdoor can wrap its socket communication in one of the following protocols, as defined in install_common.h:HTTPHTTPSSSLTCPSMTPcaption - Protocol definition in install_common.hAll data, including command codes, is encrypted and decrypted using a multi-byte XOR operation with the key "1101link". The implementation of this logic results in an operation equivalent to a single-byte XOR with the value 1.caption - EncodeDecode function in encrypt.cThe supported commands are listed below.caption - Backdoor command descriptions1.1.2. syslogk rootkitThe file work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/main.c contains the source code for the syslogk rootkit. This rootkit hides the directory containing the backdoor and related malware to evade detection. It also ensures the backdoor only runs when triggered by a specific magic packet from the actor.The rootkit hooks three functions to hide processes, ports, and directories.caption - Function hooksThe hooked functions use strstr to compare target entries against predefined strings (process names, paths, ports) and remove any matches before returning the results.The rootkit then uses nf_register_hook to register callback functions at two Netfilter hook points:NF_INET_LOCAL_IN: Intercepts packets just before they are delivered to a local process.NF_INET_LOCAL_OUT: Intercepts packets just before they are sent from a local process.caption - Netfilter hook registration logic in hkcap.cThis allows the rootkit to monitor all traffic and execute malicious actions upon receiving a magic packet.The NF_INET_LOCAL_IN callback function inspects incoming TCP packets, decrypts the payload, and checks if it matches specific conditions. The decryption keys are listed below.caption - Decryption keysThe conditions and corresponding actions are detailed below.caption - Conditions and actionsAt the NF_INET_LOCAL_OUT hook point, the callback function changes the source port of packets originating from the backdoor to a non-listening port.After registering the Netfilter callbacks, the rootkit removes itself from the system's module list to evade detection by tools like lsmod.caption - hide_module functionThe hidden rootkit can be made visible again by writing the value of MAGIC_DRBIN (defined in install.h) to a specific file controlled by the rootkit.caption - proc_write function logic1.1.3. Backdoor ClientThe file work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/work/tcat.c contains the source code for the backdoor client. This tool was likely run by the actor on their C&C server.The client accepts several command-line options, which are detailed below.caption - Command-line optionsCommands can be delivered to the backdoor in four ways:single cmd: Sends a single command to the backdoor for execution.single daemon cmd: Sends a command to be executed in a new process on the backdoor host.input loop: Enters an interactive loop, accepting commands until exit is entered.kernel cmd: Sends a command to be executed by the kernel module without returning output.Except for the input loop, the client terminates after sending the command. The commands available in the input loop are listed below.caption - Backdoor client command descriptionsAll communication is encrypted with the XOR key "1101link". For each message, the client computes a SHA512 hash of the password combined with the GENERAL_MODULE and GENERAL_PROTOCOL values defined in common.h. This hash is prepended to the message before transmission. Communication with the backdoor can be configured to use one of the following protocols:TCPHTTPOLD HTTP (A variant of HTTP that does not use cookies)1.2. tomcat20250414_rootkit_linux2341.2.1. BackdoorThe directory work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/work contains the source code for the 2025 version of the backdoor. This is an upgraded version of the 2022 backdoor, with new features such as password verification for delayed callbacks, configurable callback timers, and rate-limiting for file transfers. Its command-line options are listed below.caption - Command-line optionsIn addition to the existing password, this version introduces a master password. When a client connects, the backdoor computes a SHA512 hash of the master password and connection settings. The master password, !@nf4@#fndskgadnsewngaldfkl, is defined in common.h. While the hash is stored in a global variable and checked during SSL communications, it is not actively used. The client's provided password is then hashed in the same manner and verified.caption - passcheck_check function in encrypt.cThe password is Miu2jACgXeDsxd. Configuration settings, including the password, can be modified in config.sh and are applied at build time.caption - Default settings in config.shThe communication protocols are the same as the 2022 version:HTTPHTTPSSSLTCPSMTPWhile the original XOR key is still present, five new XOR keys and corresponding encryption/decryption functions have been added.caption - All XOR keys found in encrypt.cThis version adds several new commands and modifies the behavior of commands with "TRANSFER" in their names. The newly added command codes are:CMD_NEW_UPLOADCMD_NEW_DOWNLOADCMD_LISTEN_PROXY_TRANSCMD_TRANSFERCMD_PROXY_TRANSFERCMD_SOCKS_PROXY_TRANSFERCMD_SOCKS_PROXYCMD_NEW_SINGLE_CMDThe command behaviors are detailed in the table below. (new or significantly modified commands are grouped with an asterisk).caption - Backdoor command descriptions1.2.2. syslogk rootkitThe file at work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/main.c is the 2025 version of the rootkit. Like its predecessor, it registers callbacks at Netfilter hook points, but it features significant changes to its function hooking, module hiding, and Netfilter implementation.While the 2022 rootkit used the udis86 library for function hooking, the 2025 version uses the khook library.caption - Left: 2022 rootkit (udis86). Right: 2025 rootkit (khook).This version hooks a total of five functions, up from three in the 2022 version.caption - Function hooksThe number of Netfilter hooks has increased from two to four.NF_INET_LOCAL_IN: Before a packet is delivered to a local process.NF_INET_LOCAL_OUT: Before a packet is sent from a local process.NF_INET_PRE_ROUTING: Immediately after a packet enters the network stack.NF_INET_POST_ROUTING: Just before a packet is placed on the wire, after routing.caption - Netfilter hook registration logic in hkcap.cThe NF_INET_PRE_ROUTING callback performs two main actions. First, it checks for a magic packet to execute the backdoor, similar to the NF_INET_LOCAL_IN hook in the 2022 version. However, the condition is simpler: it only checks for a TCP SYN packet where the ID and sequence number are present in the id_list and seq_list.If the condition is met, the packet's window value is used to determine which masquerade protocol to use when launching the backdoor.caption - Masquerade protocolsThe method for executing the backdoor has also changed significantly. Instead of /bin/sh -c, this version uses call_usermodehelper to launch the backdoor on a random port between 3000 and 8000.caption - kernel_run function in hkcap.cThe second action of the PRE_ROUTING hook is to change the destination port of any packet from the C&C IP to the randomly generated backdoor port. This allows the actor to communicate with the backdoor without knowing the randomly assigned port in advance.caption - Code to change packet destination in hkcap.cThe NF_INET_LOCAL_IN callback function then changes the packet's destination port again, from the random port to the actual port the backdoor is listening on. This two-step redirection appears designed to obscure the backdoor's true listening port.caption - Code to change packet destination to the backdoor port in hkcap.cThe NF_INET_LOCAL_OUT callback changes the source port of outgoing backdoor packets from the listening port to an arbitrary port.The NF_INET_POST_ROUTING callback then changes the source port from the arbitrary port to the actual C&C port.caption - Code to change packet destination to the actor's port in hkcap.cThe rootkit's hiding mechanism has been enhanced to remove the module from sysfs in addition to the standard module list.caption - Module hiding code in hkmod.cThe sysfs-related functions are taken directly from the kv_hide_mod function of the KoviD rootkit.caption - kv_hide_mod function in the KoviD rootkitWhile writing a specific string to the rootkit still unhides it, this version adds the ability to dynamically configure the ports used by the Netfilter hooks by writing other specific strings.caption - Port configuration code in hkcap.cAll strings written to the rootkit, except for the unhide command, are first decrypted with AES-256-CBC. The key and IV are as follows:AES key: d03deb92153a71458973aef3857d75b27e552cc63e6158a8339811873994de47IV: efa3c987532cc0bdac533845ad8df5eaThe actions triggered by writing to the rootkit are listed below.caption - Strings and triggered actions1.2.3. Backdoor ClientThe file work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/work/tcat.c contains the source code for the 2025 backdoor client. Compared to the 2022 version, the primary change is the removal of the kernel command (kc) option. A new LLL option for specifying a log file path has been added. The full list of options is below.caption - Command-line optionsWith the removal of the kernel command feature, commands are delivered in three ways:single cmd: Sends a single command to the backdoor for execution.single daemon cmd: Sends a command to be executed in a new process on the backdoor host.input loop: Enters an interactive loop, accepting commands until exit is entered.While the 2022 client only accepted simple commands, the 2025 client allows options to be specified for each command, enabling more precise control. The number of top-level commands has decreased, but their functionality is more sophisticated. The commands available in the input loop are listed below.caption - Backdoor client command descriptionsA full analysis of the new features was not possible, as key functions for the new commands (e.g., tcat_new_send_file, tcat_new_recv_file) were not defined in the provided source code.Unlike the 2022 client, which sent a SHA512 hash of the password with every communication, the 2025 client sends it only once during the initial connection.All communication is still encrypted with the XOR key "1101link". However, the available communication protocols have changed. The "OLD HTTP" option has been removed, and HTTPS and SMTP have been added. The supported protocols are:TCPHTTPHTTPSSMTP1.3. Cobalt Strike1.3.1. Cobalt Strike LoaderA Rust-based loader designed to decrypt and execute embedded shellcode was found at the following paths:work/mnt/hgfs/Desktop/New folder (2)/DboRrmSS.exework/mnt/hgfs/Desktop/New folder (2)/m01QzOfI.exework/mnt/hgfs/Desktop/New folder (2)/voS9AyMZ.tar.gzwork/home/user/.cache/vmware/drag_and_drop/0pkbW4/3Powwovv.exework/home/user/.cache/vmware/drag_and_drop/gWMDML/GnAN3FhY.exework/home/user/.cache/vmware/drag_and_drop/QqiN9h/DboRrmSS.exework/home/user/.cache/vmware/drag_and_drop/rM0FG0/m01QzOfI.exeThe loader dynamically resolves Windows APIs using djb2 hashing. It then decrypts the shellcode with AES-256-CBC and executes it in memory.caption - API hashing functionThe AES keys and IVs for each loader instance are listed below.caption - Cobalt Strike Loader AES keys and IVs1.3.2. ShellcodeThe shellcode executed by the Cobalt Strike Loader decrypts and runs the final Cobalt Strike Beacon payload in memory. This shellcode was also found as standalone files at the following paths:work/home/user/.cache/vmware/drag_and_drop/5wdgDr/payload.binwork/home/user/.cache/vmware/drag_and_drop/6bX9mm/Black.x64.exework/home/user/.cache/vmware/drag_and_drop/NDBu65/payload.binwork/home/user/.cache/vmware/drag_and_drop/yf91yD/payload.binwork/home/user/.cache/vmware/drag_and_drop/zlLWeR/payload.binThe file work/home/user/.cache/vmware/drag_and_drop/6bX9mm/Black.x64.exe is a compiled executable but is functionally identical to the other shellcode files.caption - DIE result for Black.x64.exeLike the loader, the shellcode dynamically resolves Windows APIs using djb2 hashing. The embedded Cobalt Strike Beacon is decrypted using RC4 and executed in memory.caption - RC4 ksa functionThe RC4 keys used by each file are listed below.caption - Shellcode RC4 keysNotably, the Cobalt Strike Beacons deployed via this shellcode patch ETW and AMSI functions to evade detection. The encrypted beacon configuration was truncated, preventing a full analysis of its contents.1.3.3. Cobalt Strike BeaconThe source code for a Cobalt Strike Beacon was found under work/mnt/hgfs/Desktop/111/beacon. Upon execution, it decrypts its configuration using a single-byte XOR key (0x2e). A portion of the decrypted configuration, as parsed by CobaltStrikeParser, is shown below.caption - CobaltStrikeParser outputAlthough the configuration contains a C&C server address and endpoint, the beacon ignores these and uses hardcoded values instead.caption - send_Metadata function in comm.cppAfter parsing the configuration, the beacon generates metadata to send to the C&C server. Key values are listed below.caption - Metadata fieldsAfter sending the initial metadata, it begins polling for commands from the C&C server via HTTP GET requests every 5 seconds and sends the results back via HTTP POST. The supported command ids are listed below.caption - Cobalt Strike Beacon commandsThe majority of commands are either unimplemented or disabled, suggesting this is an incomplete version of the beacon.1.3.4. C# LoaderThe directory work/home/user/Desktop/0128.zip contained a C# loader (ok.dll), its source code (ok.cs), and a runner script (ok.sct) designed to inject a Cobalt Strike Beacon into another process.The frequent use of the word "test" in function names and arguments suggests this tool was experimental.ok.htaThe ok.hta file is an HTML Application that downloads a script from hxxp://192.168[.]123.200/ok.sct and calls its Fuk method.caption - ok.hta contentThe downloaded script is presumed to be the ok.sct file found in the same archive.ok.sctThis script deserializes an embedded byte array into a C# object and invokes its Work method. This object is presumed to be the ok.dll loader.caption - deserialization code in C# LoaderThe C# loader injects a Cobalt Strike Beacon into a conhost.exe process. The beacon payload is stored as a zlib-compressed and Base64-encoded string.caption - Cobalt Strike Beacon decode functionBelow is a portion of the beacon's configuration, extracted using CobaltStrikeParser.caption - CobaltStrikeParser output1.4. Ivanti Connect Secure1.4.1. BRUSHFIREThe zip file at work/mnt/hgfs/Desktop/ivanti-new-exp-20241220.zip contains Python scripts that leverage an Ivanti Connect Secure RCE exploit to deploy a backdoor.The script crafts a clientCapabilities value to trigger CVE-2025-0282 and achieve RCE.caption - exploit in exp*.pyCVE-2025-0282 has been exploited by UNC5221, a suspected China-nexus threat actor.Multiple versions of these scripts were found, all functionally equivalent with minor variations in function offsets and service endpoints. The command-line arguments accepted by the scripts are listed below.caption - Command-line optionsThe script establishes a random 3-byte magic value and a random 4-byte key for each host. It uses the RCE exploit to execute plugins/install, which overwrites the legitimate ssl_read function with the backdoor from plugins/ssl_read. During communication, when the backdoor receives a payload starting with themagic value, it XOR-decrypts the rest of the payload with the key and executes it as shellcode.caption - shellcode execution code in ssl_readThe script generates and uploads different shellcode payloads to the target server based on the provided options. It uses the replace method to patch the shellcode, adapting hardcoded placeholder values for the target environment. The table below details the options that deploy shellcode from the plugins directory and the purpose of each payload.caption - Options and corresponding shellcodeThe plugins/ssl_read backdoor and its associated file paths match the description of the BRUSHFIRE malware used by UNC5221, as detailed in this report.1.4.2. SPAWN Family ClientThe zip file at work/mnt/hgfs/Desktop/New folder/203.234.192.200_client.zip was found to contain a tunneling script, an SSH client, and an SSH private key. The included readme.txt file contains instructions for using client.py and controller.py to connect to 203.234[.]192.200, an IP address belonging to the South Korean news organization Hankyoreh.caption - content of readme.txtclient.py uses a SOCKS5 proxy to tunnel network traffic and accepts the following options:caption - Option descriptionsclient.py initializes values for client_hello and client_key_exchange packets, which are used as follows:client_hello: Before transmission, random data is written to client_hello[15:43], the CRC32 checksum of this data is written to client_hello[11:15], and a random 32-byte sessionid is included in the message.client_key_exchange: Before transmission, a random 256-byte value is written to the premaster field, and a random 32-byte value is written to the enc_handshake_msg field.The initial hardcoded value of client_hello is identical to the magic packet in the SPAWNMOLE sample detailed in this UNC5221 report. The runtime modification—writing random data and its CRC32 checksum—is consistent with the behavior of the SPAWNCHIMERA sample described in JPCert's report.Like SPAWNMOLE, SPAWNCHIMERA was deployed by UNC5221 using CVE-2025-0282 as an initial access vector.controller.py is an SSH client that uses the SOCKS5 proxy established by client.py for communication.caption - SSH client code in controller.pySPAWNMOLE was discovered alongside SPAWNSNAIL, which is capable of running an SSH server. SPAWNCHIMERA also includes SSH server functionality. Therefore, controller.py is likely a client for the SSH server component of either SPAWNSNAIL or SPAWNCHIMERA.1.4.3. ROOTROT ClientThe script at work/mnt/hgfs/Desktop/ivanti_control/main.py functions as a client for a webshell. Depending on the options provided, it generates a Perl script fragment, Base64-encodes it, sets a cookie to the encoded value, and sends an HTTP GET request. The options and their corresponding scripts are listed below.download {file_path}{command}Both Perl scripts Base64-encode their output and wrap it in HTML comments. The main.py client then extracts the content of the last comment in the HTTP response, Base64-decodes it, and prints the result.caption - The function that sends the request and decodes the responseROOTROT, as described in this UNC5221 report, is a Perl-based web shell that Base64-decodes a cookie value before executing it with eval. It then sends the Base64-encoded results back within HTML comments. This behavior confirms that main.py is the client for the ROOTROT web shell.Like the other UNC5221 malware mentioned, ROOTROT has been found in attacks targeting Ivanti Connect Secure vulnerabilities.1.5. Phishing Attacks1.5.1. Naver AitM AttackFiles related to an Adversary-in-the-Middle (AitM) attack targeting Naver credentials were found in work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing. The file work/mnt/hgfs/Desktop/New folder/readme.txt contains a configuration guide written in Chinese.caption - content of readme.txtBelow is a machine translation of readme.txt:The script work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing/cipherginx.py acts as a proxy between Naver and the victim. When the victim accesses Naver through this proxy, their headers, cookies, username, and password are saved to the cookies directory under the following filenames:{nid_id}.headers{nid_id}.cookieaccounts.txtcaption - accounts.txt writer in cipherginx.pyThe configuration file work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing/naverconfig.py contains a malicious JavaScript payload. The proxy injects this payload into the Naver login page to capture and exfiltrate user credentials.caption - Naver credential exfiltration code in naverconfig.pyScripts using the exfiltrated credentials to steal the victim's email, contacts, account details, and other data were found at the following paths:caption - File descriptions1.5.2. Kakao Login Phishing AttackThe file vps/var/www/html/kakao-login.php is a phishing page that spoofs the Kakao login portal. The HTML template for this page is located at vps/var/www/html/templates/kakao.html.On a GET request, kakao-login.php checks if a cookie named ft is set. If the cookie exists, it redirects the user to https://mail.daum.net.caption - GET request handlerIf the ft cookie is not set, the script displays the fake Kakao login page. When a user attempts to log in, the form submits the entered credentials via a POST request.Upon receiving a POST request, the script saves the credentials to log/password_log.txt and sets the ft cookie to no.caption - POST request handlerAlthough password_log.txt contains 14 entries, all but one appear to be test data (e.g., (123123, 1212121212), (ttttt222, 2323232323).1.5.3. Email Phishing AttackWeb server code for generating phishing emails and managing victim logs was found under vps/var/www/html.The web server scripts save logs, and all except generator.php use a common format.For parameters, only the xml parameter is treated specially, as detailed in the request.php section. Log files are saved with the format {name}.txt.{%Y%m%d}.generator.phpvps/var/www/html/generator.php is a page for generating phishing emails. Its behavior depends on the value of the cookie HnoplYTfPX and the request method.caption - Execution logicThe phishing email generation form contains the following fields.caption - Phishing email generation form fieldsThe generated phishing email components are displayed as follows.The value under content: is presumed to be the email body. Each generation is logged to log/generator_log.txt.{%Y%m%d} in the format below.caption - Generated phishing email componentsIf the victim's email client is configured to load external resources, the img tag triggers a request to request.php.request.phpvps/var/www/html/request.php logs victim system information to log/request_log.txt.{%Y%m%d}.If the request URI contains .png, the script returns a randomly colored image. Otherwise, it returns a page containing JavaScript to gather information about the victim's system and sends the results as URL parameters.caption - JavaScript files and collected informationThe script then redirects to response.php?i={b64encode(email)}&{results}.response.php The script at vps/var/www/html/response.php inspects the victim's IP address, user-agent, and locale. If these attributes meet specific criteria, the script Base64-decodes the i parameter and logs the result to log/response_log.txt.{%Y%m%d}. The conditions are as follows:The locale is on a whitelist.The IP address and user-agent are not on a blacklist.The locale whitelist includes:usjpjakrkoThe user-agent blacklist includes:botspidercrawltrendsymantecvirusspamsecureThe IP blacklist is detailed below.caption - IP blacklistA summary of the log files, their corresponding scripts, and activity statistics is provided below.caption - Summary of all logs and actual victim logs1.6. Yonsei University Email Exfiltration MalwareThe script at vps/var/www/html/js/chks.js is designed to exfiltrate emails from Yonsei University's webmail service (mail.yonsei.ac.kr).The script first collects user information from the endpoint https://mail.yonsei.ac.kr/common/json/agent.do. It then adds cimoon185@daum.net to the account's list of forwarding addresses.caption - Forward function in chks.jsAfter setting up the forwarding rule, it exfiltrates all emails dated since 2017-10-01 from the ent_{user} and TOTAL mailboxes. The emails are sent to https://service.navers.org/emuy.php?i={user} via POST requests. Notably, the script manually constructs the multipart/form-data request bodies instead of using the standard FormData API.

EnkiWhiteHat

Sep 22, 2025

Threat Intelligence

In-Depth Analysis of the APT Down - The North Korea Files leak

This section analyzes the malware discovered in the actor's VMware dump and the spear-phishing and infrastructure operations identified in the VPS dump. Notably, the rootkit and backdoor found in the tomcat20220420_rootkit and tomcat20250414_rootkit_linux234 directories are linked to a past incident at a South Korean financial institution investigated by our team.1.1. tomcat20220420_rootkit1.1.1. BackdoorThe backdoor source code is located in the work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/work directory. The backdoor's primary functions are to execute malicious commands or to act as a proxy for relaying network traffic. It is always executed by the rootkit and does not run as a standalone process.The backdoor's execution arguments are described in the table below.caption - Command-line optionsWhen the proxy flag is enabled, the command-handling logic is bypassed, and the backdoor waits to receive an AES-256-CBC encrypted "__step2__".caption - Data validation logic in master.cThe AES key and IV are as follows:AES key: 603deb15153a715e2b73aef3857d758b1f552c573e6158d72d9811a33914defeIV: 603deb15153a715e2b73aef3857d758b1f552c573e6158d72d9811a33914defeTo masquerade its traffic, the backdoor can wrap its socket communication in one of the following protocols, as defined in install_common.h:HTTPHTTPSSSLTCPSMTPcaption - Protocol definition in install_common.hAll data, including command codes, is encrypted and decrypted using a multi-byte XOR operation with the key "1101link". The implementation of this logic results in an operation equivalent to a single-byte XOR with the value 1.caption - EncodeDecode function in encrypt.cThe supported commands are listed below.caption - Backdoor command descriptions1.1.2. syslogk rootkitThe file work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/main.c contains the source code for the syslogk rootkit. This rootkit hides the directory containing the backdoor and related malware to evade detection. It also ensures the backdoor only runs when triggered by a specific magic packet from the actor.The rootkit hooks three functions to hide processes, ports, and directories.caption - Function hooksThe hooked functions use strstr to compare target entries against predefined strings (process names, paths, ports) and remove any matches before returning the results.The rootkit then uses nf_register_hook to register callback functions at two Netfilter hook points:NF_INET_LOCAL_IN: Intercepts packets just before they are delivered to a local process.NF_INET_LOCAL_OUT: Intercepts packets just before they are sent from a local process.caption - Netfilter hook registration logic in hkcap.cThis allows the rootkit to monitor all traffic and execute malicious actions upon receiving a magic packet.The NF_INET_LOCAL_IN callback function inspects incoming TCP packets, decrypts the payload, and checks if it matches specific conditions. The decryption keys are listed below.caption - Decryption keysThe conditions and corresponding actions are detailed below.caption - Conditions and actionsAt the NF_INET_LOCAL_OUT hook point, the callback function changes the source port of packets originating from the backdoor to a non-listening port.After registering the Netfilter callbacks, the rootkit removes itself from the system's module list to evade detection by tools like lsmod.caption - hide_module functionThe hidden rootkit can be made visible again by writing the value of MAGIC_DRBIN (defined in install.h) to a specific file controlled by the rootkit.caption - proc_write function logic1.1.3. Backdoor ClientThe file work/home/user/Desktop/tomcat20220420_rootkit/tomcat20220420_rootkit/work/tcat.c contains the source code for the backdoor client. This tool was likely run by the actor on their C&C server.The client accepts several command-line options, which are detailed below.caption - Command-line optionsCommands can be delivered to the backdoor in four ways:single cmd: Sends a single command to the backdoor for execution.single daemon cmd: Sends a command to be executed in a new process on the backdoor host.input loop: Enters an interactive loop, accepting commands until exit is entered.kernel cmd: Sends a command to be executed by the kernel module without returning output.Except for the input loop, the client terminates after sending the command. The commands available in the input loop are listed below.caption - Backdoor client command descriptionsAll communication is encrypted with the XOR key "1101link". For each message, the client computes a SHA512 hash of the password combined with the GENERAL_MODULE and GENERAL_PROTOCOL values defined in common.h. This hash is prepended to the message before transmission. Communication with the backdoor can be configured to use one of the following protocols:TCPHTTPOLD HTTP (A variant of HTTP that does not use cookies)1.2. tomcat20250414_rootkit_linux2341.2.1. BackdoorThe directory work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/work contains the source code for the 2025 version of the backdoor. This is an upgraded version of the 2022 backdoor, with new features such as password verification for delayed callbacks, configurable callback timers, and rate-limiting for file transfers. Its command-line options are listed below.caption - Command-line optionsIn addition to the existing password, this version introduces a master password. When a client connects, the backdoor computes a SHA512 hash of the master password and connection settings. The master password, !@nf4@#fndskgadnsewngaldfkl, is defined in common.h. While the hash is stored in a global variable and checked during SSL communications, it is not actively used. The client's provided password is then hashed in the same manner and verified.caption - passcheck_check function in encrypt.cThe password is Miu2jACgXeDsxd. Configuration settings, including the password, can be modified in config.sh and are applied at build time.caption - Default settings in config.shThe communication protocols are the same as the 2022 version:HTTPHTTPSSSLTCPSMTPWhile the original XOR key is still present, five new XOR keys and corresponding encryption/decryption functions have been added.caption - All XOR keys found in encrypt.cThis version adds several new commands and modifies the behavior of commands with "TRANSFER" in their names. The newly added command codes are:CMD_NEW_UPLOADCMD_NEW_DOWNLOADCMD_LISTEN_PROXY_TRANSCMD_TRANSFERCMD_PROXY_TRANSFERCMD_SOCKS_PROXY_TRANSFERCMD_SOCKS_PROXYCMD_NEW_SINGLE_CMDThe command behaviors are detailed in the table below. (new or significantly modified commands are grouped with an asterisk).caption - Backdoor command descriptions1.2.2. syslogk rootkitThe file at work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/main.c is the 2025 version of the rootkit. Like its predecessor, it registers callbacks at Netfilter hook points, but it features significant changes to its function hooking, module hiding, and Netfilter implementation.While the 2022 rootkit used the udis86 library for function hooking, the 2025 version uses the khook library.caption - Left: 2022 rootkit (udis86). Right: 2025 rootkit (khook).This version hooks a total of five functions, up from three in the 2022 version.caption - Function hooksThe number of Netfilter hooks has increased from two to four.NF_INET_LOCAL_IN: Before a packet is delivered to a local process.NF_INET_LOCAL_OUT: Before a packet is sent from a local process.NF_INET_PRE_ROUTING: Immediately after a packet enters the network stack.NF_INET_POST_ROUTING: Just before a packet is placed on the wire, after routing.caption - Netfilter hook registration logic in hkcap.cThe NF_INET_PRE_ROUTING callback performs two main actions. First, it checks for a magic packet to execute the backdoor, similar to the NF_INET_LOCAL_IN hook in the 2022 version. However, the condition is simpler: it only checks for a TCP SYN packet where the ID and sequence number are present in the id_list and seq_list.If the condition is met, the packet's window value is used to determine which masquerade protocol to use when launching the backdoor.caption - Masquerade protocolsThe method for executing the backdoor has also changed significantly. Instead of /bin/sh -c, this version uses call_usermodehelper to launch the backdoor on a random port between 3000 and 8000.caption - kernel_run function in hkcap.cThe second action of the PRE_ROUTING hook is to change the destination port of any packet from the C&C IP to the randomly generated backdoor port. This allows the actor to communicate with the backdoor without knowing the randomly assigned port in advance.caption - Code to change packet destination in hkcap.cThe NF_INET_LOCAL_IN callback function then changes the packet's destination port again, from the random port to the actual port the backdoor is listening on. This two-step redirection appears designed to obscure the backdoor's true listening port.caption - Code to change packet destination to the backdoor port in hkcap.cThe NF_INET_LOCAL_OUT callback changes the source port of outgoing backdoor packets from the listening port to an arbitrary port.The NF_INET_POST_ROUTING callback then changes the source port from the arbitrary port to the actual C&C port.caption - Code to change packet destination to the actor's port in hkcap.cThe rootkit's hiding mechanism has been enhanced to remove the module from sysfs in addition to the standard module list.caption - Module hiding code in hkmod.cThe sysfs-related functions are taken directly from the kv_hide_mod function of the KoviD rootkit.caption - kv_hide_mod function in the KoviD rootkitWhile writing a specific string to the rootkit still unhides it, this version adds the ability to dynamically configure the ports used by the Netfilter hooks by writing other specific strings.caption - Port configuration code in hkcap.cAll strings written to the rootkit, except for the unhide command, are first decrypted with AES-256-CBC. The key and IV are as follows:AES key: d03deb92153a71458973aef3857d75b27e552cc63e6158a8339811873994de47IV: efa3c987532cc0bdac533845ad8df5eaThe actions triggered by writing to the rootkit are listed below.caption - Strings and triggered actions1.2.3. Backdoor ClientThe file work/mnt/hgfs/Desktop/tomcat20250414_rootkit_linux234/tomcat20250414_rootkit_linux2345/work/tcat.c contains the source code for the 2025 backdoor client. Compared to the 2022 version, the primary change is the removal of the kernel command (kc) option. A new LLL option for specifying a log file path has been added. The full list of options is below.caption - Command-line optionsWith the removal of the kernel command feature, commands are delivered in three ways:single cmd: Sends a single command to the backdoor for execution.single daemon cmd: Sends a command to be executed in a new process on the backdoor host.input loop: Enters an interactive loop, accepting commands until exit is entered.While the 2022 client only accepted simple commands, the 2025 client allows options to be specified for each command, enabling more precise control. The number of top-level commands has decreased, but their functionality is more sophisticated. The commands available in the input loop are listed below.caption - Backdoor client command descriptionsA full analysis of the new features was not possible, as key functions for the new commands (e.g., tcat_new_send_file, tcat_new_recv_file) were not defined in the provided source code.Unlike the 2022 client, which sent a SHA512 hash of the password with every communication, the 2025 client sends it only once during the initial connection.All communication is still encrypted with the XOR key "1101link". However, the available communication protocols have changed. The "OLD HTTP" option has been removed, and HTTPS and SMTP have been added. The supported protocols are:TCPHTTPHTTPSSMTP1.3. Cobalt Strike1.3.1. Cobalt Strike LoaderA Rust-based loader designed to decrypt and execute embedded shellcode was found at the following paths:work/mnt/hgfs/Desktop/New folder (2)/DboRrmSS.exework/mnt/hgfs/Desktop/New folder (2)/m01QzOfI.exework/mnt/hgfs/Desktop/New folder (2)/voS9AyMZ.tar.gzwork/home/user/.cache/vmware/drag_and_drop/0pkbW4/3Powwovv.exework/home/user/.cache/vmware/drag_and_drop/gWMDML/GnAN3FhY.exework/home/user/.cache/vmware/drag_and_drop/QqiN9h/DboRrmSS.exework/home/user/.cache/vmware/drag_and_drop/rM0FG0/m01QzOfI.exeThe loader dynamically resolves Windows APIs using djb2 hashing. It then decrypts the shellcode with AES-256-CBC and executes it in memory.caption - API hashing functionThe AES keys and IVs for each loader instance are listed below.caption - Cobalt Strike Loader AES keys and IVs1.3.2. ShellcodeThe shellcode executed by the Cobalt Strike Loader decrypts and runs the final Cobalt Strike Beacon payload in memory. This shellcode was also found as standalone files at the following paths:work/home/user/.cache/vmware/drag_and_drop/5wdgDr/payload.binwork/home/user/.cache/vmware/drag_and_drop/6bX9mm/Black.x64.exework/home/user/.cache/vmware/drag_and_drop/NDBu65/payload.binwork/home/user/.cache/vmware/drag_and_drop/yf91yD/payload.binwork/home/user/.cache/vmware/drag_and_drop/zlLWeR/payload.binThe file work/home/user/.cache/vmware/drag_and_drop/6bX9mm/Black.x64.exe is a compiled executable but is functionally identical to the other shellcode files.caption - DIE result for Black.x64.exeLike the loader, the shellcode dynamically resolves Windows APIs using djb2 hashing. The embedded Cobalt Strike Beacon is decrypted using RC4 and executed in memory.caption - RC4 ksa functionThe RC4 keys used by each file are listed below.caption - Shellcode RC4 keysNotably, the Cobalt Strike Beacons deployed via this shellcode patch ETW and AMSI functions to evade detection. The encrypted beacon configuration was truncated, preventing a full analysis of its contents.1.3.3. Cobalt Strike BeaconThe source code for a Cobalt Strike Beacon was found under work/mnt/hgfs/Desktop/111/beacon. Upon execution, it decrypts its configuration using a single-byte XOR key (0x2e). A portion of the decrypted configuration, as parsed by CobaltStrikeParser, is shown below.caption - CobaltStrikeParser outputAlthough the configuration contains a C&C server address and endpoint, the beacon ignores these and uses hardcoded values instead.caption - send_Metadata function in comm.cppAfter parsing the configuration, the beacon generates metadata to send to the C&C server. Key values are listed below.caption - Metadata fieldsAfter sending the initial metadata, it begins polling for commands from the C&C server via HTTP GET requests every 5 seconds and sends the results back via HTTP POST. The supported command ids are listed below.caption - Cobalt Strike Beacon commandsThe majority of commands are either unimplemented or disabled, suggesting this is an incomplete version of the beacon.1.3.4. C# LoaderThe directory work/home/user/Desktop/0128.zip contained a C# loader (ok.dll), its source code (ok.cs), and a runner script (ok.sct) designed to inject a Cobalt Strike Beacon into another process.The frequent use of the word "test" in function names and arguments suggests this tool was experimental.ok.htaThe ok.hta file is an HTML Application that downloads a script from hxxp://192.168[.]123.200/ok.sct and calls its Fuk method.caption - ok.hta contentThe downloaded script is presumed to be the ok.sct file found in the same archive.ok.sctThis script deserializes an embedded byte array into a C# object and invokes its Work method. This object is presumed to be the ok.dll loader.caption - deserialization code in C# LoaderThe C# loader injects a Cobalt Strike Beacon into a conhost.exe process. The beacon payload is stored as a zlib-compressed and Base64-encoded string.caption - Cobalt Strike Beacon decode functionBelow is a portion of the beacon's configuration, extracted using CobaltStrikeParser.caption - CobaltStrikeParser output1.4. Ivanti Connect Secure1.4.1. BRUSHFIREThe zip file at work/mnt/hgfs/Desktop/ivanti-new-exp-20241220.zip contains Python scripts that leverage an Ivanti Connect Secure RCE exploit to deploy a backdoor.The script crafts a clientCapabilities value to trigger CVE-2025-0282 and achieve RCE.caption - exploit in exp*.pyCVE-2025-0282 has been exploited by UNC5221, a suspected China-nexus threat actor.Multiple versions of these scripts were found, all functionally equivalent with minor variations in function offsets and service endpoints. The command-line arguments accepted by the scripts are listed below.caption - Command-line optionsThe script establishes a random 3-byte magic value and a random 4-byte key for each host. It uses the RCE exploit to execute plugins/install, which overwrites the legitimate ssl_read function with the backdoor from plugins/ssl_read. During communication, when the backdoor receives a payload starting with themagic value, it XOR-decrypts the rest of the payload with the key and executes it as shellcode.caption - shellcode execution code in ssl_readThe script generates and uploads different shellcode payloads to the target server based on the provided options. It uses the replace method to patch the shellcode, adapting hardcoded placeholder values for the target environment. The table below details the options that deploy shellcode from the plugins directory and the purpose of each payload.caption - Options and corresponding shellcodeThe plugins/ssl_read backdoor and its associated file paths match the description of the BRUSHFIRE malware used by UNC5221, as detailed in this report.1.4.2. SPAWN Family ClientThe zip file at work/mnt/hgfs/Desktop/New folder/203.234.192.200_client.zip was found to contain a tunneling script, an SSH client, and an SSH private key. The included readme.txt file contains instructions for using client.py and controller.py to connect to 203.234[.]192.200, an IP address belonging to the South Korean news organization Hankyoreh.caption - content of readme.txtclient.py uses a SOCKS5 proxy to tunnel network traffic and accepts the following options:caption - Option descriptionsclient.py initializes values for client_hello and client_key_exchange packets, which are used as follows:client_hello: Before transmission, random data is written to client_hello[15:43], the CRC32 checksum of this data is written to client_hello[11:15], and a random 32-byte sessionid is included in the message.client_key_exchange: Before transmission, a random 256-byte value is written to the premaster field, and a random 32-byte value is written to the enc_handshake_msg field.The initial hardcoded value of client_hello is identical to the magic packet in the SPAWNMOLE sample detailed in this UNC5221 report. The runtime modification—writing random data and its CRC32 checksum—is consistent with the behavior of the SPAWNCHIMERA sample described in JPCert's report.Like SPAWNMOLE, SPAWNCHIMERA was deployed by UNC5221 using CVE-2025-0282 as an initial access vector.controller.py is an SSH client that uses the SOCKS5 proxy established by client.py for communication.caption - SSH client code in controller.pySPAWNMOLE was discovered alongside SPAWNSNAIL, which is capable of running an SSH server. SPAWNCHIMERA also includes SSH server functionality. Therefore, controller.py is likely a client for the SSH server component of either SPAWNSNAIL or SPAWNCHIMERA.1.4.3. ROOTROT ClientThe script at work/mnt/hgfs/Desktop/ivanti_control/main.py functions as a client for a webshell. Depending on the options provided, it generates a Perl script fragment, Base64-encodes it, sets a cookie to the encoded value, and sends an HTTP GET request. The options and their corresponding scripts are listed below.download {file_path}{command}Both Perl scripts Base64-encode their output and wrap it in HTML comments. The main.py client then extracts the content of the last comment in the HTTP response, Base64-decodes it, and prints the result.caption - The function that sends the request and decodes the responseROOTROT, as described in this UNC5221 report, is a Perl-based web shell that Base64-decodes a cookie value before executing it with eval. It then sends the Base64-encoded results back within HTML comments. This behavior confirms that main.py is the client for the ROOTROT web shell.Like the other UNC5221 malware mentioned, ROOTROT has been found in attacks targeting Ivanti Connect Secure vulnerabilities.1.5. Phishing Attacks1.5.1. Naver AitM AttackFiles related to an Adversary-in-the-Middle (AitM) attack targeting Naver credentials were found in work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing. The file work/mnt/hgfs/Desktop/New folder/readme.txt contains a configuration guide written in Chinese.caption - content of readme.txtBelow is a machine translation of readme.txt:The script work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing/cipherginx.py acts as a proxy between Naver and the victim. When the victim accesses Naver through this proxy, their headers, cookies, username, and password are saved to the cookies directory under the following filenames:{nid_id}.headers{nid_id}.cookieaccounts.txtcaption - accounts.txt writer in cipherginx.pyThe configuration file work/mnt/hgfs/Desktop/New folder/vps2/Cipherishing/naverconfig.py contains a malicious JavaScript payload. The proxy injects this payload into the Naver login page to capture and exfiltrate user credentials.caption - Naver credential exfiltration code in naverconfig.pyScripts using the exfiltrated credentials to steal the victim's email, contacts, account details, and other data were found at the following paths:caption - File descriptions1.5.2. Kakao Login Phishing AttackThe file vps/var/www/html/kakao-login.php is a phishing page that spoofs the Kakao login portal. The HTML template for this page is located at vps/var/www/html/templates/kakao.html.On a GET request, kakao-login.php checks if a cookie named ft is set. If the cookie exists, it redirects the user to https://mail.daum.net.caption - GET request handlerIf the ft cookie is not set, the script displays the fake Kakao login page. When a user attempts to log in, the form submits the entered credentials via a POST request.Upon receiving a POST request, the script saves the credentials to log/password_log.txt and sets the ft cookie to no.caption - POST request handlerAlthough password_log.txt contains 14 entries, all but one appear to be test data (e.g., (123123, 1212121212), (ttttt222, 2323232323).1.5.3. Email Phishing AttackWeb server code for generating phishing emails and managing victim logs was found under vps/var/www/html.The web server scripts save logs, and all except generator.php use a common format.For parameters, only the xml parameter is treated specially, as detailed in the request.php section. Log files are saved with the format {name}.txt.{%Y%m%d}.generator.phpvps/var/www/html/generator.php is a page for generating phishing emails. Its behavior depends on the value of the cookie HnoplYTfPX and the request method.caption - Execution logicThe phishing email generation form contains the following fields.caption - Phishing email generation form fieldsThe generated phishing email components are displayed as follows.The value under content: is presumed to be the email body. Each generation is logged to log/generator_log.txt.{%Y%m%d} in the format below.caption - Generated phishing email componentsIf the victim's email client is configured to load external resources, the img tag triggers a request to request.php.request.phpvps/var/www/html/request.php logs victim system information to log/request_log.txt.{%Y%m%d}.If the request URI contains .png, the script returns a randomly colored image. Otherwise, it returns a page containing JavaScript to gather information about the victim's system and sends the results as URL parameters.caption - JavaScript files and collected informationThe script then redirects to response.php?i={b64encode(email)}&{results}.response.php The script at vps/var/www/html/response.php inspects the victim's IP address, user-agent, and locale. If these attributes meet specific criteria, the script Base64-decodes the i parameter and logs the result to log/response_log.txt.{%Y%m%d}. The conditions are as follows:The locale is on a whitelist.The IP address and user-agent are not on a blacklist.The locale whitelist includes:usjpjakrkoThe user-agent blacklist includes:botspidercrawltrendsymantecvirusspamsecureThe IP blacklist is detailed below.caption - IP blacklistA summary of the log files, their corresponding scripts, and activity statistics is provided below.caption - Summary of all logs and actual victim logs1.6. Yonsei University Email Exfiltration MalwareThe script at vps/var/www/html/js/chks.js is designed to exfiltrate emails from Yonsei University's webmail service (mail.yonsei.ac.kr).The script first collects user information from the endpoint https://mail.yonsei.ac.kr/common/json/agent.do. It then adds cimoon185@daum.net to the account's list of forwarding addresses.caption - Forward function in chks.jsAfter setting up the forwarding rule, it exfiltrates all emails dated since 2017-10-01 from the ent_{user} and TOTAL mailboxes. The emails are sent to https://service.navers.org/emuy.php?i={user} via POST requests. Notably, the script manually constructs the multipart/form-data request bodies instead of using the standard FormData API.

EnkiWhiteHat

Sep 22, 2025

Analysis of Formbook Payload Loaded by PureCrypter Distributed from South Korean IP

Threat Intelligence

Analysis of Formbook Payload Loaded by PureCrypter Distributed from South Korean IP

In May 2025, a number of RAR and EXE files associated with the domestic IP 158.247.250[.]251 were discovered. This IP was identified in past DNS records as being related to a phishing infrastructure associated with Naver, and there are query records related to Naver login URLs in VirusTotal.caption - URL query records of 158.247.250[.]251Among them, the relevant email files and the attached RAR and EXE files were reported from South Korea, and the email account that received the emails also belongs to a domain of an energy company in South Korea. Malware associated with this IP has been distributed under different file names in various countries besides South Korea. Analysis revealed that the distributed files were packed Formbook malware identified as being packed with PureCrypter.

EnkiWhiteHat

Aug 29, 2025

Analysis of Formbook Payload Loaded by PureCrypter Distributed from South Korean IP

Threat Intelligence

Analysis of Formbook Payload Loaded by PureCrypter Distributed from South Korean IP

In May 2025, a number of RAR and EXE files associated with the domestic IP 158.247.250[.]251 were discovered. This IP was identified in past DNS records as being related to a phishing infrastructure associated with Naver, and there are query records related to Naver login URLs in VirusTotal.caption - URL query records of 158.247.250[.]251Among them, the relevant email files and the attached RAR and EXE files were reported from South Korea, and the email account that received the emails also belongs to a domain of an energy company in South Korea. Malware associated with this IP has been distributed under different file names in various countries besides South Korea. Analysis revealed that the distributed files were packed Formbook malware identified as being packed with PureCrypter.

EnkiWhiteHat

Aug 29, 2025

Analysis of Formbook Payload Loaded by PureCrypter Distributed from South Korean IP

Threat Intelligence

Analysis of Formbook Payload Loaded by PureCrypter Distributed from South Korean IP

In May 2025, a number of RAR and EXE files associated with the domestic IP 158.247.250[.]251 were discovered. This IP was identified in past DNS records as being related to a phishing infrastructure associated with Naver, and there are query records related to Naver login URLs in VirusTotal.caption - URL query records of 158.247.250[.]251Among them, the relevant email files and the attached RAR and EXE files were reported from South Korea, and the email account that received the emails also belongs to a domain of an energy company in South Korea. Malware associated with this IP has been distributed under different file names in various countries besides South Korea. Analysis revealed that the distributed files were packed Formbook malware identified as being packed with PureCrypter.

EnkiWhiteHat

Aug 29, 2025

Vulnerability research

From Blink to Nt: Codegate 2025 FullChain Write-up

Challenge OverviewThe goal of the challenge is to find vulnerabilities in the renderer process and develop an exploit code by analyzing the provided rce-sbx-138-0-7204-97.patch file.The patch file creates a new Blink module called minishell in the renderer. It provides various shell functions and file writing and saving, and the file data is managed through Codegate File System (CFS), which is a browser API.The available commands are:They are similar to the basic shell commands. Commands such as exec are not implemented, but there are several file operations.When a file is opened, it is managed through file_descriptor_ in the form of a FileBuffer class until Save.A user can invoke the minishell as follows:Callable methods can be bound in the *idl file.In short, one user can have multiple shells and execute each command in one shell.VulnerabilityWe can see the main functionality in mini_shell.cc.However, the vulnerability is pretty simple compared to the file size. The following shows the FileBuffer structure.In here, we can see the fixed-size buffer. Let’s check the part which uses it.There is a size check for the input data vector, but there is no any bound check for idx_ so an out-of-bounds (OOB) read/write occurs.Although the vulnerability is simple, we need to obtain arbitrary address read / write primitives with this relative address read / write, and finally achieve Arbitrary Code Execution.Exploit - AAR/WNow, we have relative read / write primitive of uint64_t size. In fact, there is no difference in the method to achieve arbitrary address read / write.However, in order to access an arbitrary address, we must know the address of the current object. This is because we need to measure the distance to move to the target.There are various ways to leak the address of a controllable object.In this challenge, it is difficult to achieve address leakage with just a simple OOB read because there is no valid address area written anywhere in the heap area. Among them, we tried using brand new technique that can stably leak objects by utilizing the characteristics of Oilpan GC.Oilpan GCThe Heap object of Oilpan GC has the following structure [link].Oilpan GC uses a different allocation method than PartitionAlloc (PA), which is mark-and-sweep and space. Unlike PA, which uses slot-bucket, Oilpan allocates space for the heap and divides (i.e., allocates) the heap object as much as requested size from the space when a request comes in.In other words, without a fixed slot, it dynamically allocates multiple sizes in each space.When they lose their reference and are GC reclaims them, they take the form of FreeList::Entry.When an object in the space is freed, the HeapObject changes to a FreeList::Entry, and additional next_ fields are created to point to the next freed object.Leak IdeaThe idea is as follows:Loop the action below enough times to allocate new spaceSpray shell objectSpray File in each shellTrigger gc()Read the next_ of the header of the next adjacent chunk of FileBuffer in the N-th Sprayed ObjectLeak (N-1)th Sprayed_objectSince each shell has only one File Buffer, N shells are needed to spray N File Buffers.Considering the characteristics of the Oilpan GC described above, consider the following chunk situation.Currently, there is only my object in space. When an object is dynamically divided(i.e., allocated) from space, gc() is executed and the small areas between each object will be treated as Free Entry, forming a FreeList as shown above.We can now read the chained Free Entry by reading temp = sizeof(FileBuffer) + 0x8 from the Sprayed2 object, and leak the Sprayed 1 address through heap_leak = temp - sizeof(FileBuffer)This allows us to leak the address of the object with only spray and out-of-bounds, regardless of how big the distance is between Sprayed 1 and Sprayed 2 whether there is a stable address.Since we have the address of the Sprayed 1 object and the relative address read / write, we can perform arbitrary address read / write.In the exploit, after sufficient spray, it triggers gc() and then leaks objects 90th to 89th.Exploit - Arbitrary Code ExecutionNow, we obtain the arbitrary address read / write primitives.In a typical V8 engine, addrof is used to obtain address of a Wasm RWX Page. However, we only have OOB, and it seems difficult to create an addrof primitive.So what should we do?Overwrite the vtable of HeapMojoRemote to call 0x4141414141414141?The challenge says that it should be exploited on chrome.exe running on Windows 11 24H2. That is, in order to achieve arbitrary function calls in the challenge, CFG Bypass must be accompanied. Of course, considering the huge size of the code base, there may be many gadgets that can bypass CFG.Also, Function::Invoker Chaining, a well-known technique, can bypass CFG.We wanted to find a more stable method, and after auditing the code, we found that there is a LazyInstance Getter for WasmCodePointerObject. We can leak Wasm RWX Page by reading WasmCodePointerTable → entrypoint_.Let's overwrite RWX Page with arbitrary shellcode and execute wasm exports function.In the end, we can stably execute arbitrary shellcode while maintaining persistence. An interesting fact is that the bug of the SBX challenge can be triggered even in the Renderer. However, triggering the vulnerability requires a slight race condition in the SBX Challenge, we are unsure whether UAF Object can be reliably occupied in Blink.

EnkiWhiteHat

Jul 21, 2025

Vulnerability research

From Blink to Nt: Codegate 2025 FullChain Write-up

Challenge OverviewThe goal of the challenge is to find vulnerabilities in the renderer process and develop an exploit code by analyzing the provided rce-sbx-138-0-7204-97.patch file.The patch file creates a new Blink module called minishell in the renderer. It provides various shell functions and file writing and saving, and the file data is managed through Codegate File System (CFS), which is a browser API.The available commands are:They are similar to the basic shell commands. Commands such as exec are not implemented, but there are several file operations.When a file is opened, it is managed through file_descriptor_ in the form of a FileBuffer class until Save.A user can invoke the minishell as follows:Callable methods can be bound in the *idl file.In short, one user can have multiple shells and execute each command in one shell.VulnerabilityWe can see the main functionality in mini_shell.cc.However, the vulnerability is pretty simple compared to the file size. The following shows the FileBuffer structure.In here, we can see the fixed-size buffer. Let’s check the part which uses it.There is a size check for the input data vector, but there is no any bound check for idx_ so an out-of-bounds (OOB) read/write occurs.Although the vulnerability is simple, we need to obtain arbitrary address read / write primitives with this relative address read / write, and finally achieve Arbitrary Code Execution.Exploit - AAR/WNow, we have relative read / write primitive of uint64_t size. In fact, there is no difference in the method to achieve arbitrary address read / write.However, in order to access an arbitrary address, we must know the address of the current object. This is because we need to measure the distance to move to the target.There are various ways to leak the address of a controllable object.In this challenge, it is difficult to achieve address leakage with just a simple OOB read because there is no valid address area written anywhere in the heap area. Among them, we tried using brand new technique that can stably leak objects by utilizing the characteristics of Oilpan GC.Oilpan GCThe Heap object of Oilpan GC has the following structure [link].Oilpan GC uses a different allocation method than PartitionAlloc (PA), which is mark-and-sweep and space. Unlike PA, which uses slot-bucket, Oilpan allocates space for the heap and divides (i.e., allocates) the heap object as much as requested size from the space when a request comes in.In other words, without a fixed slot, it dynamically allocates multiple sizes in each space.When they lose their reference and are GC reclaims them, they take the form of FreeList::Entry.When an object in the space is freed, the HeapObject changes to a FreeList::Entry, and additional next_ fields are created to point to the next freed object.Leak IdeaThe idea is as follows:Loop the action below enough times to allocate new spaceSpray shell objectSpray File in each shellTrigger gc()Read the next_ of the header of the next adjacent chunk of FileBuffer in the N-th Sprayed ObjectLeak (N-1)th Sprayed_objectSince each shell has only one File Buffer, N shells are needed to spray N File Buffers.Considering the characteristics of the Oilpan GC described above, consider the following chunk situation.Currently, there is only my object in space. When an object is dynamically divided(i.e., allocated) from space, gc() is executed and the small areas between each object will be treated as Free Entry, forming a FreeList as shown above.We can now read the chained Free Entry by reading temp = sizeof(FileBuffer) + 0x8 from the Sprayed2 object, and leak the Sprayed 1 address through heap_leak = temp - sizeof(FileBuffer)This allows us to leak the address of the object with only spray and out-of-bounds, regardless of how big the distance is between Sprayed 1 and Sprayed 2 whether there is a stable address.Since we have the address of the Sprayed 1 object and the relative address read / write, we can perform arbitrary address read / write.In the exploit, after sufficient spray, it triggers gc() and then leaks objects 90th to 89th.Exploit - Arbitrary Code ExecutionNow, we obtain the arbitrary address read / write primitives.In a typical V8 engine, addrof is used to obtain address of a Wasm RWX Page. However, we only have OOB, and it seems difficult to create an addrof primitive.So what should we do?Overwrite the vtable of HeapMojoRemote to call 0x4141414141414141?The challenge says that it should be exploited on chrome.exe running on Windows 11 24H2. That is, in order to achieve arbitrary function calls in the challenge, CFG Bypass must be accompanied. Of course, considering the huge size of the code base, there may be many gadgets that can bypass CFG.Also, Function::Invoker Chaining, a well-known technique, can bypass CFG.We wanted to find a more stable method, and after auditing the code, we found that there is a LazyInstance Getter for WasmCodePointerObject. We can leak Wasm RWX Page by reading WasmCodePointerTable → entrypoint_.Let's overwrite RWX Page with arbitrary shellcode and execute wasm exports function.In the end, we can stably execute arbitrary shellcode while maintaining persistence. An interesting fact is that the bug of the SBX challenge can be triggered even in the Renderer. However, triggering the vulnerability requires a slight race condition in the SBX Challenge, we are unsure whether UAF Object can be reliably occupied in Blink.

EnkiWhiteHat

Jul 21, 2025

Vulnerability research

From Blink to Nt: Codegate 2025 FullChain Write-up

Challenge OverviewThe goal of the challenge is to find vulnerabilities in the renderer process and develop an exploit code by analyzing the provided rce-sbx-138-0-7204-97.patch file.The patch file creates a new Blink module called minishell in the renderer. It provides various shell functions and file writing and saving, and the file data is managed through Codegate File System (CFS), which is a browser API.The available commands are:They are similar to the basic shell commands. Commands such as exec are not implemented, but there are several file operations.When a file is opened, it is managed through file_descriptor_ in the form of a FileBuffer class until Save.A user can invoke the minishell as follows:Callable methods can be bound in the *idl file.In short, one user can have multiple shells and execute each command in one shell.VulnerabilityWe can see the main functionality in mini_shell.cc.However, the vulnerability is pretty simple compared to the file size. The following shows the FileBuffer structure.In here, we can see the fixed-size buffer. Let’s check the part which uses it.There is a size check for the input data vector, but there is no any bound check for idx_ so an out-of-bounds (OOB) read/write occurs.Although the vulnerability is simple, we need to obtain arbitrary address read / write primitives with this relative address read / write, and finally achieve Arbitrary Code Execution.Exploit - AAR/WNow, we have relative read / write primitive of uint64_t size. In fact, there is no difference in the method to achieve arbitrary address read / write.However, in order to access an arbitrary address, we must know the address of the current object. This is because we need to measure the distance to move to the target.There are various ways to leak the address of a controllable object.In this challenge, it is difficult to achieve address leakage with just a simple OOB read because there is no valid address area written anywhere in the heap area. Among them, we tried using brand new technique that can stably leak objects by utilizing the characteristics of Oilpan GC.Oilpan GCThe Heap object of Oilpan GC has the following structure [link].Oilpan GC uses a different allocation method than PartitionAlloc (PA), which is mark-and-sweep and space. Unlike PA, which uses slot-bucket, Oilpan allocates space for the heap and divides (i.e., allocates) the heap object as much as requested size from the space when a request comes in.In other words, without a fixed slot, it dynamically allocates multiple sizes in each space.When they lose their reference and are GC reclaims them, they take the form of FreeList::Entry.When an object in the space is freed, the HeapObject changes to a FreeList::Entry, and additional next_ fields are created to point to the next freed object.Leak IdeaThe idea is as follows:Loop the action below enough times to allocate new spaceSpray shell objectSpray File in each shellTrigger gc()Read the next_ of the header of the next adjacent chunk of FileBuffer in the N-th Sprayed ObjectLeak (N-1)th Sprayed_objectSince each shell has only one File Buffer, N shells are needed to spray N File Buffers.Considering the characteristics of the Oilpan GC described above, consider the following chunk situation.Currently, there is only my object in space. When an object is dynamically divided(i.e., allocated) from space, gc() is executed and the small areas between each object will be treated as Free Entry, forming a FreeList as shown above.We can now read the chained Free Entry by reading temp = sizeof(FileBuffer) + 0x8 from the Sprayed2 object, and leak the Sprayed 1 address through heap_leak = temp - sizeof(FileBuffer)This allows us to leak the address of the object with only spray and out-of-bounds, regardless of how big the distance is between Sprayed 1 and Sprayed 2 whether there is a stable address.Since we have the address of the Sprayed 1 object and the relative address read / write, we can perform arbitrary address read / write.In the exploit, after sufficient spray, it triggers gc() and then leaks objects 90th to 89th.Exploit - Arbitrary Code ExecutionNow, we obtain the arbitrary address read / write primitives.In a typical V8 engine, addrof is used to obtain address of a Wasm RWX Page. However, we only have OOB, and it seems difficult to create an addrof primitive.So what should we do?Overwrite the vtable of HeapMojoRemote to call 0x4141414141414141?The challenge says that it should be exploited on chrome.exe running on Windows 11 24H2. That is, in order to achieve arbitrary function calls in the challenge, CFG Bypass must be accompanied. Of course, considering the huge size of the code base, there may be many gadgets that can bypass CFG.Also, Function::Invoker Chaining, a well-known technique, can bypass CFG.We wanted to find a more stable method, and after auditing the code, we found that there is a LazyInstance Getter for WasmCodePointerObject. We can leak Wasm RWX Page by reading WasmCodePointerTable → entrypoint_.Let's overwrite RWX Page with arbitrary shellcode and execute wasm exports function.In the end, we can stably execute arbitrary shellcode while maintaining persistence. An interesting fact is that the bug of the SBX challenge can be triggered even in the Renderer. However, triggering the vulnerability requires a slight race condition in the SBX Challenge, we are unsure whether UAF Object can be reliably occupied in Blink.

EnkiWhiteHat

Jul 21, 2025

Copyright © 2025. ENKI WhiteHat Co., Ltd. All rights reserved.

Copyright © 2025. ENKI WhiteHat Co., Ltd. All rights reserved.

Copyright © 2025. ENKI WhiteHat Co., Ltd. All rights reserved.