PyPI Supply Chain Attack Targets Pyrogram Bots
If you built a Telegram bot in Python recently, check your imports. A nasty supply chain campaign called Operation Navy Ghost has been quiet but active since last November. They aren't exploiting bugs in Pyrogram itself. Instead, they are counting on your typos, your haste, and your default trust in package managers.
Threat actors published at least eight malicious forks on PyPI mimicking the legitimate Pyrogram framework. The moment a developer pulls one of these tainted packages, the backdoor registers hidden listeners that wait for commands. Checkmarx discovered that the malware specifically targets production bot environments to secure high-value access. This means databases, cloud environments, and configuration files are ripe for the taking. It’s a clean compromise, and it runs under your app's authority.
Inside the Trojanized Pyrogram Catalog
Why target Pyrogram? Because it’s widely used despite being unmaintained. The official repository hasn't seen updates in a while, yet it still pulls about 350,000 monthly downloads. For attackers, that's a massive, unprotected user base.
Between November 2025 and June 2026, the threat actor uploaded several malicious forks under different accounts. Yet they all share identical backdoor code and Command and Control setup. Look out for these packages:
VLifeGram(nine versions, downloaded 4,150 times)VLife-Gram(five versions, 1,030 downloads)pyrogram-navy(six versions, 2,530 downloads)pyrogram-styled(over 16 versions, 15,370 downloads)pyrogram-zeeb(one version, 432 downloads)kelragram(three versions, 1,041 downloads)sepgram(one version, 264 downloads)pyrogram-kelra(one version, 672 downloads)
These packages aren't empty shells. They run the full Pyrogram codebase, so your bot will work perfectly fine. But they include an extra file called secret.py in the helpers directory. That's the trap.
Checkmarx attributes these malicious packages to a single threat actor. The proof lies in the details: the identical backdoor code, the shared list of OWNERS Telegram IDs, the exact same command names, and overlapping hosting infrastructure. Despite being uploaded from different PyPI accounts, they all funnel control to the same group. Typosquatting is a persistent threat on PyPI. It's too easy for a developer to search for 'pyrogram' and accidentally pick the wrong option, especially when some of these forks have names like pyrogram-styled or VLifeGram that sound plausible. pyrogram-styled alone was pulled over 15,000 times. That is a lot of compromised servers. This exploitation of trust through spoofed naming and page styling shares tactics with crypto reputation hijacking attacks, which abuse platforms like GitHub and YouTube to mislead developers into downloading malicious assets.
Sneaking In via the Helpers Module
The backdoor gets in without raising eyebrows. When your application loads Pyrogram, it naturally imports helper modules. This execution triggers the hidden secret.py, registering command handlers in the background.
It does this silently. Errors are caught and suppressed, logging is disabled, and the bot functions normally otherwise. If you test your bot locally, you won't see anything wrong.
But the malware checks if the client is running on a bot account. The attacker doesn't care about normal user accounts. Production bots are where the goodies are. They run on remote servers, have access to configuration variables, database connections, and API keys.
The target selection mechanism here is clever. Most malware tries to run everywhere. Here, the backdoor checks me.is_bot. If the user is running as a userbot (a personal account automated via the MTProto API), the script shuts up and doesn't register the handlers. The actors know that personal account setups are noisy and get banned by Telegram quickly. Production bots, however, run inside Docker containers on AWS, DigitalOcean, or private VPS hosts. They run forever, they have system secrets in memory, and they usually operate with elevated system privileges. By staying silent on user accounts and activating only on bot accounts, the malware avoids detection while maximizing the value of the targets it hits.
To prevent random users or security researchers from running commands on their newly acquired bots, the backdoor relies on a hardcoded list of Telegram user IDs called OWNERS. If a command comes from any other account, the bot ignores it. It looks like a normal bot to everyone except the threat actor, who holds the keys.
Remote Code Execution via Telegram Command Handlers
Once the backdoor is running, control is absolute. The attacker doesn’t need a complex dashboard. They just send normal Telegram messages to the bot using two custom commands: /asu and /asi.
If they send /asu, the bot compiles and runs the Python code they send. Send /asu print(os.environ) and the bot prints every environment variable, cloud credential, and database URL right back to their chat.
If they want a command line shell, they use /asi. The bot executes it via /bin/bash -c. A command like /asi cat /etc/passwd reads files on the server instantly. This use of a hidden Python payload to gain full system access is a key feature in other recent threats, such as the Edgecution sandbox escape which similarly deploys a Python-based backdoor.
Since Telegram messages are capped at 4,096 bytes, the backdoor has a built-in overflow handling mechanism. If the output of a command is too large, it writes the result to a temporary file on the host, uploads it to the Telegram chat as a document attachment, and then continues. This completely bypasses standard network egress alerts because it looks like normal bot-to-user document transfers.
Remediation and Securing the Bot Pipeline
If your bot uses Pyrogram, review your codebase now. Don't assume you installed the correct one.
First, check your container images and dependency lists for any of the eight blacklisted packages. If you find one, kill the server immediately.
Second, assume every credential on that server is burned. Rotate your Telegram bot token, change database passwords, cycle API keys, and swap AWS secret configurations. Just rebuilding the server with the correct package isn't enough.
Third, audit how you manage external libraries. In python, blind dependency installation is a recipe for disaster. Pin your packages with hashes. Don't grab random forks from PyPI just because the original package isn't updated. Check the source repository directly on GitHub and build from source if you have to. If you are not verifying your libraries, someone else will.