Top Categories


todayMay 10, 2021

Digital Forensics + Malware Analysis Ahmed Elmayyah

Catch the IEX if You Can: PowerShell De-Obfuscation

Introduction A lot of the time when working with malware or when investigating an incident, you may encounter PowerShell executing obfuscated commands which may look like gibberish. These commands are usually obfuscated to make it harder for the analyst to understand, as well as making it harder for detection solutions [...]

Catch the IEX if You Can: PowerShell De-Obfuscation

Digital Forensics + Malware Analysis Ahmed Elmayyah todayMay 10, 2021 6069 1 5

share close


A lot of the time when working with malware or when investigating an incident, you may encounter PowerShell executing obfuscated commands which may look like gibberish. These commands are usually obfuscated to make it harder for the analyst to understand, as well as making it harder for detection solutions to detect them.

Knowing how to de-obfuscate PowerShell is a very handy and time-saving skill. In this post, we’ll take a look at PowerShell scripts from the Lemon_Duck cryptominer as an example.

When de-obfuscating PowerShell scripts, keep two key rules in mind:

  • Always look for the cmdlet IEX, this is an alias for Invoke-Expression which basically evaluates and executes whatever you give it as input.
  • IEX is usually either at the beginning in the form of IEX (expression) or at the end in the form of expression | IEX.

Example: ("h.stn[me").Replace('.', 'o').Replace('[', 'a') will produce the string “hostname”, which will be printed.

Piping the output into IEX as follows: ("h.stn[me").Replace('.', 'o').Replace('[', 'a') | IEX results in it being executed.

PowerShell IEX Example

You generally want to avoid executing the IEX cmdlet in order to de-obfuscate the script without running the malware in your environment.

It is worth noting that a quite easy and primitive technique that may work sometimes is using Write-Output to get the deobfuscated script. This works in some cases, but we won’t get into too much details on when and why it works.

Lemon_Duck CryptoMiner Handson

In one of Cyber Castle’s IR engagements, the DFIR team encountered the Lemon_Duck cryptominer which had multiple multi-stage obfuscated PowerShell scripts.

Scheduled Task: Downloader

The first script was found in a scheduled task.

Downloader Script from Scheduled Task

This PowerShell script didn’t have many obfuscation techniques. If anything, it was quite readable from the get-go with some simple format fixing such as indentation.

It basically sends a request to which contains the hostname, username, UUID, and a random number as parameters.

By changing the call to a() to Write-Host We can get the URL instead of getting it to execute.

Downloader URL GIF

Sending that request, gets us a file: a.jsp. The file initially contained obfuscated PowerShell code. The whole code is included here. Password: infected.

a.jsp: Stager

Stager Code

The first few bytes are the signature of the script itself. Later on, we can see other scripts verifying the first 173 bytes of the script as the signature.

Length of Signature

This seems like a script which has hex content inside of it, which is decompressed as ASCII text.

We can see the IEX cmdlet clearly at the start, we can just separate it from the rest of the script to get the decompressed version of the included hex data.

We got a pretty long script, which still seems to be obfuscated, let’s pipe the output to a file and then take a closer look at it. I’ll name the file a_deobf1.ps1 to keep track of the De-Obfuscation stages. We can do so by adding | Out-File a_deobf1.ps1 to the end of the line, like so:

  • $(New-Object IO.StreamReader ... [Text.Encoding]::ASCII)).ReadToEnd() | Out-File a_deobf1.ps1

Stager De-Obfuscation 1 GIF

Now on checking a_deobf1.ps1, as usual, the first thing we look for is the IEX cmdlet. One thing that caught my attention was this part in the last line of the script | &( $shELLID[1]+$sHelLId[13]+'X'). It was a pipe (|) with three character after it, the final one being an X.

$SHELLID is a standard PowerShell variable which contains the string “Microsoft.PowerShell”. Indices 1 and 13 are i, and e respectively. This concludes that that is where the IEX cmdlet is.

As we did previously, we can now replace the IEX with Out-File a_deobf2.ps1 to get the new De-Obfuscated script.

Stager De-Obfuscation 2 GIF

Again, and like every time, the first thing we look for is the IEX. There is an explicit IEX string in the script, but it is inside a string (line 418) so it won’t execute. So, let’s take a look at the start of the script. We find this part ((gEt-VARiABLe '*mdr*').NAme[3,11,2]-joIn'') which has the rest of the script in it

If we execute that selection alone, we get IEX. This is because (gEt-VARiABLe '*mdr*').NAme returns the string MaximumDriveCount. and indices 3, 11, and 2 map to i, e, and x respectively.

We can separate the IEX from the rest of the script and use Out-File like before to get to the next stage of de-obfuscation.

Stager De-Obfuscation 3 GIF

