ZiChatBot malware abuses Zulip APIs after hiding in PyPI packages


A newly documented malware campaign used fake Python packages on PyPI to deliver ZiChatBot, a cross-platform backdoor that targets Windows and Linux systems. The malware stands out because it uses Zulip’s public REST APIs as its command channel instead of relying on a traditional attacker-controlled server.

Kaspersky researchers found that the malicious packages were uploaded to PyPI in July 2025 and later removed. The packages looked like normal developer utilities, but they quietly dropped native malware components when developers installed and imported them.

The campaign has been linked with possible OceanLotus activity based on code similarity and threat intelligence analysis. OceanLotus, also known as APT32, has a long history of targeted operations, and this campaign shows how public package repositories remain attractive for supply chain attacks.

How ZiChatBot reached developers

The attackers created three PyPI projects named uuid32-utils, colorinal, and termncolor. Each appeared to offer harmless developer functionality, such as UUID generation or terminal color support.

The uuid32-utils and colorinal packages carried malicious wheel files for Windows and Linux. The termncolor package used a more indirect method by listing colorinal as a dependency, which helped it look cleaner during a quick review.

Once the malicious package was imported in a Python project, its hidden code loaded a native dropper into the host Python process. That dropper then deployed ZiChatBot and removed some infection traces.

At a glance

DetailInformation
Malware nameZiChatBot
Delivery methodMalicious PyPI wheel packages
Packages involveduuid32-utils, colorinal, and termncolor
Target platformsWindows and Linux
Command channelZulip public REST APIs
Windows payloadlibcef.dll loaded through vcpktsvr.exe
Linux payload path/tmp/obsHub/obs-check-update
Known Zulip endpointhelper.zulipchat.com

Why the Zulip abuse matters

ZiChatBot does not use a normal malware command-and-control server. Instead, it sends and receives commands through Zulip, a legitimate team chat platform used for messaging and collaboration.

This makes network detection harder. Security tools may see traffic going to a trusted communication service, rather than a suspicious domain or unfamiliar IP address.

The code loads the dropper into the host Python process (Source – Securelist)

Kaspersky found that ZiChatBot used two channel and topic pairs inside the attacker-controlled Zulip organization. One channel handled basic system information from infected machines, while another delivered shellcode that the malware executed in a new thread.

How the Windows version works

On Windows, the malicious package drops terminate.dll. When the library gets imported, the dropper runs inside the Python process and decrypts embedded data.

The malware then extracts vcpktsvr.exe and libcef.dll into a local application data folder. The legitimate-looking executable loads the malicious DLL, which gives ZiChatBot a way to run while blending into normal file activity.

The dropper also creates a registry auto-run entry so the malware starts again when the user logs in. After deployment, it runs shellcode designed to remove the original dropper and related malicious script files.

How the Linux version works

The Linux version follows a similar idea but uses a shared object file named terminate.so. It installs the payload under /tmp/obsHub/obs-check-update.

For persistence, the Linux payload creates a crontab entry. That gives the attacker a way to keep the malware active after reboot or session changes.

The cross-platform design increases the campaign’s reach because Python developers often work across Windows, Linux, virtual machines, containers, and build servers.

What makes the attack deceptive

  • The packages had normal-looking names and descriptions.
  • The packages performed some of the advertised functions.
  • The malicious behavior started during import, not just installation.
  • termncolor looked cleaner because it depended on another malicious package.
  • The dropper used AES-CBC encryption to hide strings and embedded payloads.
  • The malware removed some files after deployment to reduce evidence.
  • Zulip API traffic helped the command channel blend with legitimate web traffic.

Why developers should pay attention

PyPI attacks are dangerous because developers often install packages quickly during testing, automation, or prototyping. A package with a useful name can reach workstations, CI environments, internal tools, and production-adjacent systems.

ZiChatBot also shows why package behavior matters more than package descriptions. A package can provide its advertised feature and still perform malicious actions in the background.

Security teams should treat developer endpoints as high-value targets. These machines often contain source code, credentials, API tokens, SSH keys, cloud access, and internal documentation.

  • Remove uuid32-utils, colorinal, and termncolor from any environment where they were installed.
  • Check package lock files, dependency files, build logs, and CI job history for these package names.
  • Hunt for libcef.dll, vcpktsvr.exe, terminate.dll, terminate.so, Backward.dll, and Backward.so.
  • Inspect Windows registry auto-run entries for suspicious persistence.
  • Inspect Linux crontab entries for /tmp/obsHub/obs-check-update.
  • Block or monitor traffic to helper.zulipchat.com if your organization does not use it.
  • Review outbound Zulip API traffic from systems that should not use Zulip.
  • Rotate credentials, API tokens, and SSH keys used on affected systems.
  • Use virtual environments and dependency pinning for Python projects.
  • Scan packages before installing them into developer or production workflows.

The bigger risk for open-source users

This campaign shows how attackers can use public repositories to reach developers across many organizations at once. They do not need to breach each company directly if they can convince developers to install poisoned code.

The use of Zulip APIs also reflects a broader attacker trend. Malware operators increasingly abuse trusted cloud, collaboration, and developer platforms because those services often pass through security controls.

For defenders, the right response combines package hygiene, behavior monitoring, network inspection, and credential rotation. Blocking known indicators helps, but it cannot replace careful review of what installed code does at runtime.

Summary

  • ZiChatBot was delivered through malicious PyPI packages named uuid32-utils, colorinal, and termncolor.
  • The malware targets both Windows and Linux systems.
  • It uses Zulip REST APIs as a command channel instead of a normal C2 server.
  • The Windows version uses libcef.dll and vcpktsvr.exe, while the Linux version uses /tmp/obsHub/obs-check-update.
  • Developers and security teams should remove the packages, hunt for persistence, and rotate credentials from affected systems.

FAQ

What is ZiChatBot?

ZiChatBot is a backdoor delivered through malicious PyPI packages. It can run on Windows and Linux and uses Zulip REST APIs to receive commands.

Does this affect Windows and Linux?

Yes. Kaspersky found Windows and Linux versions of the malicious wheel packages, with different payload files and persistence methods for each platform.

Why does ZiChatBot use Zulip?

ZiChatBot uses Zulip because traffic to a legitimate chat service can look less suspicious than traffic to a private command-and-control server.

Which PyPI packages delivered ZiChatBot?

The known package names are uuid32-utils, colorinal, and termncolor. The first two directly carried malicious components, while termncolor pulled in colorinal as a dependency.

Readers help support VPNCentral. We may get a commission if you buy through our links. Tooltip Icon

Read our disclosure page to find out how can you help VPNCentral sustain the editorial team Read more

User forum

0 messages