Malware Analysis: SocGoulish JS Dropper

This is a quick analysis of a SocGoulish dropper. The JavaScript defines a series of functions, a variable that contains the URL it attempts to download from at a later point, and then calls a "request" function that will download...

Malware Analysis: SocGoulish JS Dropper

This is a quick analysis of a SocGoulish dropper that was uploaded to Malware Bazaar by @x3ph1 on July 1st, 2022. SocGoulish ('Soc' for social engineering) is a banking trojan malware family that functions by tricking users into downloading and executing fake software updates. It is often seen targeting web browsers like Chrome and Edge or other common software such as Adobe Acrobat.

The JavaScript defines a series of functions, a variable that contains the URL it attempts to download from at a later point, and then calls a "request" function that will download additional JavaScript and then execute it with an obfuscated "eval" call.

Note that all code screenshots in this writeup are paired with a deobfuscated counterpart. This analysis was conducted on an isolated lab machine WITH a connection to the internet.

Reverse Engineering Edge.js

The related tweet from by @x39h1 says that the file was originally name "Edge.js", suggesting that this particular variant targeted the Edge browser. The file is a short, simply obfuscated JavaScript file that attempts to download the next stage of malware. At the bottom of this post I've provided a copy of it in its original form as well as a copy that I deobfuscated.

Original tweet from @x3ph1.

The first thing it executes is a function to decode the URL where it will download the next stage. It works by removing every other character and reassembling what's left in reverse order (which results in a correct URL as the original hidden URL was already reversed). It's using a modulus operation against the number '2' in order to only extract characters on odd loop count numbers. It's using the modulus operation results as a boolean value. Since JS like most languages evaluates non-zero values as "true" and zero as "false" it only executes when there's a remainder on the modulus operation.

Note: a 'mod' or 'modulus' operation is division that only returns the remainder. They are typically represented in code using a percent sign (%).

Screenshots of code that decodes and reverses the URL.

After this, it makes a function call to "request" within another call to an obfuscated eval function. Eval calls  in JavaScript are used to execute objects/variables that contain additional JavaScript. They're not commonly used for normal JS uses and finding "eval" in JS code is often used for generic malware alerts. To bypass this, there's a small function that breaks up the text while assigning it to a variable

Screenshots of the obfuscated and deobfuscated code.

The request function will send a web request to the URL seen above in the deobfuscated code and then returns the response so the obfuscated eval function can execute it.  It contains two major function calls, one the builds the http request data and then another that actually sends it. Neither are particularly complex.

The first function encodes each item using a 'encodeURIComponent()' call and then puts them in the format of a parameter with the loop count being each parameter's name. They're assembled as each one is completed in the loop and returned as one string.

Obfuscated code that builds the web request.
Deobfuscated code that builds the web request.

The function that actually sends the request is pretty straight forward, though it's still deobfuscated. It creates a MSXML2.XMLHTTP active-x object and then uses it to send a post request to hxxps://ff477f92[.]app[.]pgica[.]org/pixel.png with the parameters that were just assembled.

Obfuscated code of the http request function.
Deobfuscated code of the http request function.

Of course after the request is returned it then passes the response back to the eval function. From what I can tell, the second parameter that I renamed to "http_send_param2" will never actually hold a value, so the else statement will always be the one that is returned here meaning that the 'responseText' is what will be executed.

We can confirm the code-level analysis be replacing the eval call with some WScript echo statements and then executing the file with CScript.

Confirming analysis using the WScript Echo call.

Now that we know what the next stage of the malware is, we can use a safer method of pulling it back using Invoke-WebRequest in PowerShell. Using a user agent string from useragenstring.com for the up-to-date chrome version, I attempt to pull the next stage down. I also had Fiddler running as a proxy with it configured to break SSL so I could monitor and capture the actual data being transferred.

Command to make the web request and the response in Fiddler.

Unfortunately I only get back a 204 'no content' response. This particular URI or parameters have been burnt or already remediated by the website owner. The file had previously been submitted to Virus Total and the sandbox there observed it downloading a .dll. Without having the second stage to analyze, I'm not left with much else to do besides move on to the next analysis.

Oh, and upload^ the files.