And again, on opening the third script we look for the IEX and find it at the end of the script at: |.( $env:ComSPeC[4,26,25]-joIn'')

$env:COMSPEC has the value "C:\Windows\system32\cmd.exe" which has iex at the specified indices. The malware author really is getting repetitive with these methods!

We’ll do our usual magic with the IEX separation and Out-File to get the final script.

Stager De-Obfuscation 4 GIF


Stager Code Now we have a pretty clear PowerShell script that we can read and analyse.

The first things we notice from a quick skim are:

  • The PowerShell script is communicating with multiple domains.

  • It copies the powershell.exe executable to a differently-named file in the same original powershell path.
  • It tries to disable Windows Defender.

    • It also adds an exclusion to the C:\ directory, the path to the PowerShell executable, and the other copy it makes of powershell.exe
  • Detects the type of GPU running on the system in order to start mining

  • Sets a user agent of “Lemon-Duck” before sending a request to a specific domain.

On further analysis, we found out that the server requires the following conditions in order to reply with the payload:

  • The user agent has to be Lemon-Duck

  • The parameters need to state some of the following properties on the system:

    • Hostname

    • UUID

    • MAC Address

    • Windows Version

    • Username

    • Domain Name

    • GPU Brand (Nvidia or AMD)

  • This script downloads the cryptominer itself and executes it.
  • There are two important functions:
    • gcf():
      • Takes a file hash and file name.
      • Downloads the actual miner itself in the %TMP% directory.
      • Verifies the hashes of the downloaded files.
    • stp():
      • Takes a file path
      • Executes the file using cmd.exe.
    • Here’s a more clear version of these functions.

Miner Downoader Prettified Code

WARNING: Be extra careful if you’re going to try the following, we’re dealing with live malware which communicates with a server that is up and running as of (9/5/2021). Do not execute anything you’re unsure of, and do not send any real or personal data to the server.

The PowerShell script has a function SIEX which sends the web request to get the next script. If the parameters are not set properly, the server doesn’t respond with the next script.

Server Response if invalid

However, if the parameters are correct, the server will respond with the next script and execute it using IEX as shown: IEX (-join[char[]]$raw_bytes). We can add the correct parameters to the script to override the automatically collected ones and replace the IEX near the end of the script with a Write-Host to get the next script that the server sends back for analysis.

$params = "&DESKTOP-QTEKH69&09874D56-2136-3D8C-C24F-56EA5E7D6B61&00:0C:29:7D:6B:61&10 Pro_10.0.17763&1&User_Admin&TESTNAME&&Radeon 350&6&0&&&&&&&2475.187&157182335&0.6"


FInalPayload GIF

The Final Script

Simply by taking a look at this script, we can see the IEX cmdlet at the start, so we can separate it and write the output to a file as before.


FinalPayload De-Obfuscation 1 GIF


By looking again, we can see that this script uses the exact same IEX hiding technique as in the initial stager script which used $SHELLID.

We can separate it and write the output to a file for further analysis.

FinalPayload De-Obfuscation 2 GIF

We can see that by no surprise, the script uses the same IEX hiding technique as before which uses $env:COMSPEC.

We can de-obfuscate it using the same method.

FinalPayload De-Obfuscation 3 GIF

This script has an explicit iex string at the start of it, so, again, we can just separate it and just de-obfuscate the rest of the code.

FinalPayload De-Obfuscation 4 GIF

Now we have the final script, which shows some of the IOCs of the Lemon_Duck cryptominer. Many of which are used for persistence.

FinalPayload Code

We hope that you found this blog post useful, thanks for reading. Good luck catching the IEX!

Written by: Ahmed Elmayyah

Rate it

About the author

Ahmed Elmayyah

I work as a DFIR engineer at Cyber Castle. I am a huge tinkerer. I enjoy tinkering with low level programming, hardware, reverse engineering, and Linux. I also enjoy cycling, videogames, and prog rock music.

Previous post

Similar posts

Digital Forensics Kareem Ali / October 1, 2020

Event Log service – Between Offensive and defensive

Event Log Service Event viewer is the preinstalled application in windows to view windows logs, it depends on a event log service to function   EventLog Service Service configuration: STOPPABLE, AcceptPause, AcceptStop Binary path : svchost.exe -k LocalServiceNetworkRestricted -p -k LocalServiceNetworkRestricted is responsible for running eventlog service plus many other services this link explains how ...

Read more trending_flat

Post comments (0)

Leave a reply

Your email address will not be published. Required fields are marked *

Cyber Castle Footer Logo


Cyber Castle is an Egyptian cyber security company founded in 2020. specializes in the cyber security services & solutions with the aim to detect, protect and mitigate from sophisticated cyber threats in a timely manner.

Where We Are

92 Omar Ibn El-Khattab, Almazah, Heliopolis, Cairo Governorate


Mobile: (02) 01018233755


Follow us