惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
WordPress大学
WordPress大学
MyScale Blog
MyScale Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
The Blog of Author Tim Ferriss
U
Unit 42
罗磊的独立博客
G
Google Developers Blog
Microsoft Azure Blog
Microsoft Azure Blog
The Cloudflare Blog
aimingoo的专栏
aimingoo的专栏
Vercel News
Vercel News
N
Netflix TechBlog - Medium
H
Hackread – Cybersecurity News, Data Breaches, AI and More
云风的 BLOG
云风的 BLOG
Hugging Face - Blog
Hugging Face - Blog
大猫的无限游戏
大猫的无限游戏
F
Fortinet All Blogs
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
博客园 - 【当耐特】
H
Help Net Security
The GitHub Blog
The GitHub Blog

Security Research | Blog

Operation RapidRust: New APT36 Malware Tools | ThreatLabz SloppyRAT: A New Tool For Ransomware Attacks | ThreatLabz Microsoft Exchange Vulnerability: What Admins Should Do C2Looper Backdoor Uses GitHub for C2 | ThreatLabz Midnight Blizzard launches CaptiveCrunch | ThreatLabz ChainDrop NPM Worm Analysis | ThreatLabz Abyssos Modular RAT Analysis | ThreatLabz Frontier AI and Enterprise Readiness | Zscaler Ransomware Victims Research | ThreatLabz Targeted Attack on Middle East Govts (Part 2) | ThreatLabz Technical Analysis of GoGRPC | ThreatLabz Targeted Attack on Middle East Govts (Part 1) | ThreatLabz ClaudeFix: Shared Claude Chats Meet ClickFix | Zscaler Why Do F1 Teams Need Cybersecurity, and What Is AI’s Role? Indirect Prompt Injection Targets AI Agents | ThreatLabz Splunk Enterprise RCE (CVE-2026-20253) | ThreatLabz Edgecution: Malicious Edge Extension Backdoor | ThreatLabz SmartApeSG Supply Chain Attack Targets Okendo | ThreatLabz AI Generated ClickFix Attack Delivers SmartRAT | ThreatLabz What the ThreatLabz 2026 Phishing and Initial Access Report Means for the Public Sector | Zscaler Shai-Hulud: Miasma, Hades, & AI Scanner Evasion | ThreatLabz Zscaler ThreatLabz 2026 Phishing and Initial Access Report Technical Analysis of MLTBackdoor | ThreatLabz When the Scanner Starts Thinking: Learnings from Mythos & GPT 5.5 Cyber in Security Testing | Zscaler OpenClaw Skill Distributes Remcos & GhostLoader | ThreatLabz Tropic Trooper: AdaptixC2 + Custom Beacon | ThreatLabz Do not delete blog (testing) | Zscaler Payouts King Takes Aim at the Ransomware Throne | ThreatLabz The Alibaba Incident and Why Zero Trust Matters More Than Ever In-Memory Loader Drops ScreenConnect | ThreatLabz
Termncolor and Colorinal Explained | ThreatLabz
Manisha Ramcharan Prajapati, Satyam Singh · 2025-08-15 · via Security Research | Blog

Technical Analysis

Discovery of the malicious package

While monitoring for threats, ThreatLabz identified a Python package named termncolor, which imports a secondary package, colorinal, via pip. This package was flagged during routine scans in our Python package database, as illustrated in the figure below.

Shows the termncolor package as it appears in the Zscaler package hunting database.

Figure 1: Shows the termncolor package as it appears in the Zscaler package hunting database. 

While termncolor functions as a color utility for Python without displaying any malicious behavior, the inclusion of its external dependency, colorinal, raises concerns. The figure below illustrates the potential attack chain connected to the PyPI package discovery.

The attack chain illustrates how termncolor could import colorinal, which would trigger unicode.py to deploy a malicious DLL via sideloading.

Figure 2: The attack chain illustrates how termncolor could import colorinal, which would trigger unicode.py to deploy a malicious DLL via sideloading.

File investigation (unicode.py)

