Analyzing a .NET RAT Configuration

25 minIn Progress

Analyzing a .NET RAT Configuration

Why RAT Configuration Extraction Matters

Remote Access Trojans (RATs) are the most common category of .NET malware. Every RAT must store operational parameters -- the C2 server address, encryption keys, mutex names, persistence paths -- somewhere in its binary. Extracting this configuration is one of the highest-value analysis tasks because it produces immediate, actionable intelligence:

Config FieldIntelligence ValueHow It Helps
C2 Host / PortNetwork IOCBlock at firewall/proxy, create detection rules
Encryption KeyDecryption capabilityDecrypt captured C2 traffic for full visibility
Mutex NameHost IOCDetect running infections across the enterprise
Install PathFile IOCSweep endpoints for installed copies
Registry KeyPersistence IOCIdentify and remove persistence mechanisms
Campaign ID / VersionAttribution dataLink samples to campaigns and threat actors
Anti-Analysis FlagsOperational contextUnderstand what defenses the attacker anticipated

Analyst Tip: A single extracted RAT config can generate a dozen or more IOCs. This is often faster and more reliable than dynamic analysis for producing actionable intelligence.


Common .NET RAT Configuration Patterns

Through analyzing hundreds of .NET RAT samples, several recurring configuration patterns emerge. Recognizing these patterns lets you locate the config quickly, even in unfamiliar families.

Pattern 1: Static Fields in a Settings Class (AsyncRAT, Quasar)

The simplest pattern. Config values are stored as static fields in a dedicated class. In unobfuscated samples, you can read them directly:

// AsyncRAT-style Settings class (decompiled from dnSpyEx)
internal static class Settings
{
    public static string Host    = "185.196.x.x";
    public static string Port    = "8808";
    public static string Key     = "VGhpcyBpcyBhIHRlc3Q=";
    public static string Mutex   = "AsyncMutex_6a1f3b2c";
    public static string InstDir = "%AppData%";
    public static string InstFile = "svchost.exe";
    public static string Version  = "0.5.8";
    public static bool   Install  = true;
    public static bool   AntiVM   = true;
}

How to find it: Search (Ctrl+Shift+K) in dnSpyEx for strings like "Host", "Port", "Mutex", "Settings", or "Config". The class usually stands out as a collection of static string fields.

Pattern 2: Encrypted Config in Resources (Agent Tesla, Formbook)

More sophisticated RATs encrypt the entire configuration and store it as an embedded resource. A decryption routine extracts it at runtime:

// Agent Tesla-style encrypted config extraction
byte[] encryptedConfig = Resources.ResourceManager.GetObject("CONFIG");
byte[] key = Encoding.UTF8.GetBytes("hardcoded_key_here");
byte[] iv  = Encoding.UTF8.GetBytes("hardcoded_iv_here");

using (Aes aes = Aes.Create())
{
    aes.Key = key;
    aes.IV = iv;
    aes.Mode = CipherMode.CBC;
    byte[] decrypted = aes.CreateDecryptor().TransformFinalBlock(
        encryptedConfig, 0, encryptedConfig.Length);
    // decrypted contains: "host|port|mutex|key|installpath"
    string[] parts = Encoding.UTF8.GetString(decrypted).Split('|');
}

How to find it: Look for Resources.ResourceManager calls near the beginning of Main(), or search for encryption-related classes (AES, RijndaelManaged, DES).

Pattern 3: Constructor-Based Config (NanoCore, njRAT)

Config values are decrypted in a constructor, often using a per-field decryption call:

// NanoCore-style per-field decryption
public ClientSettings()
{
    this.Host       = Crypto.Decrypt("a3F2X09iZnVzY2F0ZWQ=");
    this.Port       = Crypto.Decrypt("ODgwOA==");
    this.Mutex      = Crypto.Decrypt("TmFub0NvcmVfYWJj");
    this.GroupName   = Crypto.Decrypt("RGVmYXVsdA==");
    this.InstallPath = Crypto.Decrypt("JUFwcERhdGEl");
}

How to find it: Search for class constructors that call the same method repeatedly with string/byte arguments. The decryption method will have many "Used By" references.

Pattern 4: Base64 + Multi-Layer Encoding (RedLine)

Some RATs stack multiple encoding layers:

// RedLine-style multi-layer config decryption
string encoded = "encrypted_blob_here";
byte[] step1 = Convert.FromBase64String(encoded);     // Base64 decode
byte[] step2 = Xor(step1, key);                       // XOR decrypt
string step3 = Encoding.UTF8.GetString(step2);        // UTF8 decode
string[] config = step3.Split(new[] { "|||" });        // Split fields

Pattern 5: Reflectively Loaded Config (Multi-Stage Loaders)

In multi-stage .NET malware, the configuration may be embedded in a second-stage assembly that is loaded via Assembly.Load():

// Stage 1: Loader decrypts and loads Stage 2
byte[] stage2Bytes = DecryptResource("embedded_payload");
Assembly stage2 = Assembly.Load(stage2Bytes);
// Config is inside stage2, not in the initial loader
Type configType = stage2.GetType("Namespace.Settings");

Analyst implication: If you cannot find a config in the initial binary, it may be in a reflectively loaded second stage. Use DotDumper or debugging to extract the loaded assembly, then analyze that for the config.


Step-by-Step Config Extraction with dnSpyEx

Step 1: Identify the Config Storage Mechanism

Open the sample in dnSpyEx and look for config indicators:

Search targets (Ctrl+Shift+K):
  - String search: "Host", "Port", "Mutex", "Install", "Key", "C2"
  - Type search: "Settings", "Config", "Options", "ClientConfig"
  - Method search: "Decrypt", "Deobfuscate", "GetConfig"
  - Resource search: Check Resources node in Assembly Explorer

