Files
Anthropic-Cybersecurity-Skills/skills/extracting-config-from-agent-tesla-rat/scripts/agent.py
T
mukul975 c47eed6a64 Production hardening: security fixes, code quality, 724 skills complete
- Fix 25 shell=True subprocess calls with list-based commands
- Fix 49 verify=False in defensive skills (env-var override)
- Add timeout to 231 HTTP/subprocess/socket calls
- Fix 6 SQL injection patterns with whitelist validation
- Replace 8 __import__() with standard imports
- Remove 701 unused imports across 442 files
- Add authorized-testing disclaimers to all offensive skills
- Complete 11 incomplete skill directories
- Expand 10 stub SKILL.md files with full content
- Fix 2 YAML parse errors in frontmatter
- Fix 5 pre-existing syntax errors
- Convert 22 hardcoded paths/ports to environment variables
- Back up 21 redundant skill pairs to .bak
- Fix 2 global declaration errors
- 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE)
- 0 compile errors across all 724 agent.py files
2026-03-19 13:26:49 +01:00

174 lines
5.5 KiB
Python

#!/usr/bin/env python3
"""Agent for extracting configuration from Agent Tesla RAT samples (malware analysis)."""
import argparse
import base64
import hashlib
import json
import os
import re
from datetime import datetime, timezone
AGENT_TESLA_INDICATORS = {
"strings": [
"smtp.gmail.com", "smtp.yandex.com", "SmtpPort",
"KeyboardHook", "ClipboardLogger", "ScreenCapture",
"GetClipboardData", "GetForegroundWindow",
"Mozilla/5.0", "passwords.txt",
],
"namespaces": [
"AgentTesla", "WebMonitor", "HPDefender",
"GodMode", "AKStealer", "Origin Logger",
],
}
def compute_file_hashes(file_path):
"""Compute MD5, SHA1, SHA256 of a file."""
md5 = hashlib.md5()
sha1 = hashlib.sha1()
sha256 = hashlib.sha256()
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(65536), b""):
md5.update(chunk)
sha1.update(chunk)
sha256.update(chunk)
return {
"md5": md5.hexdigest(),
"sha1": sha1.hexdigest(),
"sha256": sha256.hexdigest(),
}
def extract_strings(file_path, min_len=6):
"""Extract ASCII and wide strings from binary."""
strings = []
with open(file_path, "rb") as f:
data = f.read()
# ASCII strings
for match in re.finditer(rb'[\x20-\x7e]{%d,}' % min_len, data):
strings.append(match.group().decode("ascii", errors="replace"))
# Wide strings (UTF-16LE)
for match in re.finditer(rb'(?:[\x20-\x7e]\x00){%d,}' % min_len, data):
try:
strings.append(match.group().decode("utf-16-le", errors="replace"))
except UnicodeDecodeError:
pass
return strings
def find_smtp_config(strings_list):
"""Extract SMTP configuration from string artifacts."""
config = {"smtp_server": None, "smtp_port": None, "email": None, "password": None}
for s in strings_list:
if re.match(r'smtp\.\w+\.\w+', s, re.I):
config["smtp_server"] = s
if re.match(r'^\d{2,5}$', s) and int(s) in (25, 465, 587, 2525):
config["smtp_port"] = int(s)
if re.match(r'[\w.+-]+@[\w-]+\.[\w.]+', s):
config["email"] = s
return config
def find_ftp_config(strings_list):
"""Extract FTP exfiltration configuration."""
config = {"ftp_server": None, "ftp_user": None, "ftp_password": None}
for s in strings_list:
if re.match(r'ftp\.\w+\.\w+', s, re.I):
config["ftp_server"] = s
if "ftp://" in s.lower():
config["ftp_url"] = s
return config
def find_telegram_config(strings_list):
"""Extract Telegram bot exfiltration config."""
config = {"bot_token": None, "chat_id": None}
for s in strings_list:
if re.match(r'\d{8,12}:[A-Za-z0-9_-]{35}', s):
config["bot_token"] = s
if re.match(r'^-?\d{9,13}$', s):
config["chat_id"] = s
return config
def decode_base64_strings(strings_list):
"""Try to decode base64-encoded configuration strings."""
decoded = []
for s in strings_list:
if len(s) > 20 and re.match(r'^[A-Za-z0-9+/=]+$', s):
try:
d = base64.b64decode(s).decode("utf-8", errors="replace")
if any(c.isprintable() for c in d) and len(d) > 4:
decoded.append({"encoded": s[:40], "decoded": d[:100]})
except Exception:
pass
return decoded
def analyze_sample(file_path):
"""Full analysis of suspected Agent Tesla sample."""
hashes = compute_file_hashes(file_path)
strings = extract_strings(file_path)
indicators_found = []
for indicator in AGENT_TESLA_INDICATORS["strings"]:
if any(indicator.lower() in s.lower() for s in strings):
indicators_found.append(indicator)
smtp = find_smtp_config(strings)
ftp = find_ftp_config(strings)
telegram = find_telegram_config(strings)
b64_decoded = decode_base64_strings(strings)
return {
"file": file_path,
"file_size": os.path.getsize(file_path),
"hashes": hashes,
"agent_tesla_indicators": indicators_found,
"is_agent_tesla": len(indicators_found) >= 3,
"config": {
"smtp": smtp,
"ftp": ftp,
"telegram": telegram,
},
"base64_decoded": b64_decoded[:10],
"total_strings": len(strings),
}
def main():
parser = argparse.ArgumentParser(
description="Extract configuration from Agent Tesla RAT samples"
)
parser.add_argument("sample", help="Path to suspected Agent Tesla sample")
parser.add_argument("--output", "-o", help="Output JSON report")
parser.add_argument("--verbose", "-v", action="store_true")
args = parser.parse_args()
print("[*] Agent Tesla Configuration Extraction Agent")
result = analyze_sample(args.sample)
print(f"[*] SHA256: {result['hashes']['sha256']}")
print(f"[*] Agent Tesla indicators: {len(result['agent_tesla_indicators'])}")
print(f"[*] Likely Agent Tesla: {result['is_agent_tesla']}")
if result["config"]["smtp"]["smtp_server"]:
print(f"[*] SMTP C2: {result['config']['smtp']['smtp_server']}")
if result["config"]["telegram"]["bot_token"]:
print(f"[*] Telegram bot found")
report = {"timestamp": datetime.now(timezone.utc).isoformat(), "analysis": result}
if args.output:
with open(args.output, "w") as f:
json.dump(report, f, indent=2)
print(f"[*] Report saved to {args.output}")
else:
print(json.dumps(report, indent=2))
if __name__ == "__main__":
main()