ThreatLabz uncovered a critical file named unicode.py while investigating the colorinal package, which is pivotal to the malware's operation. At first glance, unicode.py looks like a normal Python script designed for terminal color utilities. However, our analysis revealed a method, is_color_supported, which loads an embedded DLL called terminate.dll. This DLL deploys the malware's payload, kicking off the first stage of the attack. To avoid detection, the malware deletes both unicode.py and terminate.dll after execution.

In the code sample below, the Python class ctypes.CDLL(...) loads the terminate.dll file into memory, making its functions accessible to Python. The DLL's file path is derived from the directory of the current Python script using os.path.dirname(__file__). Once loaded, the termin instance allows Python to interface with the DLL. The function then calls the export function envir from the loaded DLL, passing a UTF-8-encoded string, xterminalunicode, which appears to query the terminal's capabilities. The result of this query determines whether the terminal supports color.

def is_color_supported():
   try:
       "Find out if your terminal environment supports color."
       termin = ctypes.CDLL(os.path.dirname(__file__) + "/" + "terminate.dll")
       envir = termin.envir("xterminalunicode".encode("utf-8"))


First stage

The first stage of the malware operation is initiated by the execution of terminate.dll, as mentioned above. Below is a technical breakdown of the role terminate.dll plays in the attack.

Decryption of the payload

A core function of terminate.dll is to decrypt its embedded payload using AES in CBC mode. It uses a UTF-8-encoded key, xterminalunicode, provided by a Python script. Once deciphered, the payload reveals the files necessary to proceed to the next stage of the attack.

The decrypted payload is stored in the target system’s %LOCALAPPDATA%\vcpacket directory, which serves as the staging area for the next-stage files. Here, terminate.dll drops two distinct executables: vcpktsvr.exe, a signed file that appears legitimate and is used for DLL sideloading, and libcef.dll, a malicious DLL responsible for executing the malware’s harmful activities.

Persistence mechanism

To establish persistence, the malware creates a registry entry named pkt-update under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run. This entry points to the file vcpktsvr.exe, which was dropped into the %LOCALAPPDATA%\vcpacket directory as mentioned above.

Linux variant

The malware also includes a variant tailored for Linux systems, broadening its scope beyond Windows environments. The file terminate.so, as shown in the code sample below, is a Shared Object file, a dynamically linked library commonly used in Unix-like operating systems. Similar to its Windows counterpart, this file is designed to execute the same functionality on Linux systems.

def is_color_supported():
   try:
       "Find out if your terminal environment supports color."
       termin = ctypes.CDLL(os.path.dirname(__file__) + "/" + "terminate.so")
       envir = termin.envir("xterminalunicode".encode("utf-8"))


Second stage


System information discovery

The second stage begins with the execution of libcef.dll, the primary malicious component dropped in the first stage. Unlike the legitimate vcpktsvr.exe, libcef.dll is specifically designed to communicate with the threat actor-controlled C2 server and gather crucial system information, such as the computer name, username, and operating system version.

Command-and-control (C2) HTTPS communication

The sample concatenates all the strings and formats the collected system information for transmission to the C2 server using HTTPS. The malware leverages the Zulip team messaging platform, disguising its activity by mimicking legitimate communication patterns, as shown in the figure below.

Shows the malware communicating with the Zulip chat platform.

Figure 3: Shows the malware communicating with the Zulip chat platform.

The collected data is sent to the Zulip channel, after which the malware resolves APIs via a custom hashing method (explained in the section below) and executes shellcode received from the threat actor in a new thread.

Techniques used by the threat actors
 

API hashing 

The API hashing algorithm used by the threat actors appears to be a custom, lightweight hash function, likely designed for specific use cases such as obfuscating DLL or API names in low-level programming or malware. Its simplicity—relying on ASCII values, multiplication, and bitwise operations—makes it fast but potentially more prone to collisions compared to cryptographic hashes.

The Python code sample below shows the custom hashing algorithm. 

def calculate_hash(name: str, case_sensitive: bool = False) -> int:
   if not name:
       return 12
   hash_value = 12
   string_to_hash = name
   
   if not case_sensitive:
       string_to_hash = name.upper()
   current_char_value = ord(string_to_hash[0])
   
   for i in range(1, len(string_to_hash) + 1):
       temp_hash = current_char_value + 4 * hash_value
       hash_value = (2 * temp_hash) & 0xFFFFFFFF
       if i