John Hammond 02.2.2021

Bring Your Own Command & Control (BYOC2)

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 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.

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.


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 the 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 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:


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 target
  • Loader.Persist, placing this explorer.js stub and registry data
  • Execute, 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 less false positives, less 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. 


John Hammond

Threat hunter. Education enthusiast. Senior Security Researcher at Huntress.