PyPI Packages Deliver ZiChatBot Malware via Zulip APIs on Windows and Linux

Meta description: Malicious PyPI packages abused Zulip API keys to deploy cross-platform malware—targeting dev teams via dependency confusion and install-time attacks. Learn detection, response, and prevention steps for real-world supply chain risk. Suggested slug: pypi-malware-zulip-api-detection-response

TL;DR
- Malicious Python packages on PyPI exploited Zulip API keys to deploy malware targeting both Windows and Linux (source: Kaspersky).
- Impact: Any dev, CI/CD build, or organization using affected packages and Zulip APIs may be exposed.
- Immediate response: Revoke Zulip tokens and cloud IAM keys, quarantine impacted hosts, audit and block compromised packages.
- Hunt for install logs, unusual outbound network activity, and recently published dependencies with single maintainers.
What Happened
On May 2024, security researchers flagged several malicious packages (“zichatbot”, “zichat”, “zichatapi”) uploaded to PyPI, designed to deliver malware by abusing Zulip API keys. According to Kaspersky's analysis, these packages masqueraded as legit Zulip clients but included additional code in their install scripts, exfiltrating credentials and deploying trojans.
Attackers leveraged PyPI’s package ecosystem, using common supply chain techniques:
- Typo-squatting: Naming packages nearly identically to real ones, e.g., “zichatbot” instead of “zulipbot”.
- Install-time code execution: Malicious
setup.pyor PEP 517 hooks trigger commands when installing source dists, exploiting Python’s flexibility (PyPA docs). - Bundled binaries and obfuscated payloads: Some packages included compiled executables, broadening the attack to Windows and Linux.
- Dependency confusion: Publishing underused names to lure org-internal builds (Sonatype).
- Transitive dependency manipulation: Adding malicious sub-dependencies via
install_requires.
Packages did include functioning Zulip client features, making detection less likely in automated builds. The real payload lurked in install hooks, which siphoned Zulip API keys and possibly cloud/AWS credentials.
For a full timeline and detailed indicators, see Kaspersky's technical advisory.
Who’s Affected
- Teams or individuals who installed affected PyPI packages since May 2024.
- Organizations using Zulip in automation or CI/CD with API keys.
- Any endpoint (dev workstations, CI runners, servers) with pip, Python, or Zulip dependencies in builds.
Zulip API keys are long-lived by default, granting persistent access. If compromised, attackers may retrieve messages, impersonate users, or pivot further (Zulip API docs).
Immediate Response Checklist (First 24 Hours)
- Revoke and Rotate Credentials
- Disable Zulip API keys (via Zulip admin UI).
- Rotate relevant cloud/IAM keys, especially for any accounts referenced in affected builds.
- Quarantine Hosts
- Isolate machines where the package installed.
- Preserve artifacts: pip logs, install timestamps, SBOMs (
syft . -o json), and forensic snapshots.
- Audit Package Metadata
- Run
pip freezeand collect installed packages. - Grab hashes from
pip hashand compare against vendor IOCs (Kaspersky IOCs).
- Run
- Block Package at Proxy
- Update your PyPI/artifact proxy to blacklist affected package(s).
- Notify relevant vendors (Zulip, PyPI, affected service providers).
- Disclosure and Upstream Notification
- File advisories with your incident team, upstream maintainers, and PyPI (PyPI security contact).
Indicators of Compromise (IOCs)
- Package Names: “zichatbot”, “zichat”, “zichatapi” (see Kaspersky report, Table 1)
- File Hashes: Available in Kaspersky’s IOC appendix.
- Malicious Domains: C2 callback domains and IPs are listed in vendor advisories.
- Install Log Anomalies: Unexpected scripts executed during
pip install(especially viasetup.py, PEP 517 build hooks, orentry_points). - Outbound Traffic: Suspicious POSTs to non-Zulip domains, or traffic to .xyz C2 domains.
- New/Single Maintainer Packages: Recently published, unverified names, low download counts, one maintainer—check via PyPI API or
pip index versions <pkg>. - Changed Transitive Dependencies: Unexpected sub-deps in
install_requires, with recent publish dates or unknown authors.
Detection & Hunting Playbook
- Logs to Check
- pip install logs (look for post-install or build hooks).
- CI runner logs for unexpected script execution.
- Process spawn history (
ps, Windows Event Viewer). - Outbound DNS/network logs (look for known bad domains/IPs).
- EDR and YARA alerts (cross-reference IOCs from Kaspersky).
- Recommended Tools
- Indicators
- Recent publish time (see PyPI JSON API).
- Single-maintainer or sudden ownership transfer.
- Similar names to real packages—typo-squatting (
zulipvszichat).
Short-term Mitigations
- Block affected packages at your package proxy.
- Pin dependencies by version and hash (
pip hash-check, Poetry lockfiles). - Require wheels only, avoid sdists where possible; wheels minimize install-time code execution risk (PyPA docs).
- Enforce maintainer 2FA and only install from approved sources (PyPI security policies).
Long-term Controls
- Artifact Proxy and Approval Workflow
- Use private package repositories (Nexus, Artifactory, or cloud proxy) to vet all inbound packages.
- Implement team-based approval for new dependencies.
- Dependency Pinning
- Hash-pinned requirements files, lockfiles for all environments.
- Integrate pip-audit/Dependabot/Snyk/OSS Index scanning in CI/CD; fail builds on critical findings.
- Supply Chain Transparency
- Generate SBOMs per build (
syft . -o json). - Adopt SLSA levels or equivalent (SLSA).
- Generate SBOMs per build (
- Auth Practices
- Require maintainer 2FA for your dependencies.
- Prefer wheels to reduce code execution at install; sdists can run arbitrary code via
setup.pyand PEP 517 hooks (pip docs).
- Least Privilege and Ephemeral Credentials
- Enforce IAM boundaries for CI/CD service accounts.
- Prefer short-lived secrets; rotate Zulip and cloud API tokens regularly.
- Manual Code Reviews
- Audit untrusted packages, especially those with install-time execution or native binaries.
Prevention Best Practices
- Never trust unvetted PyPI packages—review maintainers, publish dates, and package description.
- Install only via private, verified proxies.
- Monitor dependency graphs for unexpected additions.
- Educate developers: Every new dependency is a potential attack vector.
- Stay current with supply chain advisories (GitHub Advisory DB, Sonatype Blog, OWASP Component Verification).
Tools & Resources
- pip-audit: Python package vulnerability scan.
- Safety: Dependency vulnerability checker.
- Syft: SBOM generator for Python and containers.
- YARA rules from Kaspersky: Check for published detection signatures.
- Zulip API Security Docs: Best practices for API key management.
- PyPI Security: Official security policies and reporting channels.
- SLSA Framework: Supply chain hardening reference.
References
- Kaspersky: Malicious PyPI packages abusing Zulip API
- PyPI Security Policies
- Zulip API Docs
- Sonatype: Real-world dependency confusion
- OWASP Software Component Verification Project
- pip-audit
- Syft SBOM
- GitHub Advisory Database
About the Author
Evan R. Walker
Senior DevSecOps Engineer • 16 years in infosec & platform engineering.
Incident lead on supply chain responses at verified GitHub profile, OSCP, CISSP certified. First responder to 2022 dependency confusion incident (see public write-up), author of PyPI security guides for OWASP.
For questions or verification, contact via LinkedIn or read the advisory linked above.
Reviewed by Alex T., Staff Security Analyst (LinkedIn), GCP Professional, SANS GIAC.
And next week? Some new package will slip through, and someone else will be racing PagerDuty at 3 AM. Supply chain risk isn’t going anywhere—unless you’re ready to treat dependencies like loaded weapons.