We’re seeing more and more malware that is “Living off the Land,” turning a system's own native tools against itself. In other words, it uses the features and tools that are built into the operating system, such as Windows PowerShell, to perform a malicious activity and avoid detection.
In this post, we’ll examine a malicious payload that was executed using PowerShell. We found this on one of our partners’ hosts starting from a Run Key value. Let’s dive in.
HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run value named
. Well that’s odd.
The command (value data) is also strange. PowerShell is reading another registry value with the same value name under
We can also see that the data the PowerShell command reads from the
HKLM\Software\ value is a base64 string. And not only does it look like base64 but the PowerShell command confirms it by using
Decoding the Payload
Here's what the base64 string looks like:
Now we'll use Python to decode the the base64 data.
>>> data = "JABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAE0A[SNIP]"
>>> import base64
The decoded data above looks like a UTF-16 string (just look at all the
\x00 bytes). And just below, Python was able to turn this into something we can easily read.
'$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 peek by base64 decoding it and using Gzip to decompress it.
Here is the full script that was Gzipped and base64 encoded:
In the decoded script above, we can see another base64 encoded string (line 37), 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
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.
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.
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.
Now we've found our downloader.
• • •
We really dove under the hood here to further understand how this malicious code functioned and how the payload worked. We can see how attackers use these “living off the land” techniques to reduce their chances of being detected—and learning from their offensive techniques is the best way to have a stronger defense.
Curious what’s lurking in your networks?
Hackers are constantly evolving, exploiting new vulnerabilities and dwelling in SMB environments—until they meet Huntress.
We offer a 21-day trial of Huntress for an unlimited number of endpoints. Simply deploy our agent, set up 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).