I first ran across the SecureString usage in this twitter thread where @Anyrun_app is talking about a version of “Fake Net” to get all of the C2’s here https://twitter.com/anyrun_app/status/966227622899351552
There are a few methods listed in this thread by different people to run the PowerShell malware to get the output but as usual I like to dig deeper to see how it works.
This link below was actually the first thread I had seen, with “PO3T @PO3T1985”. All of it does not show in in the first link.
We also see the thread here from @JAMESWT_MHT of a long thread of malware documents used with Emotet.
So lets dig in and figure out how the encryption works.
Lets take a look and see what the original PowerShell script I seen looks like.
If we look on the anyrun_app site at the extracted PowerShell script we see this.
And if we copy it to Notepad++ we see this.
After a little more digging we find out that this was most likely generated using @danielhbohannon Invoke-Obfuscation Out-SecureStringCommand.ps1 found here https://github.com/danielbohannon/Invoke-Obfuscation/blob/master/Out-SecureStringCommand.ps1
So how exactly does this thing work ?
The first part is just standard setup script encoded using Invoke-Obfuscation to run this next part that we are really interested in at this point.
This is “Marshaling” managed to unmanaged code to decode the encrypted data (that is in the base 64 string) into memory as a “SecureString” then run the decrypted code.
We can get more info here on SecureString. https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/convertto-securestring?view=powershell-6
The last part is where it gets piped into ConvertTo-SecureString with a key value.
The 2 dots between the two integers represents that it is an array from 224 down to 201.
You will also see it go the other way from low to high and the length depends on the key length chosen.
That will be the numbers used for the key to decrypt the data.
Lets Base64 Decode using Unicode encoding this string to bytes and see what we have.
If we look close we can see a possible delimiter of the char “|” a possible base 64 string and what looks like a Unicode Hex encoded string with a null byte after each value. The first part of that looks like garbage.
Lets take a closer look at the beginning of this base64 string.
All of the samples I looked at had the same hex value at the beginning but what is it?
After some more searching I stumbled onto this page.
This is found in the source for PowerShell itself.
We now see that it is a header to indicate that this data was a Secure string exported to an encrypted string.
So what does our bytes look like after we ignore the header bytes and base 64 decode the remainder of the string ?
Now that is looking a bit different. We now have a #2 , a base64 string and hex bytes.
If we go to here we can now see the format of how this data works.
So we now split to Version | IV | Encrypted Data . We only need the IV and data.
The IV is the middle base 64 string that we will decode to byte() in Unicode format which in this case will give us 16 bytes of data for the IV. While testing decoding to UTF-8 encoding did not produce the correct bytes for the IV.
The next thing we need is the key.
So I built a tool to speed up building the array.
From the example from the builder we can see you can also supply the key as a full array.
We now have all of the pieces to the puzzle and just need to decrypt the data.
It says it is AES but does not say which Version / Flavor to use .
I had a Rijndael Managed version handy so I used that using PKCS7 padding mode to decrypt with.
So now we end up with these decrypted bytes.
Although it is readable it is still in UTF-16/Unicode format. So I need to convert the bytes to UTF-8.
And we finally end up with these UTF-8 bytes.
A little better view.
As we can see here it splits the string of Url’s using the Char “?” and attempts to download and run a file from each one.
The “NSB” appears to be a random number value used for a file name that gets run.
Going back and looking at the PowerShell source code we find in “SecureStringCommands” the function called “ProcessRecord()” on how to unpack and decrypt this Base 64 string.
It is nice to find this at all. I keep forgetting the the PowerShell source code is available online now.
I also found the plain version of the AES class https://msdn.microsoft.com/en-us/library/system.security.cryptography.aes(v=vs.110).aspx
The one without the different Modes (CBC,EBC, etc..) It looks pretty much the same code I used.
Well that it for this one I hope you found the discovery as interesting as I did how how the internals worked.