MagicWolf - Six Weeks of Evolving PyPI Supply Chain Attacks
By Paul McCarty
Over the past six weeks, a single threat actor has orchestrated a sustained supply chain attack against the Python Package Index (PyPI), publishing at least 28 malicious package versions under six different package names. What makes this campaign particularly noteworthy isn't just its scale, but the rapid evolution of techniques we've observed as the attacker learned from mistakes and adapted to detection efforts.
This is the story of how one threat actor went from clumsy first attempts to building sophisticated analyst evasion into their malware — all while leaving a trail of operational security failures that reveal their methods and mindset.
The Big Picture
Between early January and mid-February 2026, a single threat actor published malicious Python packages targeting developers on PyPI under these names:


All 28 packages share common infrastructure, code patterns, and a unique fingerprint that ties them together: every single version contains an identical URL hash for macOS payloads. This shared DNA allowed us to track the campaign's evolution across package name changes and version bumps.
The attack flow is straightforward but effective: victims install what appears to be a legitimate Python package via pip install, and the installation automatically triggers a multi-stage dropper that downloads and executes malware. Windows users receive a PyInstaller-packed executable (likely an infostealer or remote access trojan), while macOS users are targeted with shell scripts that download similar payloads.
Stage 1: The Learning Curve (magichat 0.1.0 - 1.0.2)
The campaign began with magichat 0.1.0 in early January 2026. This first version was remarkably simple — just 787 bytes of Python code with a single function that downloaded a file disguised as a Python installer (python-3.14.3-amd64.exe) from Dropbox and displayed a fake success message: "Successfully installed AI Assistant."
The early versions reveal an attacker still learning the craft:
Versions 1.0.1 and 1.0.2 remained equally basic. The threat actor was testing the waters, learning how PyPI packaging worked, and seeing if anyone would notice.
Stage 2: Adding Sophistication (magichat 1.0.3 - 1.0.7)
By version 1.0.3, the attacker began experimenting with different payload delivery methods. We saw rapid iteration:
DocSend.application (Microsoft ClickOnce)TLSWebDriver.exeInstaller.exe as the stable payload nameThis experimentation phase shows the attacker testing which payload names would evoke the least suspicion and determining which hosting infrastructure worked reliably.
Stage 3: Professional Tradecraft (magichat 1.0.8 - 1.1.2)
Version 1.0.8 marked a significant maturation. The attacker added:
The code jumped from amateur to semi-professional. Someone had done their homework — studying Windows security mechanisms, learning about NTFS alternate data streams, and understanding how to use Python's ctypes library to call Windows APIs directly.
Interestingly, versions 1.0.9, 1.1.0, and 1.1.1 are byte-for-byte identical. The attacker was publishing identical code under new version numbers, possibly to evade version-based detections or simply as publishing experiments.
Stage 4: Infrastructure Changes (magicwolf 1.1.8 - 1.2.1)
In late January, the attacker rebranded to magicwolf and made significant infrastructure changes:
45.150.34.209The Telegram integration is particularly clever. By using Telegram's legitimate Bot API, the attacker could receive real-time notifications when victims installed the malicious package — all while blending in with normal Telegram traffic and avoiding the need to maintain their own C2 server.
The base64 encoding was primitive (easily decoded), but it's effective against basic static analysis tools that scan for plaintext URLs.
Stage 5: Diversification and Social Engineering (clawdest 1.1.2 - 1.1.7)
Next came clawdest, introducing new infrastructure at updatedappython.com and more sophisticated social engineering:
Installer2.exewinrar-x64-713.exe)The social engineering shows strategic thinking. TLauncher and WinRAR are widely used tools that users are accustomed to downloading and installing. By naming payloads after these legitimate applications, the attacker increased the chance victims would click through security warnings.
Stage 6: Analyst Evasion (clawdist, polyclawd, polyutil)
The most recent evolution came in mid-February 2026 with clawdist, polyclawd, and polyutil. These packages introduced a game-changing capability: automatic detection and evasion of analyst environments.
The new code checks for three indicators before executing:
SSH_CONNECTION, SSH_TTY, and SSH_CLIENT environment variablesIf any of these conditions are detected, the malware silently aborts without executing its malicious payload.
This is a direct response to security researchers. Most malware analysts examine suspicious packages by installing them in virtual machines accessed via SSH or RDP. By detecting these remote session indicators, the attacker ensures that analysts see nothing malicious — the package appears to install cleanly and do nothing.
polyutil also introduced a new social engineering angle, targeting the Polymarket prediction market community with its package description. The author name changed to "John Lover" with the email johnlover@gmail.com — the first non-placeholder email in the entire campaign and a potential attribution lead.
The Multi-Stage Attack Chain
Across all versions, the attack follows a similar pattern once the initial Python package is installed:
Stage 1: Python dropper installed via pip
↓
Stage 2: Downloads a VBScript file to %LocalAppData%\\\\vhost.vbs
↓
Stage 3: VBScript spawns hidden PowerShell to download the final payload
↓
Stage 4: Windows executable (PyInstaller-packed, ~11MB) runs with persistence
Each stage adds separation between the initial infection vector and the final payload, making it harder to analyze and harder to attribute.
Malware Analysis
Windows Payload: update.exe
File Characteristics: - Size: 11,289,384 bytes (11 MB) - Type: PE32+ executable (console) x86-64, for MS Windows - Sections: 6 sections - Packer: PyInstaller (Python 3.9)
Cryptographic Hashes:
MD5: dc6e2daa0e78e7431b1d39f0545996eb
SHA256: 6410ef206329a97e33181eef9a1c3dfda1e6cdc2848ead59ba4af1b8de92809f
Download Behavior (script.py:11-26): 1. HTTP GET request to `http://45.150.34.209/api/` 2. Streams download in 8KB chunks 3. Saves to `%LOCALAPPDATA%\update.exe` 4. Removes Zone.Identifier NTFS alternate data stream 5. Executes payload via `os.startfile()`
OPSEC Failures: How the Attacker Exposed Themselves
Despite the increasing sophistication, the threat actor made numerous mistakes that reveal their identity and methods:
1. Copy-Paste Errors
magicwolf and clawdist packages reference the wrong module in their entry points — they call clawdest.script:run instead of their own module names. This reveals the attacker copied and pasted code between packages without carefully updating references.
Even more damning: clawdest version 1.1.2 contains an internal module directory named magichat instead of clawdest. The attacker literally forgot to rename the directory when forking the code.
2. Evolving Author Names
The author attribution evolved over time:
your_nicknameJames DawnJames DawnJames BondJames BondJohn LoverThe progression from placeholder (your_nickname) to generic fake names suggests growing awareness of the need for plausible attribution metadata. But the use of "James Bond" — a name so obviously fake it seems like a joke — undermines the attempt at legitimacy.
3. Placeholder Metadata Everywhere
Nearly every package uses:
example@gmail.comexample pythonrequests>=2.25.1>=3.7 (outdated for 2026)This template-based approach screams "auto-generated" and makes the packages easy to fingerprint.
4. The Grammar Tell
Every package since clawdest includes the description: "Package to working [name]" or "Package to [name]" — grammatically incorrect English suggesting a non-native speaker. This phrasal pattern is unique enough to be a fingerprint.
5. The Universal Fingerprint
Every single package in the campaign — all 28 versions — contains the exact same macOS payload URL:
<http://myghibligenerator.com/curl/bb4b22014136fa4bd8b47449b7d6032780033e7cbfb104c1f7f61214c602987c>
This URL never changed across six weeks and six package names. It's a smoking gun that ties the entire campaign to a single actor. The attacker never bothered to regenerate this URL or change the hash, making it trivially easy to identify all related packages.
6. Consistent Timestamps
Most package uploads occurred between 1-2 AM in a consistent timezone, suggesting the attacker operates in a specific geographic region and works late at night.
7. Bug Recycling
Many packages contained a bug where error handlers called return run() when the actual function was named init(). This bug was copy-pasted across multiple package families before being fixed in polyclawd/polyutil. It shows the attacker wasn't testing their code thoroughly before publishing.
The Infrastructure
The campaign uses a consistent set of infrastructure:
7531315855:AAG6UjCVvxlrAhzQd9bSnz7DwlxtmPcEgM0)The shift from Dropbox to self-hosted infrastructure suggests the attacker was either experiencing Dropbox rate-limiting or wanted more control over payload delivery.
What We Learned
This campaign demonstrates several important trends in supply chain attacks:
1. Rapid Iteration and Learning
The attacker improved significantly over six weeks. From basic downloaders to analyst-evading malware shows someone actively learning, experimenting, and adapting based on what works. You can see in the magichat package how quickly the threat actor was iterating:

