# OceanLotus-attributed ZiChatBot PyPI droppers: uuid32-utils, colorinal, termncolor with Zulip-API C2

> Kaspersky GReAT (2026-05-08) re-attributed three PyPI wheels uploaded by an attacker between 2025-07-16 and 2025-07-22 - `uuid32-utils`, `colorinal`, and `termncolor` - to the Vietnam-aligned OceanLotus (APT32) group. The droppers fetch a Windows DLL or Linux `.so`, persist via Run-key or crontab, and load `ZiChatBot`, a Python backdoor that uses public Zulip REST APIs as its C2 channel to blend with normal developer traffic.

- Published: 2026-05-08
- Severity: high
- Kind: Typosquat - A package that never had a legitimate version, named to be mistaken for a real one - a misspelling, a lookalike scope, or an impersonated vendor SDK.
- Ecosystems: PyPI
- Scope: 3 packages, 7 compromised versions
- Tags: typosquat, infostealer, credential-theft, obfuscation, dormant-domain
- Threat actor: OceanLotus / APT32 (Kaspersky moderate-confidence attribution)
- Also known as: ZiChatBot, APT32 PyPI wheel campaign, Zulip-API C2 backdoor
- Detected by: Kaspersky GReAT, Zscaler ThreatLabz
- Incident ID: pypi-2026-05-08-oceanlotus-zichatbot-zulip-c2

