Threat reportMalwareTL-2026-0467

OceanLotus (APT32) PyPI Supply Chain Campaign — ZiChatBot Cross-Platform Malware via uuid32-utils, termncolor & colorinal Wheels Using Zulip REST API for C2

highMONITORING

OceanLotus (APT32) PyPI Supply Chain Campaign (TL-2026-0467), also tracked as ZiChatBot Campaign, is a high-severity malware campaign, first published 2026-05-06. It is attributed to APT32 (Vietnam) with medium confidence, affects Python Software Foundation Python Package Index (PyPI), maps to 21 MITRE ATT&CK techniques (T1027, T1036.005, T1053.003), and is covered by 9 detection rules and 42 indicators of compromise.

Severity
HIGHAssessed severity
CVEs
0None referenced
Techniques
21MITRE ATT&CK
Actors
1APT32
Detection rules
9SPL · KQL · Sigma
IOCs
42Indicators of compromise

Key facts for TL-2026-0467

Threat ID
TL-2026-0467
Also known as
ZiChatBot Campaign, Operation ZiChatBot, OceanLotus PyPI Wheel Campaign, termncolor/colorinal supply chain attack
Severity
HIGH
Status
MONITORING
Category
MALWARE
First published
Last reviewed
Attribution
APT32
Attribution confidence
MEDIUM
Nation-state nexus
Vietnam
Motivation
ESPIONAGE
Target sectors
technology, software-development, open-source, government, defense, telecommunications, automotive, pharmaceutical, research-academia
Target regions
Southeast Asia, ASEAN, North America, Europe, Global (developer ecosystem)
Detection rules
9
Indicators of compromise
42

Malware and tooling in OceanLotus (APT32) PyPI Supply Chain Campaign

Malware and tooling: ZiChatBot, Zulip Cloud (legitimate SaaS), Zulip REST API (custom ZiChatBot)

How OceanLotus (APT32) PyPI Supply Chain Campaign works

Kaspersky GReAT attributed a PyPI supply chain campaign to OceanLotus (APT32) involving three malicious wheel packages — uuid32-utils, termncolor and colorinal — uploaded between 10-22 July 2025 that drop a previously unknown cross-platform malware family named ZiChatBot. The malware abuses the Zulip team-chat REST API on the helper.zulipchat.com organization (now deactivated) as a covert C2 channel, weaponising a benign vcpktsvr.exe via DLL side-loading of libcef.dll on Windows and a /tmp/obsHub/obs-check-update ELF on Linux. Attribution to OceanLotus is supported by Kaspersky's Threat Attribution Engine which matched dropper decompression and decryption logic with 64% similarity to known APT32 droppers; an earlier Zscaler ThreatLabz disclosure in August 2025 covered the termncolor/colorinal cluster without naming the actor.

Overview -------- Between 10 July and 22 July 2025, three malicious Python wheel packages were published to the Python Package Index (PyPI) by accounts laz**** (tutamail.com) and sym**** (proton.me): uuid32-utils (multiple 1.x.x versions), colorinal 0.1.7 and termncolor 3.1.0. termncolor depends on colorinal so installing termncolor pulls in the malicious chain; uuid32-utils carries the dropper directly. colorinal had ~529 downloads and termncolor ~355 downloads before removal. All three packages were taken down by PyPI maintainers, and the attacker-controlled Zulip organisation "helper" (helper.zulipchat.com) was officially deactivated by Kandra Labs. Kaspersky's Securelist disclosure on 6 May 2026 attributed the campaign to OceanLotus (APT32) — a Vietnam-aligned espionage group — based on a 64% similarity match between the dropped loader's decryption/decompression logic and a known OceanLotus dropper, surfaced by Kaspersky's Threat Attribution Engine. The malware family was named ZiChatBot for its use of the Zulip Chat platform as command and control.

