Analysis of a Suspicious Piece of JavaScript

Published: 2017-02-12
Last Updated: 2017-02-18 01:44:32 UTC
by Xavier Mertens (Version: 1)
1 comment(s)

What to do on a cloudy lazy Sunday? You go hunting and review some alerts generated by your robots. Pastebin remains one of my favourite playground and you always find interesting stuff there. In a recent diary, I reported many malicious PE files[1] stored in Base64 but, today, I found a suspicious piece of JavaScript code[2]. It was posted by a valid account but it was its first pastie (with a validity of one month). Here is the sample (beautified):

 1 : var _2519;
 2 : var _6101='34280B84F123A777A741D825 ... stripped data ... F713C589E';
 3 : var _9332=/[\x41\x42\x43\x44\x45\x46]/;
 4 : var _3352=2;
 5 : var _3603=_6101.charAt(_6101.length-1);
 6 : var _9837;
 7 : var _4678=_6101.split(_9332);
 8 : var _4029=[String.fromCharCode,isNaN,parseInt,String];
 9 : _4678[1]=_4029[_3352+1](_4029[_3352](_4678[1])/21);
10 : var _5991=(_3352==4)?String:eval;
11 : _9837='';
12 : _11=_4029[_3352](_4678[0])/_4029[_3352](_4678[1]);
13 :  for(_2519=3;_2519<_11;_2519++)
14 :     _9837+=(_4029[_3352-2]((_4029[_3352](_4678[_2519])+_4029[_3352](_4678[2])+ \
         _4029[_3352](_4678[1]))/_4029[_3352](_4678[1])-_4029[_3352](_4678[2])+_4029[_3352](_4678[1])-1));
15 : var _8383='_1472';
16 : var _2078='_8383=_9837';
17 :
18 : function _6430(_9378)
19 : {
20 :    _5991(_1667);
21 :    _6430(_3473);
22 :    _3473(_2078);
23 :    _6430(_8383);
24 : }
25 :
26 : var _1667='_6430=_5991';
27 : var _3473='_3473=_6430';
28 :
29 : _6430(_3603);

It's an interesting example of code obfuscation but not very complicated to reverse. After a quick check, we may assume that the malicious code is stored in the variable '_6101' (line 2) and that the rest of the code is just used to deobfuscate it. Note also the presence of the string 'eval' in 10. This should get you thinking. Let's review the code line by line:

Line 3, '_9332' contains the following string (hex-encoded): 'ABCDEF'.

Line 5, _3603 contains the last characters of the payload: 'E'.

Line 7, the payload is split based on the separators 'ABCDEF' and stored in _4678. It contains:

34280,84,123,777,741,825,741,813,749,809,773,801,817,585,481,825,741,809,481,689,773,817,785,757,481,597,481,489,621,669,625,629,481,693,665,633,681,645,629,665,625,481,617,709,481,709,741,793,765,593,541,613,601,489,589,393,825,741,809,481,625,757,813,749,809,773,801,817,773,797,793,813,481,597,481,489,489,529,393,481,481,481,481,733,817,757,833,817,481, ...

Line 8: _4029 contains an array of JavaScript functions

Line 9:  _4678[1] contains '4' (String(parseInt(84)/21) = 4)

Line 10: The most important one:  _5991 contains the 'eval' function! (The condition never matches: 2 != 4)

Line 12: _11 contains the length of our payload: 8570. (parseInt(34280)/parseInt(4) = 8570)

Line 13: The main loop will process all integers in _4678 (see above). Deobfuscated characters are stored in _9837:

_9837 += (String.fromCharCode((parseInt(_4678[_2519])+parseInt(123)+parseInt(4))/parseInt(4)-parseInt(123)+parseInt(4)-1))

Starting from line 15, more obfuscation is performed to fool the analyst. The function _6430 is in fact just a call to eval() which executes the code stored in _9837.

function _6430(_9378){
    _5991(_1667); // eval(_6430=eval)
    _6430(_3473); // eval(_3473=eval)
    _3473(_2078); // eval(_8383=_9837)
    _6430(_8383); // eval(_9837)
}

What is stored in the variable _9837? Is it malicious or just suspicious? The payload passed to eval() is a JavaScript code called "CODE UNFRIEND by Yang". It looks to be a script to massively remove friends from a Facebook account. I posted a copy of the de-obfuscated payload on pastebin[3]. If it rings a bell to you, let me know.

[1] https://isc.sans.edu/forums/diary/Many+Malware+Samples+Found+on+Pastebin/22036/
[2] http://pastebin.com/raw/DmxeKdgw
[3] http://pastebin.com/yBWnQQ5P

Xavier Mertens (@xme)
ISC Handler - Freelance Security Consultant
PGP Key

1 comment(s)

Comments


Diary Archives