reverse-engineering-dotnet-malware-with-dnspy について
dnSpy を使って .NET サンプルを調べる、マルウェア分析担当者向けのリバースエンジニアリングスキルです。難読化解除、コード確認、実行時デバッグ、設定や C2 情報の抽出を扱い、隔離環境での分析を前提とします。
主な機能
- 01.NET アセンブリと難読化方式の識別
- 02de4dot による一般的な難読化の解除
- 03dnSpy でのコード逆コンパイル
- 04C2 設定と指標の抽出
- 05ブレークポイントによる実行時動作の観察
活用シーン
- 01AgentTesla など .NET マルウェアの分析
- 02難読化されたアセンブリのコードと文字列の確認
- 03ハードコードされた C2 アドレスや鍵の抽出
- 04復号や動的ロードの挙動の観察
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill reverse-engineering-dotnet-malware-with-dnspyインストール後、Claude Code で/reverse-engineering-dotnet-malware-with-dnspyを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
dnSpyを使用した.NETマルウェアのリバースエンジニアリング
使用する場面
- マルウェアのサンプルが、逆コンパイルが必要な.NETアセンブリ(C#、VB.NET、F#)として特定された場合
- .NETベースのマルウェアファミリー(AgentTesla、AsyncRAT、RedLine Stealer、Quasar RAT)を分析する場合
- ConfuserEx、SmartAssembly、またはカスタム難読化ツールで保護された.NETコードを難読化解除する場合
- マネージアセンブリからハードコードされたC2設定、暗号化キー、認証情報を抽出する場合
- 実行時に.NETマルウェアをデバッグし、復号ルーチンや動的な動作を観察する場合
ネイティブ(アンマネージド)PEバイナリには使用しないでください。ネイティブコードの分析にはGhidraまたはIDAを使用してください。
前提条件
- dnSpyまたはdnSpyExがインストールされていること(https://github.com/dnSpyEx/dnSpy - コミュニティによって保守されているフォーク)
- 自動.NET難読化解除用のde4dot(
https://github.com/de4dot/de4dot) - 相互検証用の代替逆コンパイラーとしてILSpy
- 分析中に変更したアセンブリを再コンパイルするため、.NET SDKがインストールされていること
- 実際のマルウェアでdnSpyデバッガーを実行するための隔離されたWindows VM
- 使用されている.NET難読化ツールを特定するためのDetect It Easy(DIE)
ワークフロー
ステップ1:.NETアセンブリと難読化ツールを特定する
サンプルが.NETバイナリであることを確認し、保護を検出します:
# 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
ステップ2:de4dotで難読化を解除する
手動分析の前に、一般的な.NET難読化を解除します:
# 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)
ステップ3:dnSpyで開いてコードを分析する
難読化を解除したアセンブリをdnSpyに読み込み、ソースコードレベルで分析します:
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
ステップ4:設定とC2データを抽出する
逆コンパイルしたソースコードから、ハードコードされた設定を特定します:
// 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}")
ステップ5:dnSpyでデバッグする
ブレークポイントを設定してマルウェアをデバッグし、実行時の動作を観察します:
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
ステップ6:調査結果を記録する
分析結果を整理されたレポートにまとめます:
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
主な概念
| 用語 | 定義 |
|---|---|
| CIL/MSIL | 共通中間言語。 .NETアセンブリのコンパイル先となるバイトコード形式で、逆コンパイルして高水準のC#/VB.NETに戻すことができます |
| メタデータトークン | アセンブリのメタデータテーブル内にある.NETの型、メソッド、フィールドを識別する一意の識別子。dnSpyでのナビゲーションに使用します |
| de4dot | 多くの商用およびマルウェア専用の難読化ツールを特定し、保護を解除するオープンソースの.NET難読化解除ツール |
| ConfuserEx | マルウェア作成者が文字列の暗号化や制御フローの難読化に頻繁に使用する、人気のオープンソース.NET難読化ツール |
| 文字列の暗号化 | 文字列リテラルを暗号化データと実行時の復号呼び出しに置き換え、静的分析からIOCを隠す難読化手法 |
| リソースの埋め込み | 設定、ペイロード、または追加のアセンブリを.NETの埋め込みリソースに格納する手法。アセンブリのメタデータから導出したキーで暗号化されることがよくあります |
| Assembly.Load | メモリ内のバイト配列からアセンブリを読み込む.NETメソッド。埋め込みペイロードのファイルレス実行を可能にします |
ツールとシステム
- dnSpy/dnSpyEx:C#およびVB.NETの逆コンパイルに対応した、オープンソースの.NETアセンブリエディター、逆コンパイラー、デバッガー
- de4dot:ConfuserEx、SmartAssembly、Dotfuscator、Reactorなど、多数のプロテクターに対応した自動.NET難読化解除ツール
- ILSpy:アセンブリコードのC#、VB.NET、ILビューを提供するオープンソースの.NET逆コンパイラー
- dotPeek:シンボルサーバーと相互参照ナビゲーションを備えた、JetBrainsの無料.NET逆コンパイラー
- Detect It Easy(DIE):.NET Frameworkのバージョン、難読化ツール、コンパイラー情報を特定するマルチフォーマットファイル解析ツール
よくあるシナリオ
シナリオ:AgentTesla の情報窃取型マルウェアを分析する
コンテキスト:フィッシングメールによって、AgentTesla と特定された .NET 実行ファイルが配信されます。サンプルを分析し、窃取する認証情報、データの持ち出し方法、C2 の設定を特定する必要があります。
アプローチ:
- Detect It Easy を実行して、難読化ツールを特定します(一般的には ConfuserEx またはカスタムのものです)。
- de4dot で難読化を解除し、クラス名とメソッド名を読みやすい状態に戻して、文字列を復号します。
- dnSpy で開き、エントリーポイントに移動して初期化処理を理解します。
- 認証情報を収集するモジュール(ブラウザー、メール、FTP、VPN のパスワードを窃取するクラス)を特定します。
- 持ち出し方法(SMTP メール、FTP アップロード、HTTP POST、Telegram ボット API)を見つけます。
- C2 の設定(SMTP サーバー、認証情報、送信先メールアドレス、または HTTP URL)を抽出します。
- 復号関数にデバッガーのブレークポイントを設定し、すべての復号済み文字列を一度に取得します。
注意点:
- 最初に de4dot を使わずに分析する(ConfuserEx により、手動での分析が非常に困難になります)。
- 複数段階の読み込みを確認しない(最初の .NET 実行ファイルが、リソースから追加のアセンブリを読み込む場合があります)。
- .NET リソース内に保存された設定を見落とす(ハードコードされた文字列ではない場合があります)。
- ネットワークを隔離せずにデバッガーを実行する(AgentTesla はすぐにデータを持ち出そうとします)。
出力形式
.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
コメント
Markdown 対応