## Affected packages (3)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [colorinal](https://dependencywatch.io/package/pypi/colorinal) | PyPI | 1.0.0 |
| [termncolor](https://dependencywatch.io/package/pypi/termncolor) | PyPI | 1.0.0 |
| [uuid32-utils](https://dependencywatch.io/package/pypi/uuid32-utils) | PyPI | 1.0.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4 |

## What happened

On 2026-05-08 Kaspersky's Global Research and Analysis Team published a re-attribution write-up linking three previously-disclosed malicious PyPI wheels to the Vietnam-aligned OceanLotus (APT32) group. The packages - `uuid32-utils`, `colorinal`, and `termncolor` - were first flagged in August 2025 by Zscaler ThreatLabz as generic supply-chain malware; Kaspersky's KTAE code-similarity engine matched the dropper logic at 64% against known APT32 implants, upgrading the incident from opportunistic crime to suspected state-sponsored espionage.

## Campaign

All three wheels were uploaded between 2025-07-16 and 2025-07-22 from a fresh attacker account. `uuid32-utils` impersonates a 32-character UUID generator, `colorinal` impersonates a cross-platform terminal-colour utility, and `termncolor` is a benign-looking wrapper that lists `colorinal` as a transitive dependency - installing the latter pulls and detonates the former. Recorded download totals before PyPI takedown: `uuid32-utils` 1,479, `colorinal` 614, `termncolor` 387 (Kaspersky tally; Zscaler observed 529 / 355 for `colorinal` / `termncolor` in an earlier snapshot).

## Payload - DLL sideload + crontab + Zulip C2

The bdist wheels carry a platform-matched dropper: a Windows DLL or a Linux `.so`. On Windows the dropper sideloads into a benign Python loader, drops a payload into `%APPDATA%`, and persists via `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`. On Linux the equivalent path uses a `crontab` entry to respawn the backdoor on reboot. The implant - Kaspersky-named `ZiChatBot` - is a Python backdoor whose distinguishing feature is that it has **no dedicated C2 server**: every command, exfiltration, and heartbeat is funnelled through the public Zulip team-chat REST API (`*.zulipchat.com`). The attacker created Zulip organisations and channels under throwaway accounts, then used Zulip's OAuth tokens as authenticated C2 - outbound looks like ordinary developer traffic to a Slack-style chat service. Kaspersky reports the Zulip organisations were deactivated after disclosure.

## Attribution

Kaspersky's KTAE clustering matched the dropper to OceanLotus / APT32 with **moderate confidence** at 64% code similarity. OceanLotus has been active since at least 2014 and historically targets Asia-Pacific governments, dissidents, automotive companies, and infrastructure operators with custom backdoors (KerrDown, Ratsnif, Cobalt Strike variants). The 2025-07 PyPI campaign represents a deliberate pivot to the open-source supply chain - APT32 had previously been observed using compromised websites and Skype/Telegram lures, not registry uploads.

## Timeline

- 2025-07-10 - earliest attacker activity observed (first malicious commit to staging repos, per ThreatLabz reconstruction)
- 2025-07-16 → 2025-07-22 - `uuid32-utils`, `colorinal`, `termncolor` uploaded to PyPI in three separate bursts
- 2025-08 - Zscaler ThreatLabz publishes the original detection; PyPI removes the packages, Zulip deactivates the C2 organisations
- 2026-05-08 - Kaspersky GReAT publishes the OceanLotus / APT32 re-attribution write-up with KTAE similarity analysis
- 2026-05 → 2026-06 - re-attribution amplified by The Hacker News, GBHackers, GridinSoft, daily.dev, MalwareTips, and others

No CVE / GHSA covers the wave - PyPI security removed the packages but no advisory was created at the time. The Kaspersky write-up and the original Zscaler post are the only structured references; we record the Kaspersky attribution date as `published` because that is when the campaign became a named, attributed disclosure. Exact published version numbers per package are not enumerated in the public sources beyond Safety DB's record of `uuid32-utils` reaching `1.0.4`; we list inferred initial-publish versions only, and a lockfile match on any version of these three names should be treated as compromise.

## Impact

- Cross-platform persistence: Windows persistence via `HKCU\Software\Microsoft\Windows\CurrentVersion\Run`, Linux persistence via a `crontab` entry that respawns the backdoor on every reboot
- DLL sideloading on Windows (`uuid32-utils` / `colorinal`) and ELF `.so` loading on Linux - both wheel families carry platform-matched droppers inside the bdist
- `ZiChatBot` Python backdoor connects to public Zulip REST APIs for command-and-control - perimeter detection that flags rare C2 hostnames will miss this because Zulip is allow-listed in many engineering environments
- Sleeper window: ~10 months between PyPI publication (2025-07) and public re-attribution (2026-05-08); any environment that pinned these names in a lockfile during the window has run the backdoor
- Termncolor is a benign wrapper that imports `colorinal` as a transitive dependency - a lockfile that only mentions `termncolor` still pulls and executes the malicious payload
- OceanLotus / APT32 targeting profile is Asia-Pacific governments, dissidents, and enterprises; Kaspersky scored the dropper at 64% similarity to known APT32 implants in their KTAE engine

## What to do

1. Grep every `requirements.txt`, `Pipfile.lock`, `poetry.lock`, and `pdm.lock` in scope for `uuid32-utils`, `colorinal`, or `termncolor` - all three were removed from PyPI but pinned lockfiles will still attempt to install them from caches / mirrors
2. Quarantine any developer workstation or CI runner that ran `pip install` against one of the three names between 2025-07-16 and 2026-05-08; assume full host compromise and re-image
3. On Windows, audit `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` for unexpected entries pointing into `%APPDATA%` or `%LOCALAPPDATA%`
4. On Linux, audit `crontab -l` (per-user) and `/etc/cron.d/`, `/etc/crontab` for unexpected jobs added during the dwell window
5. Egress hunt: outbound to `*.zulipchat.com` REST APIs from Python interpreters that should not be using Zulip - `ZiChatBot` is the only published example of Zulip-as-C2 to date
6. Rotate any credential reachable from a compromised host: SSH keys, cloud tokens (AWS / Azure / GCP), Git tokens, npm/PyPI publish tokens, and browser-stored session cookies

## Check your own dependencies

- Check a requirements.txt against this incident: https://dependencywatch.io/check/requirements-txt

The scan runs entirely in the browser; lockfile contents are never uploaded.

## References

- [OceanLotus suspected of distributing ZiChatBot malware via wheel packages in PyPI](https://securelist.com/oceanlotus-suspected-pypi-zichatbot-campaign/119603/) - Kaspersky Securelist
- [PyPI Packages Deliver ZiChatBot Malware via Zulip APIs on Windows and Linux](https://thehackernews.com/2026/05/pypi-packages-deliver-zichatbot-malware.html) - The Hacker News
- [New ZiChatBot Malware Uses Zulip REST APIs as Command and Control Server](https://cybersecuritynews.com/new-zichatbot-malware-uses-zulip-rest-apis/) - Cyber Security News
- [PyPI ZiChatBot Packages Linked to Suspected OceanLotus Campaign](https://gridinsoft.com/blogs/pypi-zichatbot-packages-oceanlotus/) - GridinSoft
- [ZiChatBot Malware Abuses Zulip APIs for Stealthy C2 Operations](https://gbhackers.com/zichatbot-malware-abuses-zulip/) - GBHackers
- [uuid32-utils - Safety DB version history](https://data.safetycli.com/packages/pypi/uuid32-utils/) - Safety CLI

---

Canonical page: https://dependencywatch.io/incident/pypi-2026-05-08-oceanlotus-zichatbot-zulip-c2
Markdown version: https://dependencywatch.io/incident/pypi-2026-05-08-oceanlotus-zichatbot-zulip-c2.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