2. Living Off the Land
By using PyPI as the initial infection vector, Telegram for C2 notifications, and PowerShell for payload downloads, the attacker leverages legitimate infrastructure at every stage. This makes blocking difficult — you can't simply block "malicious" infrastructure when it's GitHub, Telegram, and PyPI.
3. The Cat-and-Mouse Game
The addition of SSH/RDP detection shows the attacker is aware of analyst workflows and is actively working to evade analysis. This arms race between attackers and defenders is accelerating.
4. Low Barriers to Entry
The initial versions were extremely unsophisticated. This shows that launching a supply chain attack against PyPI doesn't require advanced skills — basic Python knowledge and a willingness to experiment is enough to get started.
5. OPSEC is Hard
Despite improving technical capabilities, the attacker made basic operational security mistakes that exposed the entire campaign. The universal macOS URL hash alone was enough to link all 28 packages together.
Recommendations
For Developers
pip show magicwolf magichat clawdest clawdist polyclawd polyutil to check if you've installed any campaign packagespip-audit or safety to scan for known malicious packagesFor PyPI and Package Registry Operators
For Security Researchers
Timeline Summary
DatePackage FamilyVersionsKey ChangesEarly Jan 2026magichat0.1.0 - 1.0.2Initial basic dropper, Dropbox hostingMid Jan 2026magichat1.0.3 - 1.0.7Payload experimentation, social engineeringLate Jan 2026magichat1.0.8 - 1.1.2Platform detection, UAC bypass, SmartScreen bypassLate Jan 2026magicwolf1.1.8 - 1.2.1Infrastructure move, Telegram C2, base64 obfuscationEarly Feb 2026clawdest1.1.2 - 1.1.7New C2 domain, TLauncher/WinRAR impersonationMid Feb 2026clawdist1.2.5 - 1.2.6VBScript dropper introducedMid Feb 2026polyclawd, polyutil1.1.0, 1.0.0SSH/RDP detection, Polymarket targeting
Indicators of Compromise (IOCs)
If you need to check your environment for signs of compromise, here are all the IOCs from this campaign:
PyPI Packages (Remove Immediately)
Package Name Versions Status magichat 0.1.0, 1.0.1, 1.0.2, 1.0.3, 1.0.4, 1.0.5, 1.0.6, 1.0.7, 1.0.8, 1.0.9, 1.1.0, 1.1.1, 1.1.2 MALICIOUS magicwolf 1.1.8, 1.1.9, 1.2.0, 1.2.1 MALICIOUS clawdest 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.1.7 MALICIOUS clawdist 1.2.5, 1.2.6 MALICIOUS polyclawd 1.1.0 MALICIOUS polyutil 1.0.0 MALICIOUS
Indicators of Compromise (IOC)
IP Addresses:
45.150.34.209 — Payload hosting server (VBS and Windows EXE files)Domains:
updatedappython.com — C2 server and payload distributionmyghibligenerator.com — macOS payload hosting (currently non-resolving)URLs:
http://45.150.34.209/api/ — Windows EXE payload (early magicwolf versions)http://45.150.34.209/vbs/ — VBScript dropper hostinghttps://updatedappython.com/api/rest.php — Infection telemetry beacon endpointhttps://updatedappython.com/Installer.exe — Final Windows payloadhttps://updatedappython.com/Installer2.exe — Alternate Windows payloadhttps://updatedappython.com/Inst.exe — Latest Windows payloadhttp://myghibligenerator.com/curl/bb4b22014136fa4bd8b47449b7d6032780033e7cbfb104c1f7f61214c602987c — macOS payload (universal fingerprint)Telegram Bot Token:
7531315855:AAG6UjCVvxlrAhzQd9bSnz7DwlxtmPcEgM0 (magicwolf versions)Telegram Chat ID:
7101034380 (magicwolf versions)File System Indicators
Windows Dropped Files:
%LocalAppData%\\\\update.exe — Final payload executable%LocalAppData%\\\\vhost.vbs — VBScript second-stage dropper%LocalAppData%\\\\Installer.exe — Alternate payload name%LocalAppData%\\\\Installer2.exe — Alternate payload name%LocalAppData%\\\\python-3.14.3-amd64.exe — Early payload disguised as Python installer%LocalAppData%\\\\DocSend.application — Early ClickOnce payload%LocalAppData%\\\\TLSWebDriver.exe — Early payload%LocalAppData%\\\\winrar-x64-713.exe — WinRAR impersonation payloadFile Hashes
vhost.vbs (VBScript dropper):
b648c8adf5d8266cac814c9246fc9ec1fb37c9500c852716d4e534c1bb2d91bcafa19ad47f0e7dad2300dbadcba44eacupdate.exe (Windows final payload, from 45.150.34.209):
dc6e2daa0e78e7431b1d39f0545996eb6410ef206329a97e33181eef9a1c3dfda1e6cdc2848ead59ba4af1b8de92809fpolyclawd/polyutil script.py (latest Python dropper):
732acaf8ea07ae079da61fa14764ac0cbe666a2f6f7ccb4f0010b3e18d1d59bfccc41a6ebf7680abb6a53e334bebc1d3
Conclusion
The Magic Wolf campaign is a textbook example of how modern supply chain attacks evolve. We've watched a single threat actor go from publishing a 787-byte Python script to deploying multi-stage, analyst-evading malware — all in just six weeks.
What's most concerning isn't the sophistication of the final versions, but the ease with which the attacker was able to publish 28 malicious packages to PyPI over an extended period. Despite numerous OPSEC failures, obvious metadata issues, and a universal fingerprint present in every version, the packages remained available for download.
This campaign serves as a wake-up call for the open-source ecosystem. Supply chain attacks are no longer theoretical risks — they're active, evolving, and getting more sophisticated by the week. The barriers to entry are low, the potential impact is high, and the current defenses are insufficient.
The good news is that this attacker made mistakes. Many mistakes. The universal macOS hash, the copy-paste errors, the placeholder metadata — all of these made detection and attribution possible. But as attackers learn and improve, future campaigns may not be so careless.
The race is on between those who would exploit open-source trust and those working to defend it. Understanding campaigns like Magic Wolf is the first step in staying ahead.
How can Safety help protect you from these attacks?
Traditional vulnerability scanning happens too late - after potentially malicious code is already in your system. Which means that ASPM and EDR solutions don't protect you from this type of threat.
But all is not lost, as the Safety Firewall protects develoeprs and CI pipelines proactively. Every package installation request is analyzed before reaching public repositories. Malicious, vulnerable, and policy-violating packages are automatically blocked before they can enter your systems, preventing rather than just detecting threats.
You can sign up for a free Safety account and try the Safety Firewall HERE.
Feel free to reach out to me with any questions!
Let us know if this blog post helped you
I hope this blog post has helped you. Feel free to hit me up directly if you have any questions about this campaign.
Paul McCarty - Head of Research, Safety
You can find me on LinkedIn and BlueSky.