Kaspersky's Global Research and Analysis Team (GReAT) has published detailed analysis of three malicious Python packages uploaded to PyPI (the Python Package Index — the official repository where developers download open-source Python libraries) that delivered a previously undocumented malware family called ZiChatBot. The campaign is attributed with moderate confidence to OceanLotus (also known as APT32), a sophisticated threat actor historically linked to Vietnamese government interests. The packages were removed before achieving widespread distribution, but the technical sophistication of the implant and its use of a legitimate team-chat platform as command-and-control (C2 — the infrastructure attackers use to send instructions to compromised machines) infrastructure marks a significant evolution in supply chain attack methodology.
ZiChatBot: Technical Details
The three malicious packages were uploaded to PyPI in mid-2025:
| Package Name | Upload Date | Masquerade | |————-|————|————| | uuid32-utils | 2025-07-16 | UUID generation utility | | colorinal | 2025-07-22 | Terminal color library | | termncolor | 2025-07-22 | ANSI color formatting |
All three were constructed as Python wheel packages — a pre-built distribution format (.whl files) that allows Python to install packages without compiling source code, which also means the installation step executes arbitrary code on the developer's machine.
Infection Chain on Windows
- Installing any of the three packages extracts a malicious DLL called
terminate.dllfrom the wheel archive. - The package's
__init__.pyimports a malicious helper file (unicode.py), which calls anis_color_supported()function — a convincing name designed to blend into a color library. - That function loads
terminate.dllinto the Python process memory and calls its exportedenvirfunction with the parameter"xterminalunicod". - The dropper decrypts an embedded payload using AES-CBC encryption, then LZMA-decompresses it.
- Two files are written to
%LOCALAPPDATA%\vcpacket\:vcpktsvr.exeandlibcef.dll(the ZiChatBot implant). - A registry run key is created for persistence:
HKCU\Software\Microsoft\Windows\CurrentVersion\Run→"pkt-update"="C:\Users\[User]\AppData\Local\vcpacket\vcpktsvr.exe". - The dropper shellcode removes its own artifacts and self-deletes.
Infection Chain on Linux
On Linux systems, the dropper places the malware binary at /tmp/obsHub/obs-check-update and installs a cron job (a scheduled task that runs automatically at defined intervals) for persistence:
5 * * * * /tmp/obsHub/obs-check-update
This executes the implant 5 minutes past every hour, providing reliable persistence without requiring elevated privileges.
ZiChatBot Command-and-Control via Zulip
The defining characteristic of ZiChatBot is its command-and-control channel: instead of connecting to a dedicated C2 server — which is easily detected and blocked — the malware communicates over the Zulip REST API. Zulip is an open-source team messaging platform used by software development teams, universities, and open-source projects. By hiding its communications inside legitimate Zulip traffic, ZiChatBot blends with normal business communication and bypasses network-layer C2 detection.
The implant used two channel-topic pairs within a Zulip organization at helper.zulipchat.com — one to receive commands, one to send output. After executing a command, ZiChatBot sends a heart emoji (❤) as an acknowledgment. The authentication token embedded in the samples:
Morian-bot@helper.zulipchat.com:U8REXlI6Kf8qXB9rQzOPBiIA4brJ58qG
The Zulip organization has since been deactivated. ZiChatBot's core capability is shellcode execution — meaning the attacker can deliver arbitrary follow-on payloads to infected machines by passing shellcode through the Zulip channel. It also exfiltrates basic system information on initial check-in.
Attribution to OceanLotus
Kaspersky attributes this campaign to OceanLotus (APT32) based on a 64% code similarity match between the terminate.dll dropper and a dropper previously linked to OceanLotus in separate threat intelligence reports. The matching elements include the AES-CBC payload decryption algorithm and the LZMA decompression routine — not just structural similarity but identical implementation choices that suggest shared code development.
OceanLotus is a Vietnamese-attributed APT (Advanced Persistent Threat — a designation for well-resourced, long-running threat actors, typically state-sponsored) active since at least 2014. The group has historically focused on Southeast Asian government and defense targets, dissident organizations, and foreign companies operating in Vietnam. Expanding the group's reach to target the global Python developer community via PyPI supply chain represents a geographic and tactical evolution.
Exploitation Status
No CVE (Common Vulnerabilities and Exposures identifier) was involved. The campaign exploited developer trust in the PyPI ecosystem, not a software flaw. There is no CVSS score (Common Vulnerability Scoring System — a standardized 0–10 severity rating) applicable, as this is a social trust attack rather than a software vulnerability. Kaspersky confirmed zero infections — the packages were identified and removed from PyPI before achieving significant distribution, and the Zulip organization was deactivated before the C2 could be used at scale.
MITRE ATT&CK (a publicly maintained adversary behavior framework) techniques observed include:
- T1195.001 — Supply Chain: Compromise Software Repository
- T1547.001 — Boot or Logon Initialization Scripts: Registry Run Keys (Windows)
- T1547.003 — Boot or Logon Initialization Scripts: Cron job scheduling (Linux)
- T1059 — Command and Scripting Interpreter (Python execution)
- T1571 — Non-Standard Port/Protocol (REST API-based C2)
Who Is Affected
Any developer who installed uuid32-utils, colorinal, or termncolor from PyPI between July 2025 and their removal. Given that confirmed infections are zero, the risk is now limited to retrospective checking of development machines and CI/CD (Continuous Integration/Continuous Delivery — automated build and deployment pipelines that often run package installs) environments that may have cached the packages.
OceanLotus's historical targeting patterns — government contractors, defense-adjacent technology firms, companies operating in Southeast Asia — suggest that software developers at these organizations were the intended victims, though PyPI's open nature means any developer globally could have been inadvertently exposed.
What You Should Do Right Now
- Audit your Python environments for the three package names. Run
pip list | grep -E "uuid32-utils|colorinal|termncolor"across developer workstations and CI/CD runners.
pip list | grep -E "uuid32-utils|colorinal|termncolor"
- Check for the persistence artifacts. On Windows, query for
%LOCALAPPDATA%\vcpacket\vcpktsvr.exeand thepkt-updateregistry run key. On Linux, check crontab entries for/tmp/obsHub/.
# Linux check
crontab -l 2>/dev/null | grep obsHub
ls /tmp/obsHub/ 2>/dev/null
- Hash-match against the IOCs below on any machine that may have run pip installs in the July–September 2025 window.
- Enforce package allowlists in CI/CD. Use
pip-auditorpip-reviewto flag packages not in your approved registry before build steps install them. Consider pinning all dependencies with hash verification (--require-hashes). - Block Zulip domains at the network perimeter if not in use.
zulipchat.comtraffic from developer workstations that do not use Zulip for business purposes is anomalous and worth investigating. - Rotate secrets on any machine where these packages were installed, treating the machine as fully compromised — ZiChatBot's shellcode execution capability means arbitrary follow-on payloads could have been deployed.
Indicators of Compromise
Malicious package MD5 hashes:
termncolor:5152410aeef667ffaf42d40746af4d84uuid32_utils(variant 1):0a5a06fa2e74a57fd5ed8e85f04a483auuid32_utils(variant 2):e4a0ad38fd18a0e11199d1c52751908buuid32_utils(variant 3):5598baa59c716590d8841c6312d8349ecolorinal:ba2f1868f2af9e191ebf47a5fab5cbab
Dropper / payload MD5 hashes:
terminate.dll(Windows dropper):1995682d600e329b7833003a01609252terminate.so(Linux dropper):38b75af6cbdb60127decd59140d10640libcef.dll(ZiChatBot implant):a26019b68ef060e593b8651262cbd0f6
Malicious PyPI packages (removed):
uuid32-utils,colorinal,termncolor
C2 infrastructure:
helper.zulipchat.com(Zulip organization — deactivated)- Bot:
Morian-bot@helper.zulipchat.com
Background: Understanding the Risk
PyPI supply chain attacks have escalated dramatically over the past three years. Security researchers at Sonatype, Checkmarx, and Socket document hundreds of malicious packages per month across Python, npm, and RubyGems. What makes the OceanLotus ZiChatBot campaign distinctive is its attribution to a state-sponsored APT, not an opportunistic criminal group — and its use of legitimate collaborative infrastructure (Zulip) instead of dedicated C2 servers.
The tactic of living inside legitimate SaaS (Software-as-a-Service) communication platforms has appeared before: threat actors have abused Slack, Discord, GitHub Issues, and Google Docs as C2 channels. Each platform migration forces defenders to add new detection rules and to consider whether to block widely used productivity tools. Zulip, with its focus on software development teams, is a particularly high-value target for an APT whose primary objective is developer credential theft and persistent access to software build systems.
From a developer security standpoint, the threat model has fundamentally changed. Installing an unfamiliar package is no longer merely an intellectual property or license risk — it is now a direct vector for state-sponsored espionage.
Conclusion
The OceanLotus ZiChatBot campaign confirms that state-sponsored APTs are actively targeting developer supply chains on PyPI. While no confirmed infections resulted from this specific campaign, the technical capability demonstrated — cross-platform dropper, Zulip-based covert C2, shellcode execution — represents a production-ready capability that may reappear with different package names. Developers should audit their July–September 2025 pip installs and implement hash-pinned dependencies across all CI/CD pipelines.
For any query contact us at contact@cipherssecurity.com

