Sometimes the malware we find here at Huntress just makes us laugh.
Not because it’s funny (is malware ever funny?) — but because the code we review sometimes makes no effort to hide its actions.
We talk about obfuscation in a lot of different blog posts, where hackers at least try to cover up their techniques. Obfuscation means obscuring the original source code by making it difficult to understand with confusing variable names or encoding schemes.
Is This Some Sort of Joke?
No, seriously, our analysts have really seen malicious binaries that include the root (administrative) credentials to access the hacker’s staging server, outright in plaintext.
Recently, we found this malware sample written in JavaScript, with the filename explorer.js
. Take a look: no tricks up their sleeve, the code contains the C2 servers without any obfuscation whatsoever.
Well, we didn’t have to try too hard to figure that one out! No detective work needed.
This COMMAND_C2
list contains both fake and legitimate domains. While the latter domains certainly look suspicious, the redirector.gvt1.com
domain is known to be owned by Google. That is unlikely to be hosting malware or being used by C2 operations — if anything, the implant might reach out to it to hide alongside normal network traffic and "look legit."
If you haven't seen these other domains before, feel free to add them to your IOC library or block them.
http://onecs-live.azureedge.net
http://ipm-provider.ff.avast.com
http://tauhutxiga.com
http://monsuperentrepreneur.com
http://tangocation.com
http://e4a24fb0e.com
http://f78efaf43b.com
That’s the Punchline
The takeaway here is that some hackers are bold and have the audacity to include these sensitive details right in their attack. If you think about it… why would they bother obfuscating? If this malware is still going to be effective, and your antivirus or EDR solution doesn’t pick up on it, who needs to go through all those extra steps?
We wanted to share this with you because, hopefully, you get a chuckle out of it too. Maybe we have a strange sense of humor laughing at malware?
But Wait, There’s More!
It wouldn’t be a Huntress blog post if we didn’t go through at least some analysis of this malware, would it? After further research, it seems this sample is dubbed throughout the community as "Valak
."
So let’s dive into the rest of this JavaScript code. Beneath the client_config
definition you saw above, the code continues with this:
Here, a Client
object is being defined, and stitching in a property CoMainObject
so it can access the WScript.Shell
functionality.
We said this was JavaScript code, but because it is loading a ActiveXObject
we can safely say this is JScript (the Microsoft-specific dialect of JavaScript, that can access more Windows internals via Internet Explorer).
It uses this WScript.Shell
in an inline LoadLibraryReg
function, which we can see reads the contents out of a Windows Registry value. This Registry data must be something pre-planted with the malware.
HKEY_CURRENT_USER\Software\ApplicationContainer\Appsw64\WebLib32
We can see just following that—the LibraryLoadContext
function seems to eval
the contents of that Registry value. The eval
statement executes a string value as if it were code. Just after, more properties are set for the Client
object like .Windows
and .GlobalStrings
all pulled from a variable with a corresponding name. So, we can deduce that Registry value contained more JavaScript code that has now been brought into this context.
One interesting property that has been set it is the .DataTools
variable. We will see that used throughout the rest of the code.
Crafting a C2 Endpoint
This next function defined in the JScript code seems to build out an endpoint that can be used for C2. Interestingly enough, now we start to see some obfuscation, getting a .Random.String
with a length of a 12 for a nonce value (built within that .DataTools
property), and a RotString
which we can assume is a rotation cipher.
Additionally, we see a call to Base64Encode
, which is a function actually included in the malware sample. It simply performs a Base64 encoding on the argument passed in. With that, the function returns a potential endpoint that can be used for C2 dirty work.
Ready, Set, Execute!
In the next segment of code we see two new functions, PrepareExectionTask
and ExecutePlugin
. Yes, that typo is really in the source code — it is in fact Exection
.
The PrepareExectionTask
function is interesting, because we see it calculates the current time and then properly handles it as a string, and even adds a minute buffer. We then see the code prepare both an execCommand
and taskCommand
separately, using the Windows Management Instrumentation (WMI) and a “task” to execute the code.
This preparation of a time
variable, adding an extra minute to the current time and the creation of a “task” variable leads us to believe the malware is in fact creating a Scheduled Task to execute what it needs to. The .GlobalStrings
properties WMIC_EXEC
and TASK_CREATE
are used to craft a custom command that is populated with the arguments passed in.
The ExecutePlugin
function seems to prepare a command, utilizing a file present in the TEMP
directory based off of this specific target’s unique identification number. Again, it prepares a WMIC command and executes it — this time without the use of a Scheduled Task.
Considering this pluginID
is passed as an argument to the unique .bin
file mentioned in the code, that .bin
file is likely already present on the victim, pre-planted much like the Registry value. These act like beacons and this C2 code controls the implants to run commands and continue post-exploitation ops.
What Are My Marching Orders?
Personally, I think this is the most interesting function to look through.
This is the .GetTask
function that our Client
object can perform — and it begins with a for loop, that iterates through all of the C2 servers we saw previously, to check if there is a new task for it to execute.
Using this loop across each and every domain that we uncovered at the beginning of this blog post actually gives the attackers a lot of control because there are multiple. If one domain were “burned” (i.e. discovered by analysts), there are still more in the hacker’s back pocket. Also, having a domain name burned is much better than having an IP address burned. Domains are expendable to hackers. They can easily be replaced. IP addresses? Not so much — that requires more infrastructure for redirectors, proxies and more effort than simply changing a domain name.
We can see in the code that it makes an HTTP request to each C2 server with the endpoint URL the client generated earlier. It collects this response, decodes it with its DataTools
magic, and then examines the contents.
if(response.indexOf("--TASK") !== -1){
This condition checks if the marker --TASK
is present in the response. If it is, it starts to carve out and extract the details. We see that with the .replace()
and .split()
calls, using the --
as a delimiter.
It seems that the decoded response may have a format like so:
--TASK--
--
JXd0dGFoeCUlam5nb3ElJXBhcGJldCUlZ3dkb3klJWxram1qJSVudHFpJSVza214YiUl
eXhicXhmJSVudHFpJSVkcHBtdG8lJWRibGNqeSUleGpiZ2IlJWZiYWt4byUldHF3bnVx
JSV4aW1nbnklJXFxb3UlJXBhcGJldCUld2J5dCUlbnRxaSUleGhwbm5kJSVvcGZsciUl
ZG1obGp2JSVtdGJyb2IlJW50cWklJWh3YWd0diUlaGJqZXdqJSVqd2R1YiUlanBzZmhn
JSVtcWhvZmUlJWVsbHBqJSVvbnFkd3IlJXRycGpxJSVkcndjJSVubWRsJSVudHFpJSVo
dGJxY2klJXlhdHR5JSVsZ3F3b24lJXJ1bHIlJW93bWRuJQo=
--
taskname
The code indicates that the executionTask
is received as Base64 data, and then the taskname
follows, separated by those --
delimiters. It prepares the task with the functions we saw previously, and as we know from that analysis, it executes it.
With that functionality in place, the hackers have a homegrown solution to handle command and control communications on the victim. They have prepared enough primitives and building blocks to at least gain code execution and operate on the target — all within JScript.
There are a lot of other peculiar and interesting functions, especially within the loaded registry code. Some that may be worth your eyes:
Loader.DeployClient
, establishing the targetLoader.Persist
, placing thisexplorer.js
stub and registry dataExecute
,GetEnv
,CreateFile
,GetArch
and other enumeration niceties
For the curious l33t cyber ninja warriors, you can find the source code for the original C2 stub we discovered here, and the extra arsenal loaded in from the register here.
We briefly mentioned this was a variation of the known "Valak" malware. In that original client_config
object within the source code, you can see numbers defined for SOFT_VERSION
and SOFT_SIG
, which seem to refer to the specific strain of the malware being used on the target. If you are interested in other great research or articles on Valak, feel free to Google around or check out articles like these.
So What?
Now that we have wrapped up all the technobabble, we can understand why this strikes a chord.
We say all the time, “hackers are getting smarter,” “hackers are becoming more sophisticated,” “hackers are using new tricks,” etcetera. While this started out as a good laugh, with the implant not even obfuscating the C2 servers, it goes to show sometimes even that can slip by.
If we look back at what we might dare to call “traditional security,” we see ourselves with a cookie-cutter firewall and antivirus product. We flip the switch, fire those suckers up, and let them do their magic with a set-it-and-forget-it mentality. Hopefully, the automated security tool finds evil, notifies you and goes to fix it…. but what if it doesn’t?
What if the automated solution fails?
Actively hunting for evidence of compromise is what leads us to a better defense. With manual analysis supplementing automated analysis, your security stack has fewer false positives, fewer false negatives and the problem can be stopped at the source.
Dragging ourselves through code and looking under the hood to see how some malware works? That helps us find those indicators of compromise, the tradecraft and techniques the bad actors use and what defensive safeguards we can put in place to mitigate attacks like this.
In the same way that hackers are stepping up their game, we as security researchers need to just as well.
If you're interested in diving deeper into this topic, watch a webinar I did discussing how hackers can exfiltrate data or run post-exploitation with their own C2.
