John Hammond, security researcher with Huntress, requires a deep-dive into a malware’s technical and coding features.
Click, and boom, your network is compromised. All a hacker wants is just one prosperous exploit and you could have a incredibly poor working day. A short while ago we uncovered one artifact that we would like to break down and showcase. We will get “into the weeds” below and really deep-dive on the technical facts, so put on your ear protection and let’s stroll down variety.
The Cigarette smoking Gun
Recently, Huntress’ ThreatOps staff uncovered just one malware artifact that I would like to break down and showcase.
Whilst at 1st look this appears to be like like gibberish, we can choose it apart and comprehend what is genuinely occurring right here. We will transfer by way of the code in a procedural fashion, taking 1 line at a time and knowing the syntax.
The 1st issue to take note is that this took the form of a Windows “batch” script, or a file with a .bat extension. Batch scripts are interpreted and executed by the Windows command prompt, or the “cmd.exe” method. cmd.exe is the default command-line interpreter for Windows running techniques, but it is an older utility that dates again to DOS (or the Disk Operating Method). In the environment we stay in now, builders and security professionals desire to do the job in PowerShell, a much extra contemporary command-line shell and language.
PowerShell will be introduced listed here in just a moment, but initially we have to focus on the variations in syntax. Variables in PowerShell are denoted by a “$varname” syntax, with the title of the variable remaining prefixed by a dollar-signal. In cmd.exe batch scripting, variables are indicated like %varname%, with the variable name wrapped in %-signs on possibly aspect. In the scenario in this article, we see an environment variable currently being referenced, %COMSPEC%. The worth of this is:
That value will be place in place exactly where the %COMSPEC% syntax is. When executed, it will start off cmd.exe with the parameters and arguments that adhere to. In our “weaponized” analogy, we can get in touch with these starting parts of the payload, the result in.
The Bring about
The /b argument to cmd.exe implies “Start the application with no making a new window” so our hacker is seeking to hide. /c suggests “run a solitary command and exit”, which clarifies that the rest of this code will essentially execute.
That get started command that follows will spin off a new method, yet again with the /b to enforce no window is established. The /min argument appears to be to be extra for just additional evaluate – the software would start off minimized (if, for some reason, a window ended up to be designed with the /b argument)
Following that, we see powershell.exe is the application commenced. It also features several arguments, like -nop (do not instantiate with a startup profile), -w hidden (yet once again, do not make a window), -noni (do not operate in interactive manner) and lastly -c (execute a single command and exit).
At this stage, we have eventually produced into the string of code that is handed into PowerShell. This does a number of checks to guarantee the payload remaining utilized for the goal is correct.
At the quite start off of the PowerShell syntax, we see:
This if assertion conditional is exciting, because it checks if the dimensions of the “integer pointer” knowledge sort is equal to the selection 4. This could possibly appear to be like kind of a random examine, but it’s truly a intelligent process to ascertain the target’s process architecture. A 64-bit laptop would have an IntPtr dimension of 8, referring to the duration of memory addresses. A 32-bit program would have an IntPtr measurement of 4, so the code establishes the path of PowerShell dependent off the architecture. The $b we see produced as a PowerShell variable to keep the path of the PowerShell executable.
Just subsequent that if statement, we see the subsequent bit of code:
This results in a different PowerShell variable $s, this time becoming defined as a new item. In this circumstance, the item created is a new course of action, with the filename becoming established to $b (as we now know is the path to PowerShell) with arguments like we have observed before. But yet again, we are spawning another PowerShell instance, with no profile and a concealed window.
For the command ran by the new, innermost PowerShell occasion, we see this syntax:
The [scriptblock]::generate contact defines new code to run. The New-Item IO.StreamReader permits us to read the code “on-the-fly”, pulled in from the passed in information.
The data we see is wrapped in these capabilities: IO.Compression.GzipStream, IO.MemoryStream and [Convert]::FromBase64String, with the GzipStream employing a Decompress flag.
This indicates that the huge block of seemingly gibberish and nonsense figures is actually Foundation64 encoded GZIPed details.
Foundation64 is an encoding plan that just signifies information in a distinctive structure. Decoding the details is trivial – you just do the inverse procedure. GZIP data is compressed, archived info, almost the same as a .ZIP archive you may possibly see as a file on your pc. Luckily, we can complete the inverse operation on that massive chunk of knowledge to far better realize what it is doing.
But initially, let’s wrap up the analysis on the rest of the code.
The Silencer & the Shooter
Just right after the blob of Foundation64, we see these lines of code:
I jokingly refer to this phase as “the silencer,” simply because it however once more attempts to mask and hide the new PowerShell instance. That $s is our new procedure, with configuration values currently being set to hide the window, do not develop the window, and really don’t keep keep track of of conventional output or invoke a new shell.
And of course, just subsequent this snippet we see what truly fires the gun.
This line will start our new course of action and the decoded and uncompressed code inside the Foundation64 blob will execute. Now that we have a improved knowing of how this will work, we can zoom in on that blob of info.
Inside the Ammunition
The true substance with this launcher comes from the Foundation64 encoded, GZIP compressed blob that is extracted and executed on the fly. That is this chunk:
We can carry out the reverse operations with any toolkit we would like, no matter if it be on the command-line, or Python, or even with CyberChef.
For convenience’s sake, we can do this with CyberChef.
This returns with, unsurprisingly, additional PowerShell code. As we by now know, this will be executed by the launcher. The output dump appears to be like so:
Naturally there is a good deal to unpack in this article. This PowerShell code is at minimum fairly readable in that there are apparent newlines and whitespace — but variable names and some of the logic is nevertheless obfuscated. We will make feeling of it piece-by-piece.
Analyzing the Gunpowder
The first functionality that we see described in this PowerShell code is named sOH, which is not quite descriptive. All of these purpose and variable names seem to be random and obfuscated, but we can make perception of them by reading through the definition of the perform.
The soH perform normally takes in two parameters. It employs a strategy to “reflectively” research for the handle of Earn32 API phone calls, so that PowerShell has the capability to operate these main, inside strategies recognised to decrease-stage functioning program. In the latest context, it queries for where by the Procedure.dll could be loaded, and employs that to obtain a wanted function name within just other DLLs that it could then execute. The title of the DLL this purpose is a component of, and the Win32 API operate itself that must be called, are the two values passed in as parameters to this sOH operate. This is all completed by making use of “reflection,” the means that makes it possible for PowerShell to execute some introspection and glance up now-defined treatments.
In the end, this offers PowerShell considerably a lot more electrical power. Getting accessibility to operate the Gain32 API features will allow it to do factors like allocate memory, copy and go memory, or other peculiar items that we will see in the code pretty quickly. For our very own knowing, we ought to mentally rename this purpose to some thing like:
So far, what we realized as the sOH purpose provides a portion of this new capacity. If hackers want to use this tradecraft to invoke Win32 API function phone calls within PowerShell, they also require the features to do the job with “delegates.” The next perform, b9MW, finishes the “boilerplate” code wanted to be capable to do this.
As you can see this is overflowing with the Windows internals necessities and fluff that make this operate. We will not do a ton of in-depth investigation with this code, detailing each and every and every single line and variable, but this purpose now delivers the features to interpret Acquire32 API functionality parameters and return values.
Considering that our hacker is making out the operation to be ready to call Earn32 API functions with PowerShell, they wanted this sOH course of action to be in a position to uncover and find the capabilities, and this b9MW method to supply parameters and fully grasp the perform return values.
With these two functions in area, the code now has the primitives to freely contact any Gain32 API perform it would like. Following, we will see this in action.
Adhering to those people function definitions, this PowerShell snippet defines an array of bytes, pulled out by decoding more encoded Foundation64.
Decoding this Base64 unfortunately offers us a large amount of non-printable characters.
We can go so much as to say this is shellcode, or processor directions as opcodes that will be executed. Considering that this binary details we simply cannot quickly make perception of it, but we do know this malware does conclude up utilizing shellcode.
Just beneath this we see:
Now a $sC6US variable is in perform, calling the GetDelegateForFunctionPointer perform, with our freshly outlined sOH and b9MW functions. Keep in mind, these functions permitted the hacker to load Get32 API features — and in this circumstance, we can see they have pulled out the VirtualAlloc operate.
This VirtualAlloc functionality tells the functioning procedure to allocate memory. As we can see from the operate parameters, it invokes this operate to allocate adequate memory for the size of the $bUMJ byte array (the shellcode)! The 0x3000 suggests “reserve and dedicate this memory,” and the 0x40 signifies “this memory really should be readable, writable, and executable.”
At this position, the allotted memory room is saved in that $sC6US variable. Then, we see a Duplicate function called to fill that memory space with the shellcode byte array, $bUMJ. The destructive script has now allocated memory for the shellcode, and we can acquire an quick guess as to what they will do upcoming: Operate the shellcode.
Future, a $t6Y variable is developed, again reaching for and contacting a Gain32 API contact, this time specially CreateThread . This CreateThread contact is invoked with the $sC6US memory handle – which as we now know, is made up of the shellcode. In the end, this executes the shellcode!
Pursuing that, we see one much more connect with to operate the WaitForSingleObject Win32 API purpose.
This will “block” execution and patiently hold out for the shellcode to finish executing. You can see it involves the $t6Y variable (which is the new thread functioning the shellcode), and the 0xFFFFFFFF signifies “wait permanently.”
Last but not least, right after all these nested layers, obfuscation and abstractions, the malware has loaded shellcode into memory and executed it. The upcoming problem is, what accurately does this shellcode do?
As security analysts, we nevertheless have work to do. We can monitor the behavior of this malware – enjoy to see if it results in any new documents or calls out to any other exterior endpoint. The shellcode alone appears to be incredibly tiny, so most likely that is a stub to load even more malware. Though this article centered exclusively on understanding the PowerShell launcher, possibly the upcoming a person may possibly assess the shellcode inside of a debugger like “scdbg,” or observe the malware working in a contained sandbox.
We dove below the hood right here to additional have an understanding of what the hackers did and how their payload labored. Finding out from the offense is the most effective way to have a more robust protection. Some mitigation methods, like enabling AppLocker or PowerShell Constrained Language Mode, would at the very least block the execution of this preliminary launcher, and the hackers would have to perform more difficult. At the conclude of the working day, that’s our target: Make hackers gain each individual inch of their accessibility.
John Hammond is a security researcher at Huntress as nicely as a cybersecurity teacher, developer, red teamer and CTF fanatic.
Get pleasure from additional insights from Threatpost’s InfoSec Insider local community by visiting our microsite.
Some elements of this post are sourced from: