reverse-engineering-dotnet-malware-with-dnspy skill (Anthropic-Cybersecurity-Skills)
- Install
- SKILL.md (verbatim)
- When to Use
- Prerequisites
- Workflow
- Step 1: Identify .NET Assembly and Obfuscator
- Step 2: Deobfuscate with de4dot
- Step 3: Open in dnSpy and Analyze Code
- Step 4: Extract Configuration and C2 Data
- Step 5: Debug with dnSpy
- Step 6: Document Findings
- Key Concepts
- Tools & Systems
- Common Scenarios
- Scenario: Analyzing an AgentTesla Information Stealer
- Output Format
- Other files in this skill
- references/api-reference.md (verbatim)
- Overview
- Dependencies
- External Tools (Optional)
- Core Functions
- detectdotnetassembly(filepath)
- detectobfuscator(filepath)
- deobfuscatewithde4dot(filepath, outputpath)
- extractstrings(filepath, minlength)
- analyzedotnetmetadata(filepath)
- analyzedotnetmalware(filepath, outputdir)
- Obfuscators Detected
- Suspicious String Keywords
- Usage
What it does. 'Reverse engineers .NET malware samples using the dnSpy decompiler and Part of mukul975/Anthropic-Cybersecurity-Skills (817 security skills) (mukul975/Anthropic-Cybersecurity-Skills).
| Upstream | mukul975/Anthropic-Cybersecurity-Skills |
| Skill file | skills/reverse-engineering-dotnet-malware-with-dnspy/SKILL.md |
| License | Apache-2.0 (skill folder LICENSE) |
| Author | mukul975 |
| Fetched | 2026-09-10 |
Install
npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill reverse-engineering-dotnet-malware-with-dnspy, or copy the skill folder into~/.claude/skills/reverse-engineering-dotnet-malware-with-dnspy/.- Raw file:
curl -sL https://raw.githubusercontent.com/mukul975/Anthropic-Cybersecurity-Skills/HEAD/skills/reverse-engineering-dotnet-malware-with-dnspy/SKILL.md
SKILL.md (verbatim)
name: reverse-engineering-dotnet-malware-with-dnspy
description: 'Reverse engineers .NET malware samples using the dnSpy decompiler and
debugger to read C#/VB.NET source, deobfuscate code protected by tools like ConfuserEx
or SmartAssembly, and extract hardcoded C2 configurations, keys, and credentials.
Use when a sample is identified as a .NET assembly (e.g. AgentTesla, AsyncRAT, RedLine
Stealer, Quasar RAT) and needs decompilation, deobfuscation, or config extraction.
'
domain: cybersecurity
subdomain: malware-analysis
tags:
- malware
- dotnet
- reverse-engineering
- dnSpy
- decompilation
version: 1.0.0
author: mahipal
license: Apache-2.0
nist_csf:
- DE.AE-02
- RS.AN-03
- ID.RA-01
- DE.CM-01
mitre_attack:
- T1027
- T1055
- T1140
- T1497
Reverse Engineering .NET Malware with dnSpy
When to Use
- A malware sample is identified as a .NET assembly (C#, VB.NET, F#) requiring decompilation
- Analyzing .NET-based malware families (AgentTesla, AsyncRAT, RedLine Stealer, Quasar RAT)
- Deobfuscating .NET code protected by ConfuserEx, SmartAssembly, or custom obfuscators
- Extracting hardcoded C2 configurations, encryption keys, and credentials from managed assemblies
- Debugging .NET malware at runtime to observe decryption routines and dynamic behavior
Do not use for native (unmanaged) PE binaries; use Ghidra or IDA for native code analysis.
Prerequisites
- dnSpy or dnSpyEx installed (https://github.com/dnSpyEx/dnSpy - community maintained fork)
- de4dot for automated .NET deobfuscation (
https://github.com/de4dot/de4dot) - ILSpy as an alternative decompiler for cross-validation
- .NET SDK installed for recompiling modified assemblies during analysis
- Isolated Windows VM for running dnSpy debugger on live malware
- Detect It Easy (DIE) for identifying the .NET obfuscator used
Workflow
Step 1: Identify .NET Assembly and Obfuscator
Verify the sample is a .NET binary and detect protection:
# Check if file is .NET assembly
file suspect.exe
# Output should contain "PE32 executable" with .NET metadata
# Detect obfuscator with Detect It Easy
diec suspect.exe
# Python-based .NET detection
python3 << 'PYEOF'
import pefile
pe = pefile.PE("suspect.exe")
# Check for .NET COM descriptor
if hasattr(pe, 'DIRECTORY_ENTRY_COM_DESCRIPTOR'):
print("[*] .NET assembly detected")
print(f" Runtime version: {pe.DIRECTORY_ENTRY_COM_DESCRIPTOR}")
else:
# Check for mscoree.dll import (alternative detection)
for entry in pe.DIRECTORY_ENTRY_IMPORT:
if entry.dll.decode().lower() == "mscoree.dll":
print("[*] .NET assembly detected (mscoree.dll import)")
break
else:
print("[!] Not a .NET assembly")
# Check section names for .NET indicators
for section in pe.sections:
name = section.Name.decode().rstrip('\x00')
if name in ['.text', '.rsrc', '.reloc']:
print(f" Section: {name} (typical .NET)")
PYEOF
Step 2: Deobfuscate with de4dot
Remove common .NET obfuscation before manual analysis:
# Run de4dot to identify and remove obfuscation
de4dot suspect.exe -o suspect_cleaned.exe
# Force specific deobfuscator
de4dot suspect.exe -p cf # ConfuserEx
de4dot suspect.exe -p sa # SmartAssembly
de4dot suspect.exe -p dr # Dotfuscator
de4dot suspect.exe -p rv # Reactor
de4dot suspect.exe -p bl # Babel.NET
# Verbose output for debugging
de4dot -v suspect.exe -o suspect_cleaned.exe
# Handle multi-file assemblies
de4dot suspect.exe suspect_helper.dll -o cleaned/
Common .NET Obfuscators:
━━━━━━━━━━━━━━━━━━━━━━━
ConfuserEx: String encryption, control flow, anti-debug, anti-tamper
SmartAssembly: String encoding, flow obfuscation, pruning
Dotfuscator: Renaming, string encryption, control flow
.NET Reactor: Native code generation, necrobit, anti-debug
Babel.NET: String encryption, resource encryption, code virtualization
Crypto Obfuscator: String encryption, anti-debug, watermarking
Custom: Malware-specific obfuscation (manual de4dot configuration needed)
Step 3: Open in dnSpy and Analyze Code
Load the deobfuscated assembly in dnSpy for source-level analysis:
dnSpy Analysis Workflow:
━━━━━━━━━━━━━━━━━━━━━━━
1. File -> Open -> Select cleaned assembly
2. Navigate to the entry point:
- Assembly Explorer -> <namespace> -> Program class -> Main method
- Or: Right-click assembly -> Go to Entry Point
3. Key areas to examine:
- Entry point (Main) for initialization and execution flow
- Form classes for UI-based malware (RATs, stealers)
- Network/HTTP classes for C2 communication
- Crypto/encryption classes for data protection
- Resource access for embedded payloads
- Timer/Thread classes for persistence and scheduling
4. Navigation shortcuts:
Ctrl+G - Go to token/address
Ctrl+Shift+K - Search assemblies
F12 - Go to definition
Ctrl+R - Analyze (find usages)
F5 - Start debugging
F9 - Toggle breakpoint
Step 4: Extract Configuration and C2 Data
Locate hardcoded configuration in the decompiled source:
// Common .NET malware configuration patterns:
// Pattern 1: Static class with hardcoded values
public static class Config {
public static string Host = "185.220.101.42";
public static int Port = 4782;
public static string Key = "GhOsT_RaT_2025";
public static string Mutex = "AsyncMutex_6SI8OkPnk";
public static bool Install = true;
public static string InstallFolder = "%AppData%";
}
// Pattern 2: Encrypted strings decrypted at runtime
public static string Decrypt(string input) {
byte[] data = Convert.FromBase64String(input);
byte[] key = Encoding.UTF8.GetBytes("SecretKey123");
for (int i = 0; i < data.Length; i++) {
data[i] ^= key[i % key.Length];
}
return Encoding.UTF8.GetString(data);
}
// Pattern 3: Resource-embedded configuration
byte[] configData = Properties.Resources.config;
string config = AES.Decrypt(configData, derivedKey);
# Python script to extract .NET resource strings
import subprocess
import re
import base64
# Use monodis (Mono) or ildasm (.NET SDK) to dump IL
result = subprocess.run(
["monodis", "--output=il_dump.il", "suspect_cleaned.exe"],
capture_output=True, text=True
)
# Search for string literals in IL dump
with open("il_dump.il", errors="ignore") as f:
il_code = f.read()
# Find ldstr (load string) instructions
strings = re.findall(r'ldstr\s+"([^"]+)"', il_code)
for s in strings:
# Check for Base64 encoded strings
try:
decoded = base64.b64decode(s).decode('utf-8', errors='ignore')
if len(decoded) > 3 and decoded.isprintable():
print(f" Base64: {s[:40]}... -> {decoded[:100]}")
except:
pass
# Check for URLs/IPs
if re.match(r'https?://', s) or re.match(r'\d+\.\d+\.\d+\.\d+', s):
print(f" Network: {s}")
Step 5: Debug with dnSpy
Set breakpoints and debug the malware to observe runtime behavior:
dnSpy Debugging Workflow:
━━━━━━━━━━━━━━━━━━━━━━━
1. Set breakpoints on key methods:
- String decryption functions (to capture decrypted values)
- Network connection methods (to capture C2 URLs)
- File write operations (to see what is dropped)
- Registry modification methods (to see persistence)
2. Debug -> Start Debugging (F5)
- Select the assembly to debug
- Set command-line arguments if needed
- Configure exception handling (break on all CLR exceptions)
3. At each breakpoint:
- Inspect local variables (Locals window)
- Evaluate expressions (Immediate window)
- View call stack to understand execution context
- Step over (F10) / Step into (F11) / Step out (Shift+F11)
4. Capture decrypted strings:
- Set breakpoint after decryption function returns
- Read the return value from the Locals window
- Document all decrypted configuration values
Step 6: Document Findings
Compile analysis results into a structured report:
Analysis documentation should include:
- .NET assembly metadata (CLR version, target framework, compilation info)
- Obfuscator identified and deobfuscation method used
- Complete C2 configuration (hosts, ports, encryption keys, mutex names)
- Malware capabilities (keylogging, screen capture, file theft, etc.)
- Persistence mechanisms (registry, scheduled tasks, startup folder)
- Anti-analysis techniques (VM detection, debugger detection, sandbox evasion)
- Extracted IOCs (C2 IPs/domains, file hashes, mutex names, registry keys)
- YARA rule based on unique code patterns or strings
Key Concepts
| Term | Definition |
|---|---|
| CIL/MSIL | Common Intermediate Language; the bytecode format .NET assemblies compile to, which can be decompiled back to high-level C#/VB.NET |
| Metadata Token | Unique identifier for .NET types, methods, and fields within the assembly metadata tables; used for navigation in dnSpy |
| de4dot | Open-source .NET deobfuscator that identifies and removes protection from many commercial and malware-specific obfuscators |
| ConfuserEx | Popular open-source .NET obfuscator frequently used by malware authors for string encryption and control flow obfuscation |
| String Encryption | Obfuscation technique replacing string literals with encrypted data and runtime decryption calls to hide IOCs from static analysis |
| Resource Embedding | Storing configuration, payloads, or additional assemblies in .NET embedded resources, often encrypted with a key derived from assembly metadata |
| Assembly.Load | .NET method loading assemblies from byte arrays in memory, enabling fileless execution of embedded payloads |
Tools & Systems
- dnSpy/dnSpyEx: Open-source .NET assembly editor, decompiler, and debugger supporting C# and VB.NET decompilation
- de4dot: Automated .NET deobfuscator supporting ConfuserEx, SmartAssembly, Dotfuscator, Reactor, and many other protectors
- ILSpy: Open-source .NET decompiler providing C#, VB.NET, and IL views of assembly code
- dotPeek: JetBrains' free .NET decompiler with symbol server and cross-reference navigation
- Detect It Easy (DIE): Multi-format file analyzer identifying .NET framework version, obfuscator, and compiler information
Common Scenarios
Scenario: Analyzing an AgentTesla Information Stealer
Context: A phishing email delivers a .NET executable identified as AgentTesla. The sample needs analysis to determine what credentials it steals, how it exfiltrates data, and its C2 configuration.
Approach:
- Run Detect It Easy to identify the obfuscator (commonly ConfuserEx or custom)
- Deobfuscate with de4dot to restore readable class/method names and decrypt strings
- Open in dnSpy and navigate to the entry point to understand initialization
- Locate the credential harvesting modules (browser, email, FTP, VPN password theft classes)
- Find the exfiltration method (SMTP email, FTP upload, HTTP POST, Telegram bot API)
- Extract C2 configuration (SMTP server, credentials, recipient email, or HTTP URL)
- Set debugger breakpoints on the decryption function to capture all decrypted strings at once
Pitfalls:
- Analyzing without de4dot first (ConfuserEx makes manual analysis extremely difficult)
- Not checking for multi-stage loading (initial .NET executable may load additional assemblies from resources)
- Missing configuration stored in .NET resources rather than hardcoded strings
- Running the debugger without network isolation (AgentTesla will attempt to exfiltrate immediately)
Output Format
.NET MALWARE ANALYSIS REPORT
================================
Sample: invoice_scanner.exe
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
Type: .NET Assembly (C#)
Framework: .NET Framework 4.8
Obfuscator: ConfuserEx v1.6
Deobfuscated: Yes (de4dot -p cf)
CLASSIFICATION
Family: AgentTesla v3
Type: Information Stealer / Keylogger
Compile Date: 2025-09-10
C2 CONFIGURATION
Exfil Method: SMTP (Email)
SMTP Server: smtp.yandex[.]com:587
SMTP User: exfil.account@yandex[.]com
SMTP Pass: Str0ngP@ssw0rd2025
Recipient: operator@protonmail[.]com
Interval: 30 minutes
Encryption: AES-256 with key "AgentTesla_2025_key"
CAPABILITIES
[*] Browser credential theft (Chrome, Firefox, Edge, Opera)
[*] Email client passwords (Outlook, Thunderbird)
[*] FTP client credentials (FileZilla, WinSCP)
[*] VPN credentials (NordVPN, OpenVPN)
[*] Keylogging (SetWindowsHookEx)
[*] Screenshot capture (every 30 seconds)
[*] Clipboard monitoring
PERSISTENCE
Method: Registry Run key + Scheduled Task
Registry: HKCU\Software\Microsoft\Windows\CurrentVersion\Run\WindowsUpdate
Task: \Microsoft\Windows\WindowsUpdate\Updater
EXTRACTED IOCs
SMTP Server: smtp.yandex[.]com
Exfil Email: exfil.account@yandex[.]com
Recipient: operator@protonmail[.]com
Mutex: AgentTesla_2025_Q3_MUTEX
Install Path: %AppData%\Microsoft\Windows\svchost.exe
Other files in this skill
references/api-reference.md (verbatim)
API Reference: .NET Malware Reverse Engineering with dnSpy Agent
Overview
Analyzes .NET malware: validates CLR headers, detects obfuscators (ConfuserEx, SmartAssembly), deobfuscates with de4dot, extracts strings/IOCs, and parses .NET metadata via monodis.
Dependencies
| Package | Version | Purpose |
|---|---|---|
| hashlib | stdlib | Sample hash computation |
| struct | stdlib | PE/CLR header parsing |
| re | stdlib | String pattern extraction |
External Tools (Optional)
| Tool | Purpose |
|---|---|
| diec (Detect It Easy) | Obfuscator identification |
| de4dot | Automated .NET deobfuscation |
| monodis | .NET assembly metadata extraction |
Core Functions
detect_dotnet_assembly(filepath)
Validates PE file has CLR header (COM descriptor directory entry).
- Checks: MZ signature, PE signature, optional header magic, CLR RVA
- Returns:
dictwithis_dotnet,clr_header_rva
detect_obfuscator(filepath)
Runs Detect It Easy to identify ConfuserEx, SmartAssembly, .NET Reactor, Dotfuscator, Babel, Eazfuscator, Crypto Obfuscator.
- Returns:
dictwithdetectedlist
deobfuscate_with_de4dot(filepath, output_path)
Runs de4dot to remove obfuscation, producing a cleaner assembly.
- Timeout: 120 seconds
- Returns:
dictwithsuccess,output_path
extract_strings(filepath, min_length)
Extracts ASCII and Unicode strings, classifies into URLs, IPs, emails, registry keys, base64, and suspicious keywords (keylog, stealer, webhook, etc.).
- Returns:
dict[str, list[str]]- categorized indicator lists
analyze_dotnet_metadata(filepath)
Uses monodis to extract assembly info, type definitions, and method counts.
- Returns:
dictwithtype_count,method_count,types
analyze_dotnet_malware(filepath, output_dir)
Full pipeline: hashes -> .NET check -> obfuscator detection -> deobfuscation -> strings -> metadata.
Obfuscators Detected
| Obfuscator | Indicator |
|---|---|
| ConfuserEx | Most common open-source .NET obfuscator |
| SmartAssembly | Commercial obfuscator by Redgate |
| .NET Reactor | Code protection with native stub |
| Dotfuscator | Microsoft-provided obfuscator |
| Eazfuscator | Commercial string/flow obfuscation |
Suspicious String Keywords
keylog, screenshot, clipboard, password, credential, smtp, telegram, discord, webhook, stealer, inject, hook, persist, startup
Usage
python agent.py suspect.exe
Back to mukul975/Anthropic-Cybersecurity-Skills (817 security skills) or Agent skills.