Windows Infection Chain ------------------------ 1. The user runs `pip install termncolor` (or installs uuid32-utils). The wheel registers `colorinal\unicode.py` which is imported by `__init__.py`. 2. `is_color_supported()` in unicode.py loads the bundled native module `terminate.dll` into the running Python process and invokes the exported function `envir` with the parameter `xterminalunicod` (UTF-8 encoded). 3. terminate.dll AES-CBC decrypts an embedded blob and drops two files into `%LOCALAPPDATA%\vcpacket\` — a legitimate signed Microsoft binary `vcpktsvr.exe` (the side-loading host) and the malicious `libcef.dll` (the ZiChatBot payload). 4. vcpktsvr.exe is launched, side-loads libcef.dll, and ZiChatBot begins execution. 5. Persistence is established by writing the registry value `HKCU\Software\Microsoft\Windows\CurrentVersion\Run\pkt-update` pointing to `%LOCALAPPDATA%\vcpacket\vcpktsvr.exe`. 6. The dropper and unicode.py self-delete to reduce forensic surface.

Linux Infection Chain --------------------- 1. The Linux variant of the wheel ships terminate.so (and a variant Backward.so) which performs the equivalent decryption stage. 2. The ELF payload is dropped to `/tmp/obsHub/obs-check-update`. 3. Persistence is established with the user crontab entry: `5 * * * * /tmp/obsHub/obs-check-update`.

ZiChatBot — C2 over Zulip ------------------------- Unlike traditional malware ZiChatBot does not contact dedicated attacker infrastructure. Instead it authenticates to the Zulip Cloud REST API at `https://helper.zulipchat.com/api/v1/` using a hard-coded base64-embedded credential that decodes to `Morian-bot@helper.zulipchat.com:U8REXlI6Kf8qXB9rQzOPBiIA4brJ58qG`. It uses two fixed channel/topic pairs: one for posting harvested system information from the victim and one for fetching shellcode tasking. Shellcode is XOR-decoded with the three-byte key `3a7` and executed reflectively in the host process. The bot supports a single command — "execute shellcode received from server" — and acknowledges successful execution by sending the heart emoji (`:heart:`) reaction back to the C2 message. Strings, imports and configuration are protected with AES-CBC. Forensic analysis of the Zulip organisation showed three active operator users and 90,692 messages exchanged from 10 July 2025 onward.

Attribution ----------- Kaspersky Threat Attribution Engine reported a 64% similarity score between ZiChatBot's loader code (decryption and decompression routines, control-flow markers and string obfuscation) and a known OceanLotus dropper. OceanLotus (also tracked as APT32, SeaLotus, APT-C-00, Cobalt Kitty, Ocean Buffalo) is a Vietnam-nexus espionage actor with a long history of supply chain abuse, watering-hole operations and signed-binary side-loading targeting ASEAN governments, dissidents, automotive and pharmaceutical sectors. The choice of Zulip as a C2 channel is novel for the actor and represents the first publicly documented use of Zulip's REST API for C2 by a nation-state cluster.

