WannaMine dropper – Powershell Obfuscation

File details

NAME: file.ps1
TYPE: ASCII text, with very long lines, with no line terminators
SIZE: 3687344 B
MD5: F79F028888C1EED2806179FD256FB239
SHA1: ECCE0CD4C9DD44A1C85E167B7A22EB52B3BD2C70
SHA256: 3F287E29BCB10B200439626D97DD49521816C8DC847797F5ACC7EBFE25B4EFC4
SSDEEP: 49152:60yNRIKiJV1CB3HfqE8HqSi8Hsg91iQCT:q
SIGNATURE: Unsigned

I got bored

Sometime not long before November 2017 I obtained this sample. I have already analyzed it and used it to build WMILister and have evolved WMILister since then. But I wanted to do a write up on the obfuscation techniques I found in it. So this write up will simply cover how I de-obfuscate the dropper. If you decide to analyze a copy of this sample, or similar sample, you do so at your own risk. This particular dropper can place a worm which can spread across a network. This worm is commonly referred to as WannaMine, which is a reference to WannaCry. WannaMine is a crypto-jacking worm but uses the same EternalBlue exploit which WannaCry used. Although, WannaMine uses a powershell variant of EternalBlue. But let’s skip ahead to the de-obfuscation.

So it begins

Firstly, in these screenshots, I have already started to separate the code into separate lines. Originally there were 3 lines (one line was blank). But here is a screen of what I have broken the lines down into:

Line 1 – Is a variable that is 3,683,729 characters long. Currently, this line is boring. It gets used in a Powershell script that gets built later.

Line 2 – Is zero characters long (yes that’s right, I took the time to state that something is zero characters long).

Line 3 – This line is 48,411 characters long. This starts with an open parenthesis and this is not closed until Line 5. The string in this line is our first obfuscated portion that will build a powershell script that will use the $fa variable. More on this later

Line 4 – The main logic to de-obfuscate the string on Line 3 is here. We can see that this will split the on several different characters, then convert item from the split to a character. We also can notice a lot of odd casing of characters. There are capital letters randomly sprinkled through this line. This is a tactic that is attempting to avoid detection methods that are too dumb to ignore case sensitivity.

Line 5 – Simply joins all the separated de-obfuscated strings into one intelligent string.

Line 6 – This is the that makes me scream “STRANGER DANGER!!!!!!!!!!”. If you want to know why, you can simply run this command in powershell to see why (What? You thought you would be able to copy paste it? Nope):

As you can see, it’s a tricky way of using Invoke-Expression in powershell. If you look back at Line 6, you can see that the output of Lines 3 through 5 are being piped into IEX in order to execute it.

Before I forget, Line 7 is an empty line (you’re welcome).

Time for wizardry

But how can we safely de-obfuscate? What ever shall we do? Here is what we do, we fix line 6 to not execute anything but instead, log what gets decoded to another file. DO THIS IN A SANDBOXED ENVIRONMENT!!!!!!! Just like so:

As you can see, I altered Line 6. Also, you have remove the line breaks I added to make this script easier to digest. Otherwise the script will freak out about Line 3, Char 48,411 and I simply don’t have time to worry about that. In short, we replaced the pipe output into IEX to pipe the output into an Out-File. We used NoClobber simply because it sounds cool. But it wasn’t needed at all.

What is in the OutputOfFile.ps1.txt file, you ask? More mess and more stuff to clean up:

Line 1 – Since this starts with an ampersand (damn monkey…if you don’t get that reference, not my problem) the we can tell that the original file with the $fa variable is what is implied to exist here. In fact in lines 2 through 6 we can see “fa” being referenced, but the “$” is obfuscated currently as “sjG” (more on this later). Also, guess what? “STRANGER DANGER!!!!!”. That’s right, Line 1 has another hidden IEX. We can use “Write-Host” to decode that one part as so:

Line 2 through Line 284 is one big ass string (actually the big ass string starts on line one, but I’m just going to say Line 2). But its an organized big ass string. Good indentation, but the text isn’t readable. Well, I guess if I cross my eyes and take 6 shots, it is readable (don’t drink and analyze malicious files…just don’t). But we can see that the very last line is doing a bunch of “.Replace” methods on the string. So lets copy this entire line 284 into a new file and start making it friendlier to read and lets kill that very first quote character of line 284:

Phew….So I have this now to a point where I can easily see there are multiple interesting replacements happening. To make it more human readable, replace “.REPLaCE” with “Write-Host” and run them one at a time in powershell. Also, kill the last closing parenthesis on line 8:

As you can see, I forgot to put “Write-Host” on a few of the commands. I made a mistake. Good thing I was using a SandBox. Although, this mistake didn’t allow anything to become active. So it was a safe mistake that didn’t make me cry. Instead, this mistake taught me something. It taught me that I should be more careful. This time I was safe. Next time, who knows. But you can see what strings will be replaced with other strings. The most significate part of these replacements is that 3 characters will be replaced by 1 character. And we can see that “sjG” will translate to “$” which will then cause lines 2 through 6 to have the fabled “$fa” variable from Line 1 of our original file.ps1.

So far we know that Line 1 has the hidden IEX and that Line 284 has fun string replacement. But how can we get this to be decoded?

Wizardry skill take 2

Here is the secret sauce to this step. You ready for it? Here it is:

Ok, so altering Line 1 to be a Write-Host instead of a hidden IEX isn’t the only step. When I ran this .ps1 file from powershell, I pipped the output of the .ps1 file to out-file like so “Example.ps1 | Out-File -File

Path .\OutputOfSecondFile.ps1.txt -NoClobber” Yup, I used -NoClobber again, simply because I like the way it sounds.

Just about done

So what does the fully de-obfuscated code look like? It looks like this:

As you can see, there is still a little bit of obfuscation by use of concatenation and use of the backtick character. I will simply clean this up by doing a find and replace to remove the ‘+’ and the ‘. I will also add the original $fa declaration back to this script and you will now have an easy to read script like so:

A short explanation of what is in this final screen shot is…

$fa is 5 separate base64 encoded files in one (ps1, exe files, and shell code). Each file will get embedded into the WMI Database. An additional .ps1 file will be downloaded and executed (its just an updated script of what we analyzed and likely isn’t even still hosting anything anymore. I don’t feel like testing it right now.). There is more that this script will do, but it simply is adding persistence using WMI Event Consumers and hiding exe files, ps1 files and shell code into the WMI. Then this infection will worm its way across your network using EternalBlue or credentials stolen via mimikatz (yup, that’s one of the EXEs).