Skip to content

Back to the catalog

Malicious 'Pyronut' Package Backdoors Telegram Bots with Remote Code Execution | Blog | Endor Labs
endorlabs.comwriteup

Malicious 'Pyronut' Package Backdoors Telegram Bots with Remote Code Execution | Blog | Endor Labs

Endor Labs analyzes the malicious PyPI package pyronut (versions 2.0.184–2.0.186), a trojanized fork of the Telegram framework pyrogram. It hooks Client.start() to import a hidden pyrogram/helpers/secret.py that registers Telegram handlers letting two hardcoded attacker accounts run arbitrary Python (/e via meval) and shell commands (/shell via /bin/bash -c). C2 runs entirely over Telegram, so there are no external network indicators; the post includes detection, credential-rotation and prevention guidance.

TL;DR Malicious pyrogram fork 'pyronut' on PyPI backdoors Telegram bots at runtime, giving two attacker accounts Python and shell RCE over Telegram itself.
Document

What it is

pyronut is a malicious PyPI fork of the Telegram MTProto framework pyrogram (about 370,000 monthly downloads). Only three versions were ever published: 2.0.184, 2.0.185 and 2.0.186. All are malicious, and all were published, identified and quarantined on 2026-03-18. The author copied pyrogram's project description verbatim and listed a GitHub URL that does not resolve. Endor Labs reads this as a trojanized fork promoted through Telegram groups, forums or tutorials, not as typosquatting.

How it works

Nothing runs at install time, so there is no setup.py hook to catch. The trigger is a modified Client.start() in pyrogram/methods/utilities/start.py (a file the page says is absent from upstream pyrogram). After get_me(), it imports pyrogram.helpers.secret and calls secret.init_secret(self) inside a bare try/except: pass, so failures are silent.

init_secret() returns early if client.me.id is in OWNERS = [1905813501, 8020909936]. Otherwise it registers two hidden message handlers, restricted to those two user IDs and filtered with ~forwarded and ~via_bot:

  • /e <code> evaluates Python in the running client process via meval. It exposes the pyrogram.Client as c, plus the message, the raw API layer and others. The attacker can read messages and contacts, send as the victim, and call any raw Telegram API method.
  • /shell <cmd> runs ["/bin/bash", "-c", cmd] through subprocess.run, with the privileges of the Python process.

Command and control runs entirely over Telegram. Output goes back to the same chat, as a file attachment if it exceeds 4096 characters. The attacker can message the victim's bot directly, or any group the bot or userbot is in.

flowchart LR
    A[Attacker account] -->|"/e or /shell"| T[Telegram]
    T --> B[Victim bot or userbot]
    B -->|OWNERS check passes| X[meval or bash -c]
    X -->|output as reply| T

Preconditions / Affected

  • pyronut 2.0.184, 2.0.185 or 2.0.186 is installed and a Telegram client has been started (Client.start() ran).
  • The attacker can reach the bot, by direct message or through a shared group.
  • Exposure is bounded by the hours-long availability window. The page rates exploitation likelihood as relatively low, since the attacker must actively trigger the payload.

What to do

  1. Search requirements.txt, Pipfile, pyproject.toml and setup.py for pyronut (the three versions above). Also look for an unexpected meval in the environment, since pyronut pulls it in as a dependency.
  2. If found, terminate all active Telegram sessions and revoke any Bot API tokens the process could access.
  3. Rotate everything reachable by the process: environment variables, API keys, SSH keys and database passwords. The page says to assume all of them are compromised.
  4. Uninstall the package and rebuild the virtualenv from a known-good state, rather than patching in place.
  5. Hunt in EDR and system logs for /bin/bash -c <command> child processes spawned by Python. Also review the bot's Telegram message history for /e and /shell messages from the two IDs above.
  6. For prevention, use lockfiles with hashes, run SCA in CI, apply least privilege and egress limits, and diff any fork against upstream before adopting it. Red flags here were a dead repository URL and a copied description with no changelog.

Caveats

  • There are no network IOCs, because there is no external C2 domain. Detection depends on process and log artifacts, or on what the attacker runs.
  • /e activity, such as silently reading Telegram messages, may leave no child processes or network signs. Absence of /bin/bash children is therefore not proof of safety.
  • The distribution channel is inferred by Endor Labs, not observed.

Organisations named here

  • malicious fork
  • meval
  • pyrogram
  • pyronut
  • runtime backdoor
  • T1195.002

Technologies named here

  • pyronut versions 2.0.184, 2.0.185, 2.0.186
  • Telegram bots and userbots built on pyronut
  • meval library
  • Host systems running the Python process
  • Runtime monitoring tools – detect anomalous behavior
  • PyPI
  • Python
  • Telegram
  • Endor Labs

Techniques named here

  • Error suppression with bare try/except
  • Self-exclusion logic
  • Post-exploitation potential
  • Remote code execution

Threat actors named here

  • pyronut malicious package campaign
  • Backdoor module pyrogram/helpers/secret.py