Extracting Config from Agent Tesla RAT
Overview
Agent Tesla is a .NET-based Remote Access Trojan (RAT) and keylogger that ranked among the top 10 malware variants in 2024, impacting 6.3% of corporate networks globally. It exfiltrates stolen credentials via SMTP email, FTP upload, Telegram bot API, or Discord webhooks. The malware configuration is embedded in the .NET assembly, typically obfuscated using string encryption, resource encryption, or custom loaders that decrypt and execute Agent Tesla in memory via .NET Reflection (fileless). Configuration extraction involves decompiling the .NET assembly with dnSpy or ILSpy, identifying the decryption routine for configuration strings, and extracting SMTP server addresses, credentials, FTP endpoints, Telegram bot tokens, and targeted applications.
When to Use
- When performing authorized security testing that involves extracting config from agent tesla rat
- When analyzing malware samples or attack artifacts in a controlled environment
- When conducting red team exercises or penetration testing engagements
- When building detection capabilities based on offensive technique understanding
Detection Gaps & Validation
- Regex-grepping the raw file usually returns nothing useful. Agent Tesla encrypts its config strings (XOR, then SHA256-derived-key AES in newer builds) and stores them in the .NET resource section, so plaintext SMTP/FTP/Telegram values won't appear. You must find and replay the in-binary decryption routine, not scrape strings.
- Multi-stage loaders hide the real RAT. The first-stage assembly often decrypts and
Assembly.Loads the actual Agent Tesla payload in memory (fileless) - decompiling the dropper alone yields no config. Dump the unpacked second stage from memory (sandbox/MegaDumper/pe-sieve) and decompile that.
- Obfuscators break dnSpy/ILSpy. ConfuserEx/.NET Reactor mangle names and control flow; run
de4dot first, and if string decryption is delegate-based, use dynamic decryption (invoke the decryptor under dnSpy debugger) rather than static reading.
- Confirm extraction by validating each artifact: the Telegram token against the
bot<token>/getMe format, SMTP host:port + credentials as a coherent pair, and decoded base64 blobs decoding to printable creds/URLs - then corroborate in a sandbox capture (ANY.RUN/CAPE) showing the actual exfil connection.
- Don't stop at one channel. A sample may carry SMTP and fallback FTP/Telegram/Discord; enumerate all four exfil patterns plus the targeted-application list and persistence path.
- Benign lookalikes / FP traps: legitimate SMTP libraries, embedded test creds, and analytics tokens in clean .NET apps match these regexes. Family attribution (Agent Tesla code structure, panel strings) must accompany any "config extracted" claim.
Prerequisites
- dnSpy or ILSpy for .NET decompilation
- Python 3.9+ with
dnlib or pythonnet for automated extraction
- de4dot for .NET deobfuscation
- Understanding of .NET IL code and Reflection
- Sandbox for dynamic analysis (ANY.RUN, CAPE)
Workflow
Step 1: Deobfuscate and Extract Configuration
#!/usr/bin/env python3
"""Extract Agent Tesla RAT configuration from .NET assemblies."""
import re
import sys
import json
import base64
import hashlib
from pathlib import Path
def extract_strings_from_dotnet(filepath):
"""Extract readable strings from .NET binary for config analysis."""
with open(filepath, 'rb') as f:
data = f.read()
# Extract US (User Strings) heap from .NET metadata
strings = []
# Look for common Agent Tesla config patterns
patterns = {
"smtp_server": re.compile(rb'smtp[\.\-][\w\.\-]+\.\w{2,}', re.I),
"email": re.compile(rb'[\w\.\-]+@[\w\.\-]+\.\w{2,}'),
"ftp_url": re.compile(rb'ftp://[\w\.\-:/]+', re.I),
"telegram_token": re.compile(rb'\d{8,10}:[A-Za-z0-9_-]{35}'),
"telegram_chat": re.compile(rb'(?:chat_id=|chatid[=:])[\-]?\d{5,15}', re.I),
"discord_webhook": re.compile(rb'https://discord\.com/api/webhooks/\d+/[\w-]+'),
"password": re.compile(rb'(?:pass(?:word)?|pwd)[=:]\s*[\w!@#$%^&*]{4,}', re.I),
"port": re.compile(rb'(?:port|smtp_port)[=:]\s*\d{2,5}', re.I),
}
results = {}
for name, pattern in patterns.items():
matches = pattern.findall(data)
if matches:
results[name] = [m.decode('utf-8', errors='replace') for m in matches]
# Extract Base64-encoded strings (common obfuscation)
b64_pattern = re.compile(rb'[A-Za-z0-9+/]{20,}={0,2}')
b64_decoded = []
for match in b64_pattern.finditer(data):
try:
decoded = base64.b64decode(match.group())
text = decoded.decode('utf-8', errors='strict')
if text.isprintable() and len(text) > 5:
b64_decoded.append(text)
except Exception:
pass
if b64_decoded:
results["base64_decoded_strings"] = b64_decoded[:30]
return results
def decrypt_agenttesla_strings(data, key_hex):
"""Decrypt Agent Tesla encrypted configuration strings."""
key = bytes.fromhex(key_hex)
# Agent Tesla V1: Simple XOR with key
decrypted_strings = []
# Find encrypted blobs (high-entropy byte sequences)
blob_pattern = re.compile(rb'[\x80-\xff]{16,256}')
for match in blob_pattern.finditer(data):
blob = match.group()
# Try XOR decryption
decrypted = bytes(b ^ key[i % len(key)] for i, b in enumerate(blob))
try:
text = decrypted.decode('utf-8', errors='strict')
if text.isprintable() and len(text.strip()) > 3:
decrypted_strings.append(text.strip())
except UnicodeDecodeError:
pass
# V2: SHA256-based key derivation then AES
sha256_key = hashlib.sha256(key).digest()
return decrypted_strings
def analyze_exfiltration_config(config):
"""Analyze extracted configuration for exfiltration methods."""
methods = []
if config.get("smtp_server"):
methods.append({
"type": "SMTP",
"servers": config["smtp_server"],
"emails": config.get("email", []),
})
if config.get("ftp_url"):
methods.append({
"type": "FTP",
"urls": config["ftp_url"],
})
if config.get("telegram_token"):
methods.append({
"type": "Telegram",
"tokens": config["telegram_token"],
"chat_ids": config.get("telegram_chat", []),
})
if config.get("discord_webhook"):
methods.append({
"type": "Discord",
"webhooks": config["discord_webhook"],
})
return methods
if __name__ == "__main__":
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} <agent_tesla_sample>")
sys.exit(1)
config = extract_strings_from_dotnet(sys.argv[1])
methods = analyze_exfiltration_config(config)
report = {"raw_config": config, "exfiltration_methods": methods}
print(json.dumps(report, indent=2))
Validation Criteria
- Exfiltration method identified (SMTP/FTP/Telegram/Discord)
- Server addresses and credentials extracted from config
- Targeted applications list recovered
- Keylogger and screenshot capture settings documented
- Persistence mechanism identified
- IOCs suitable for network blocking extracted
References
1---2name: extracting-config-from-agent-tesla-rat3description: Extract embedded configuration from Agent Tesla RAT samples including SMTP/FTP/Telegram exfiltration credentials, keylogger settings, and C2 endpoints using .NET decompilation and memory analysis.4license: Apache-2.05---6# Extracting Config from Agent Tesla RAT78## Overview910Agent Tesla is a .NET-based Remote Access Trojan (RAT) and keylogger that ranked among the top 10 malware variants in 2024, impacting 6.3% of corporate networks globally. It exfiltrates stolen credentials via SMTP email, FTP upload, Telegram bot API, or Discord webhooks. The malware configuration is embedded in the .NET assembly, typically obfuscated using string encryption, resource encryption, or custom loaders that decrypt and execute Agent Tesla in memory via .NET Reflection (fileless). Configuration extraction involves decompiling the .NET assembly with dnSpy or ILSpy, identifying the decryption routine for configuration strings, and extracting SMTP server addresses, credentials, FTP endpoints, Telegram bot tokens, and targeted applications.111213## When to Use1415- When performing authorized security testing that involves extracting config from agent tesla rat16- When analyzing malware samples or attack artifacts in a controlled environment17- When conducting red team exercises or penetration testing engagements18- When building detection capabilities based on offensive technique understanding1920## Detection Gaps & Validation2122- **Regex-grepping the raw file usually returns nothing useful.** Agent Tesla encrypts its config strings (XOR, then SHA256-derived-key AES in newer builds) and stores them in the .NET resource section, so plaintext SMTP/FTP/Telegram values won't appear. You must find and replay the in-binary decryption routine, not scrape strings.23- **Multi-stage loaders hide the real RAT.** The first-stage assembly often decrypts and `Assembly.Load`s the actual Agent Tesla payload in memory (fileless) - decompiling the dropper alone yields no config. Dump the unpacked second stage from memory (sandbox/`MegaDumper`/`pe-sieve`) and decompile *that*.24- **Obfuscators break dnSpy/ILSpy.** ConfuserEx/.NET Reactor mangle names and control flow; run `de4dot` first, and if string decryption is delegate-based, use dynamic decryption (invoke the decryptor under dnSpy debugger) rather than static reading.25- **Confirm extraction** by validating each artifact: the Telegram token against the `bot<token>/getMe` format, SMTP host:port + credentials as a coherent pair, and decoded base64 blobs decoding to printable creds/URLs - then corroborate in a sandbox capture (ANY.RUN/CAPE) showing the actual exfil connection.26- **Don't stop at one channel.** A sample may carry SMTP *and* fallback FTP/Telegram/Discord; enumerate all four exfil patterns plus the targeted-application list and persistence path.27- **Benign lookalikes / FP traps:** legitimate SMTP libraries, embedded test creds, and analytics tokens in clean .NET apps match these regexes. Family attribution (Agent Tesla code structure, panel strings) must accompany any "config extracted" claim.2829## Prerequisites3031- dnSpy or ILSpy for .NET decompilation32- Python 3.9+ with `dnlib` or `pythonnet` for automated extraction33- de4dot for .NET deobfuscation34- Understanding of .NET IL code and Reflection35- Sandbox for dynamic analysis (ANY.RUN, CAPE)3637## Workflow3839### Step 1: Deobfuscate and Extract Configuration4041```python42#!/usr/bin/env python343"""Extract Agent Tesla RAT configuration from .NET assemblies."""44import re45import sys46import json47import base6448import hashlib49from pathlib import Path505152def extract_strings_from_dotnet(filepath):53 """Extract readable strings from .NET binary for config analysis."""54 with open(filepath, 'rb') as f:55 data = f.read()5657 # Extract US (User Strings) heap from .NET metadata58 strings = []5960 # Look for common Agent Tesla config patterns61 patterns = {62 "smtp_server": re.compile(rb'smtp[\.\-][\w\.\-]+\.\w{2,}', re.I),63 "email": re.compile(rb'[\w\.\-]+@[\w\.\-]+\.\w{2,}'),64 "ftp_url": re.compile(rb'ftp://[\w\.\-:/]+', re.I),65 "telegram_token": re.compile(rb'\d{8,10}:[A-Za-z0-9_-]{35}'),66 "telegram_chat": re.compile(rb'(?:chat_id=|chatid[=:])[\-]?\d{5,15}', re.I),67 "discord_webhook": re.compile(rb'https://discord\.com/api/webhooks/\d+/[\w-]+'),68 "password": re.compile(rb'(?:pass(?:word)?|pwd)[=:]\s*[\w!@#$%^&*]{4,}', re.I),69 "port": re.compile(rb'(?:port|smtp_port)[=:]\s*\d{2,5}', re.I),70 }7172 results = {}73 for name, pattern in patterns.items():74 matches = pattern.findall(data)75 if matches:76 results[name] = [m.decode('utf-8', errors='replace') for m in matches]7778 # Extract Base64-encoded strings (common obfuscation)79 b64_pattern = re.compile(rb'[A-Za-z0-9+/]{20,}={0,2}')80 b64_decoded = []81 for match in b64_pattern.finditer(data):82 try:83 decoded = base64.b64decode(match.group())84 text = decoded.decode('utf-8', errors='strict')85 if text.isprintable() and len(text) > 5:86 b64_decoded.append(text)87 except Exception:88 pass8990 if b64_decoded:91 results["base64_decoded_strings"] = b64_decoded[:30]9293 return results949596def decrypt_agenttesla_strings(data, key_hex):97 """Decrypt Agent Tesla encrypted configuration strings."""98 key = bytes.fromhex(key_hex)99 # Agent Tesla V1: Simple XOR with key100 decrypted_strings = []101102 # Find encrypted blobs (high-entropy byte sequences)103 blob_pattern = re.compile(rb'[\x80-\xff]{16,256}')104 for match in blob_pattern.finditer(data):105 blob = match.group()106 # Try XOR decryption107 decrypted = bytes(b ^ key[i % len(key)] for i, b in enumerate(blob))108 try:109 text = decrypted.decode('utf-8', errors='strict')110 if text.isprintable() and len(text.strip()) > 3:111 decrypted_strings.append(text.strip())112 except UnicodeDecodeError:113 pass114115 # V2: SHA256-based key derivation then AES116 sha256_key = hashlib.sha256(key).digest()117118 return decrypted_strings119120121def analyze_exfiltration_config(config):122 """Analyze extracted configuration for exfiltration methods."""123 methods = []124125 if config.get("smtp_server"):126 methods.append({127 "type": "SMTP",128 "servers": config["smtp_server"],129 "emails": config.get("email", []),130 })131132 if config.get("ftp_url"):133 methods.append({134 "type": "FTP",135 "urls": config["ftp_url"],136 })137138 if config.get("telegram_token"):139 methods.append({140 "type": "Telegram",141 "tokens": config["telegram_token"],142 "chat_ids": config.get("telegram_chat", []),143 })144145 if config.get("discord_webhook"):146 methods.append({147 "type": "Discord",148 "webhooks": config["discord_webhook"],149 })150151 return methods152153154if __name__ == "__main__":155 if len(sys.argv) < 2:156 print(f"Usage: {sys.argv[0]} <agent_tesla_sample>")157 sys.exit(1)158159 config = extract_strings_from_dotnet(sys.argv[1])160 methods = analyze_exfiltration_config(config)161162 report = {"raw_config": config, "exfiltration_methods": methods}163 print(json.dumps(report, indent=2))164```165166## Validation Criteria167168- Exfiltration method identified (SMTP/FTP/Telegram/Discord)169- Server addresses and credentials extracted from config170- Targeted applications list recovered171- Keylogger and screenshot capture settings documented172- Persistence mechanism identified173- IOCs suitable for network blocking extracted174175## References176177- [Splunk - Agent Tesla Detection and Analysis](https://www.splunk.com/en_us/blog/security/inside-the-mind-of-a-rat-agent-tesla-detection-and-analysis.html)178- [Qualys - Catching the RAT Agent Tesla](https://blog.qualys.com/vulnerabilities-threat-research/2022/02/02/catching-the-rat-called-agent-tesla)179- [ANY.RUN Agent Tesla Analysis](https://any.run/malware-trends/agenttesla/)180- [Trustwave - Agent Tesla Novel Loader](https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/agent-teslas-new-ride-the-rise-of-a-novel-loader/)181- [Malpedia - Agent Tesla](https://malpedia.caad.fkie.fraunhofer.de/details/win.agent_tesla)