On March 27, 2014, Trend Micro revealed the so called “Power Worm” PowerShell-based malware that is actively being used in the wild. With so few publicly reported instances of PowerShell malware in existence, I was excited to get my hands on this most recent strain of PowerShell-based malware. Unable to track it down on my own, I reached out to the security and PowerShell communities. It was with great relief that my friend Lee Holmes – PowerShell developer extraordinaire and author of the Windows PowerShell Cookbook kindly provided me with all of the samples described in the Trend Micro post.
While the Trend Micro post was thorough in its coverage of the broader capabilities of the malware, they did not provide an analysis of its implementation which, as a PowerShell enthusiast and malware analyst, I was very interested in. That said, what follows is my analysis of the mechanics of the Office document infecting malware. Since there were multiple payloads associated with “Power Worm.” I decided to focus on the X97M_CRIGENT.A payload – a malicious Excel spreadsheet.
The targeted Excel macro used in the "Power Worm" campaign |
The spreadsheet contains the following macro:
Private Sub Workbook_Open()
b = "JwBDAEkREDACTEDREDACTED" _
& "QA7ACcAcgREDACTEDREDACTED" _
& "BzACgAKQAREDACTEDREDACTED" _
& "jAGUAIAAtREDACTEDREDACTED" _
& "ACAAUwB5AREDACTEDREDACTED" _
& "GcALgBpAGREDACTEDREDACTED" _
& "4AIAAtAGEREDACTEDREDACTED" _
& "AdAAuAHAAREDACTEDREDACTED"
Set a = CreateObject("WScript.Shell")
a.Run "powershell.exe" & " -noexit -encodedcommand " & b, 0, False
End Sub
People have asked, “Wouldn’t the PowerShell execution policy potentially mitigate this attack?” No. First of all, the execution policy should not be viewed as a security mitigation considering PowerShell itself provides the mechanism to bypass it. Second, the execution policy is not honored when a Base64 encoded command is provided to the ‘-EncodedCommand’ parameter. Malware authors know this and will never run into a situation where the execution policy is the reason their malicious PowerShell code was prevented from executing. Having macros disabled by default prevents the initial infection, but all it takes is a naïve victim to click a single button to enable macros.
The ‘Workbook_Open’ function will execute automatically upon opening an Excel spreadsheet (assuming macros are allowed to execute). After decoding the Base64-encoded PowerShell command, you will be presented with an obfuscated mess consisting of the following:
- The payload is a single line of semicolon delimited PowerShell commands.
- Junk strings that have no impact on the script are inserted between each command.
- All variables and function names are randomly generated and have no logical meaning.
- Lastly, some functions used in the script are not implemented until a subsequent payload is downloaded from the command and control (C2) server.
I rewrote all of the “Power Worm” malware (redacting key portions) that I was able to obtain so that those interested don’t have to be bogged down with difficult to understand obfuscated code. I also created a PowerWorm GitHub repo where you will find the following code:
- The rewritten X97M_CRIGENT.A PowerShell payloads (5 parts in total)
- Test-PowerWormInfection – Detects and removes a “Power Worm” infection
- Get-ExcelMacro – Outputs and removes Excel spreadsheet macros
- Get-WordMacro – Outputs and removes Word document macros
As soon as the macro executes and launches PowerShell, the following code is executed:
- Suppress error messages.
- Obtain the machine GUID with WMI. This unique value specific to your system is used throughout the malware as a directory name to store downloaded files, registry key names where additional payload are persisted, and as a unique identifier for the C2 server.
- Next, If the malware is already persistent in the registry, don’t bother running the payload again. It will execute again at next reboot.
- Define a function to resolve DNS TXT records and download and decompress a zip file located at the URI in the resolved TXT record. Both Tor and Polipo are downloaded via this function.
- Mark the downloaded file directory as hidden.
The next portion of the payload executes tor and polipo, a requirement for communicating with the C2 server and downloads and executes the next stage of the attack:
For those unfamiliar with common malware techniques, what should be worrisome about the fact that additional PowerShell code is downloaded and executed is that the malware authors have complete control over the downloaded content. The analysis that follows describes the instance of the malware that I downloaded. The malware authors could very well change the payload at any time.
The downloaded payload starts by persisting three additional Base64-encoded payloads to the registry.
The Trend Micro article neglected to mention the two payloads saved in the registry at the following locations:
HKCU:\Software\Microsoft -> {Machine GUID}0
HKCU:\Software\Microsoft -> {Machine GUID}1
$EncodedPayload1 and $EncodedPayload2 are essentially equivalent to the initial payload included in the Excel macro – they serve to reinfect the system and download/execute any additional payloads. $EncodedPayload3 contains all the logic to infect Office documents.
The malware then collects information about the compromised system and uploads it to the C2 server.
Finally, the Office document infection functions are called and if an additional payload is available, it is executed. I was unable to retrieve the additional payload during my analysis.
The Office document infection payload implements the following functions:
- Start-NewDriveInfection – Registers a WMI event that detects when a new drive is added (e.g. USB thumb drive) and infects all Office documents present on the drive
- Invoke-OfficeDocInfection – Infects all Office documents on the drive letter specified
- Start-ExistingDriveInfection – Registers a FileSystemWatcher event to detect and infect newly created Office documents
- Set-OfficeDocPayload – Adds a macro to the specified Office document
- New-MaliciousMacroPayload – Generates a macro based upon one of the payloads present in the registry
- Set-ExcelDocumentMacroPayload – Infects an Excel spreadsheet
- Set-WordDocumentMacroPayload – Infects a Word document
In order to programmatically create/modify/remove Excel and Word macros, macro security must be disabled in the registry with these commands:
Set-ItemProperty HKCU:\Software\Microsoft\Office\*\*\Security -Name AccessVBOM -Type DWORD -Value 1
Set-ItemProperty HKCU:\Software\Microsoft\Office\*\*\Security -Name VBAWarnings -Type DWORD -Value 1
After the registry values are set, you will no longer be prompted to enable macros. They will execute automatically without your knowledge. Also, be mindful that if a macro is present in an Office document and you attempt to analyze it with the Word.Application and Excel.Application COM objects, the macro security settings are not honored and the macro will execute without your permission. Before opening an Office document with the COM objects, you must explicitly disallow the execution of macros by setting the ‘AutomationSecurity’ property to ‘msoAutomationSecurityForceDisable’.
The Word document infector is implemented as follows:
What’s interesting is that once the macro is written to the Word document, it is downgraded to a ‘macro-enabled’ .doc file.
Once a document or spreadsheet is infected, it will download and execute another PowerShell payload. I was unable to successfully download any additional payloads during my analysis. Either I was not emulating C2 communication properly or the payload was not made available at the time.
So in the end, I was rather impressed by the effectiveness of which the PowerShell payloads infected Office documents. It has yet to be seen though the true power of this malware until additional malicious payloads can be downloaded from the C2 server.
Should you become the victim of a “Power Worm” infection or any malicious Office document for that matter, I’ve provided tools to detect and remove “Power Worm” and Word/Excel macros. You can download these tools from my Github repo.
Great write up Matt!
ReplyDeleteMy read is that they are just using PowerShell because it is a nice powerful language and that if PowerShell wasn't there, they could do the same things another way but it would be harder. Is that correct?
From your analysis, is there anything that we can/should be doing in PowerShell that would help protect users from attacks like this?
Thanks!
Jeffrey Snover [MSFT]
Thanks Jeffrey!
DeleteYou're absolutely right. If PowerShell wasn't there, they would have most likely stuck to VBScript to infect Office documents as well as to download and execute PE executables. Using PowerShell offers the flexibility to do everything without having to drop any binaries to disk.
My best recommendation for improving the overall PowerShell security model would be to emulate the Windows RT implementation of PowerShell - enable constrained language mode by default. While it wouldn't remove the impact of malicious PowerShell scripts altogether, it would severely limit the impact out of the box.
Thanks for your input!
Cheers,
Matt
That's an interesting idea, though it would cripple a lot of legitimate PowerShell use as well. Ideally, there would be ways to enable full language mode while still maintaining a reasonable barrier against malicious code. Perhaps signed scripts from trusted publishers automatically run in full language mode, and add a cmdlet that presents a UAC-style prompt on the secure desktop, if a user wants to enable full language mode in an interactive console.
DeleteHey Dave,
DeleteThanks for you comment and insight. I completely agree.
You're right about constrained language crippling legitimate uses of PowerShell. It was implied but I should have explicitly stated that from an elevated prompt you would be able set non-admin language modes accordingly. Just like Set-ExecutionPolicy, I imagine a cmdlet like Set-LanguageMode that can only be set from an elevated session.
Regardless of the implementation, I think it's safe to say that unless restrictions are put in place out of the box in PowerShell for non-admins, malware like this will continue to flourish and be successful (unless the user is already running as admin, of course).
I would suggest starting a "Great Debate" on powershell.org discussing reasonable implementations for locking down PowerShell out of the box. It would be great way to get the broader public engaged on an important topic like this.
Regards,
Matt
Done: http://powershell.org/wp/2014/04/09/community-brainstorming-powershell-security-versus-malicious-code/
DeleteThanks, Dave!
DeleteHi,
ReplyDeleteWould you please provide the actual malware code? We would need it for further analysis and custom signature creation.
Thanks,
Alex
Hi Alex,
DeleteThe best I can so is provide the hashes:
2D0CF7D1E257F2757EF58F8BE2BC1628
D96546DD69DAEE76A30F82F57DCB2A11
D9C9384373597F1A170E29CE70C337FE
D2F53B20B56B8304B4980F7A76126D6E
6EE1BA5CF9AEFF651A2F95E2BBA46285
3614BBE081F4B43DE46AB917F3148DBC
D529278A342110DB95D17E2195D0FE96
32A51C40AC1D026181B374174048239E
2D0CF7D1E257F2757EF58F8BE2BC1628
D96546DD69DAEE76A30F82F57DCB2A11
B0A7AC8A0CDAE0AF886B72BBAFD0F6CA
AFED5A670DF53CFD6DA766721CCCB9FB
507642F01C546DA66B2CA85B378D2CF3
B0B1776B55D1906DADA2504A32DD3A4C
F52839508CE333915BF6439AA5DEB8F5
D904F19ED6037CB2A7510E1DA6D02A9E
DBEBBE796F649841581E117B0F64747B
2DF14B83C8E0335CEAAC636D4EC09073
To Alex and any others that are trying to create signatures for the malware:
ReplyDeleteIn one of the instances for the encoded powershell scripts, when I decoded the Base64 string, there was a lot of gibberish between different lines of code. A smart hacker would modify the script by adding any random strings as you will see below. When Base64 encoded, this will result in a different signature (i.e. they could replace 'TYfpMAifj'; with 'sSDrgoSqd';). Just something to be aware of.
'GXBtDNYIjd';
$ErrorActionPreference = 'SilentlyContinue';
'TYfpMAifj';
'dNmYWaHeOcM';
Thanks!
Anonymous
This is awesome. I've been using bits and pieces of this already but this is a very nice all in one package we can use at work; with a bit of our own spin of course. Thanks!!!
ReplyDeleteBe sure to thank our friendly malware author[s]. I just provided the analysis. ;)
DeleteHow did you convert the base64 to a decent script sources ? I tried with base64 then to byte array then to string but without luck.
ReplyDeleteThanks a lot.
Encoded PowerShell commands need to be Unicode encoded so the following one-liner will get the job done:
Delete[Text.Encoding]::Unicode.GetString([Convert]::FromBase64String('BASE64STRINGHERE'))
There is an example as well in 'powershell.exe /?'
-Matt
There is a updated version of this, possible the payload that didnt execute as you were talking about that encrypts the victims files. I have analysed it, and also have gotten it to a readable state. If your interested i have explained it here:
ReplyDeletehttp://www.bleepingcomputer.com/forums/t/530294/poshcoder-malware-removal/?p=3338793
Yeah, but he says this doesn't allow him to decrypt the files. Is he missing something?
DeleteYep. I hadn't had my coffee yet and jumped to conclusions. O.o
DeleteMatt, what about one drag and drop tool to check if a certain office doc (excel, powerpoint etc.) can have a posible powershell infected macro?.
ReplyDeleteI'm not aware of a drag and drop utility. Using PowerShell is easy enough for me and it allows you to scan a lot of documents quickly.
DeleteFrom your third paragraph and "The payload is a single line of semicolon delimited PowerShell commands." Correct me if I'm misunderstanding this but, is this to say that even if you have a *restricted* execution policy the malware would still run so long as PowerShell is present?
ReplyDeleteThat's correct. The execution policy restricts the execution of scripts (i.e. ps1, psm1 files). The execution policy has no effect on commands passed via -Command, -EncodedCommand, or in the shell itself.
DeleteBy all means, validate these claims yourself and please tell your colleagues that malware authors know this and will never run into a situation where the execution policy is the reason their malicious PowerShell code was prevented from executing. :)