Step 2: Determine if Config is Encrypted

ObservationConfig StateNext Step
Readable strings visible in Settings classPlaintextRead values directly
Base64-looking strings in fieldsEncodedDecode Base64 (may be multi-layer)
Fields set by method calls with byte arraysEncryptedIdentify encryption algorithm
No obvious config class visibleHidden / in resourceCheck resources, or trace from Main()

Step 3: Extract Encrypted Config via Debugging

When the config is encrypted, let the malware decrypt it for you:

1. Locate the decryption method (the one called for each config field)
2. Set a breakpoint on the RETURN statement of that method
3. Start debugging (F5)
4. When breakpoint hits, check the return value in Locals window
5. Record: [encrypted_input] -> [decrypted_output]
6. Continue (F5) to the next call
7. Repeat until all config values are collected

Alternatively, set a breakpoint after the config class is fully initialized and inspect all fields at once:

1. Find where the config class is used (e.g., first network call)
2. Set breakpoint on that line
3. When it hits, examine the config object's fields in Locals/Watch
4. All decrypted values will be visible at this point

Step 4: Document the Configuration

Produce a structured report with all extracted values:

=== RAT Configuration Extract ===
Sample:     d41d8cd98f00b204e9800998ecf8427e (MD5)
Family:     AsyncRAT v0.5.8
Obfuscator: None detected

| Field          | Value                                    |
|---------------|------------------------------------------|
| C2 Server      | 185.196.x.x:8808                        |
| Protocol       | TCP (raw socket, custom protocol)        |
| Mutex          | AsyncMutex_6a1f3b2c                     |
| Install Path   | %AppData%\svchost.exe                   |
| Persistence    | HKCU\...\Run\svchost                    |
| AES Key        | VGhpcyBpcyBhIHRlc3Q= (Base64)          |
| Campaign ID    | campaign_2024_q4                         |
| Anti-VM        | Enabled                                  |
| Anti-Debug     | Disabled                                 |

Automated Config Extraction Tools

For known RAT families, automated extractors save significant time:

MWCP (Malware Configuration Parser) by DCSO/FireEye

# Install the framework
pip install mwcp

# Run against a sample (with appropriate parser)
mwcp parse AsyncRAT suspect.exe
# Output: JSON with extracted C2, keys, mutexes

RATDecoders by Kevin Breen

pip install malwareconfig

# Extract config from known RAT family
malwareconfig -f suspect.exe
# Automatically identifies the family and extracts config fields

CAPE Sandbox

CAPE sandbox has built-in config extractors for 100+ malware families:

  1. Submit the sample to CAPE
  2. CAPE identifies the family during dynamic analysis
  3. Config is automatically extracted and presented in the report
  4. Extracted payloads (from Assembly.Load) are also captured

DotDumper for Multi-Stage Extraction

For samples that reflectively load their payload:

# DotDumper monitors Assembly.Load and dumps everything
DotDumper.exe -file loader.exe -log output.json

# Output includes:
#   - Each assembly loaded via Assembly.Load (saved as files)
#   - Decrypted strings
#   - Network connection attempts
#   - File write operations

Family-Specific Config Extraction Tips

RAT FamilyConfig LocationEncryptionKey Extraction Tip
AsyncRATStatic Settings classAES-256 or plaintextSearch for "Settings" class, key is often in "Key" field
Agent TeslaEncrypted resource blobAES-CBCKey/IV hardcoded near ResourceManager call
Quasar RATSettings class, encrypted fieldsAES-128Key derived from hardcoded passphrase via PBKDF2
NanoCorePlugin DLLs in resourcesDES or customDecrypt the main resource, then parse plugin configs
njRATPlaintext in sourceUsually noneLook for string fields in Form1 class
RedLineEncrypted string blockXOR + Base64XOR key is typically short (4-8 bytes)
RemcosEncrypted resource "SETTINGS"RC4First byte of resource is key length, followed by key

Pivoting from Extracted Configs

Once you have extracted a config, use the IOCs to expand your investigation:

C2 IP Address -> Passive DNS -> Other domains on same IP -> Additional samples
Mutex Name    -> Enterprise sweep -> Identify all infected hosts
AES Key       -> Decrypt captured PCAP traffic -> See C2 commands
Install Path  -> EDR telemetry search -> Track lateral movement
Campaign ID   -> VirusTotal/MalwareBazaar -> Find related samples

MITRE ATT&CK Mapping for .NET RATs

BehaviorTechnique IDTechnique Name
Remote access / controlT1219Remote Access Software
KeyloggingT1056.001Keylogging
Screen captureT1113Screen Capture
Clipboard data theftT1115Clipboard Data
Credential harvestingT1555Credentials from Password Stores
Exfiltration over C2T1041Exfiltration Over C2 Channel
Registry Run key persistenceT1547.001Registry Run Keys / Startup Folder
File and directory discoveryT1083File and Directory Discovery
System information discoveryT1082System Information Discovery
Reflective code loadingT1620Reflective Code Loading
Try it in the shell
Practise this lesson's tooling on its sample in an emulated analyst shell. Output is pre-recorded — nothing executes.

Suggested triage steps

  1. 1

    Find the C2 endpoint

    RAT configuration is usually a plain block of strings — start with the callback address.

  2. 2

    Find the persistence value

    The Run key the config installs itself under.

  3. 3

    Find the log path

    Where captured keystrokes are staged before exfiltration.

  4. 4

    Cross-check the config against behaviour

    Every config field should correspond to a capability. If capa reports one the config does not explain, keep reading.

analyst@lab:~emulated · nothing executes

MAA analyst shell — emulated. Nothing executes.

Type 'help', or click a step on the left.

$