Defensive Implications ---------------------- Developers and CI/CD pipelines that pull from public PyPI without pinning or hash-checking are the primary attack surface. The Zulip-as-C2 design defeats domain blocklists that allow productivity SaaS and bypasses TLS inspection by riding a legitimate, certificate-pinned vendor. Defenders should hunt for child processes of `python.exe` writing to `%LOCALAPPDATA%\vcpacket\`, registry Run-key writes named `pkt-update`, outbound TLS to `helper.zulipchat.com`, and any anomalous workstation traffic to `*.zulipchat.com` from hosts that do not normally use Zulip.

MITRE ATT&CK techniques used in TL-2026-0467

Defense Evasion

T1027 Obfuscated Files or Information; T1036.005 Match Legitimate Resource Name or Location; T1070.004 Indicator Removal: File Deletion; T1140 Deobfuscate/Decode Files or Information; T1574.001 DLL; T1620 Reflective Code Loading

Persistence

T1053.003 Scheduled Task/Job: Cron; T1547.001 Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder

Execution

T1059.006 Command and Scripting Interpreter: Python; T1106 Native API; T1204.002 User Execution: Malicious File

Command and Control

T1071.001 Application Layer Protocol: Web Protocols; T1102.002 Web Service: Bidirectional Communication; T1132.001 Data Encoding: Standard Encoding; T1573.001 Encrypted Channel: Symmetric Cryptography

Discovery

T1082 System Information Discovery

Initial Access

T1195 Supply Chain Compromise; T1195.002 Compromise Software Supply Chain

Resource Development

T1583.006 Acquire Infrastructure: Web Services; T1585.002 Establish Accounts: Email Accounts; T1587.001 Develop Capabilities: Malware

Affected products and versions in OceanLotus (APT32) PyPI Supply Chain Campaign

  • Python Software Foundation — Python Package Index (PyPI)
    Vulnerable versions: uuid32-utils 1.x.x; colorinal 0.1.7; termncolor 3.1.0
    Fixed in: all three packages removed from PyPI
  • Microsoft — Windows
    Vulnerable versions: Windows 10; Windows 11; Windows Server 2019; Windows Server 2022
  • Linux — GNU/Linux distributions running CPython
    Vulnerable versions: any glibc-based x86_64 distribution with Python 3
  • Kandra Labs — Zulip Cloud (helper.zulipchat.com)
    Vulnerable versions: organization 'helper'
    Fixed in: organization deactivated by Zulip Trust & Safety

Remediation for OceanLotus (APT32) PyPI Supply Chain Campaign

Patches

  • Remove uuid32-utils, colorinal 0.1.7 and termncolor 3.1.0 from any internal mirror or lockfile
  • Upgrade to a pinned version from a vetted alternative (e.g. termcolor, colorama) for any project that referenced termncolor

Immediate actions

  • Block all outbound traffic to helper.zulipchat.com at the perimeter and proxy
  • Hunt endpoints for the file path %LOCALAPPDATA%\vcpacket\ and the Linux path /tmp/obsHub/
  • Hunt the registry value HKCU\Software\Microsoft\Windows\CurrentVersion\Run\pkt-update and remove if present
  • Hunt the cron entry '5 * * * * /tmp/obsHub/obs-check-update' on Linux developer hosts
  • Quarantine any host that installed uuid32-utils, termncolor, or colorinal between 2025-07-10 and 2025-08-31
  • Rotate developer credentials, SSH keys, npm/PyPI tokens and cloud API keys exposed to suspect workstations

Workarounds

  • Restrict pip and npm installations from developer workstations to a curated internal index until hunt is complete
  • Apply egress filtering on developer subnets to block direct internet pip/npm pulls

Longer-term hardening

  • Mandate hash-pinned dependencies (pip install --require-hashes) in all CI/CD pipelines
  • Deploy private PyPI mirror (Artifactory, devpi, Nexus) with allowlist of vetted packages and hold-window for new releases
  • Enable PyPI 2FA enforcement and trusted-publisher OIDC for internal package publishers
  • Deploy EDR rules covering DLL side-loading from %LOCALAPPDATA%\vcpacket\ and reflective shellcode execution under python.exe child processes
  • Add SaaS-as-C2 detection for Zulip, Slack, Discord, Telegram and Mattermost API calls from non-business hosts

Weaknesses (CWE) in OceanLotus (APT32) PyPI Supply Chain Campaign

CWE-506, CWE-829, CWE-1357, CWE-494

Timeline of OceanLotus (APT32) PyPI Supply Chain Campaign

  • Earliest operator activity recorded inside the attacker-controlled 'helper' Zulip organization (per Zscaler ThreatLabz forensic review).
  • First malicious wheel uploaded to PyPI by author 'laz**** (tutamail.com)' — uuid32-utils 1.x.x series begins publication.
  • termncolor 3.1.0 and colorinal 0.1.7 uploaded to PyPI by author 'sym**** (proton.me)'; closes the July upload window. Zscaler ThreatLabz simultaneously discovers termncolor.
  • Zscaler ThreatLabz publishes 'Supply Chain Risk in Python: Termncolor and Colorinal Explained', documenting the DLL side-loading chain and Zulip C2 but not naming an actor. PyPI removes the packages.
  • The Hacker News, GBHackers, and Cybersecurity News publish coverage of the termncolor/colorinal cluster; npm sister-cluster (redux-ace, rtk-logger) reported in the same wave.
  • Kandra Labs (Zulip) deactivates the 'helper' organization and revokes the Morian-bot@helper.zulipchat.com bot credential.
  • Threat documented in Threadlinqs Intelligence as TL-2026-0467 with full IOC, MITRE and detection coverage.
  • Kaspersky GReAT publishes Securelist analysis naming the malware family ZiChatBot, releasing additional uuid32-utils IOCs and attributing the campaign to OceanLotus (APT32) with 64% similarity per the Threat Attribution Engine.
  • As of 2026-05-29, this specific campaign is contained: all three PyPI wheels (uuid32-utils, colorinal, termncolor) were removed and the helper.zulipchat.com C2 org was deactivated 2025-08-31, with no new beaconing since. But OceanLotus/APT32 remains a highly active Vietnam-nexus actor with ongoing supply-chain tradecraft, so resurgence is a live concern.

Sources cited for OceanLotus (APT32) PyPI Supply Chain Campaign

Detection coverage for TL-2026-0467

As of 2026-05-06, Threadlinqs Intelligence publishes 9 detection rule(s) for TL-2026-0467 across Splunk SPL, Microsoft KQL and Sigma, covering 42 indicator(s) of compromise. The whole corpus is readable without an account; a free account unlocks full detection query text in Splunk SPL, Microsoft KQL and Sigma; paid tiers add raw indicator values, correlation and the MCP server. Threadlinqs MCP server · View plans.

9 detection rules (Splunk SPL, Microsoft KQL, Sigma) · Blue and above. Compare plans
42 indicators of compromise · Red and above. Compare plans

Further reading

Threadlinqs Intelligence — Real-Time Threat Detection Platform

[ 0 threats ] [ 0 det ] [ CRIT: 0 ] [ HIGH: 0 ]
// threat_feed
$ sort --newest
Showing all threats

Live intelligence console

Threat level
Fig. 01 · Threat weatherIndexing the archive…
1 square = 1 threat · click to open

Latest Threats