长亭百川云 - 文章详情

最近CDN供应链事件的曲折分析与应对-业务安全

lufei

49

2024-07-18

一、前言

假如业务的JS文件被外部人员控制,并且是针对性利用(多种bypass监控),对业务来说是一次灾难,对最近CDN供应链事件进行了分析(艰难)。

之前也分析过类似事件:BootCDN供应链攻击分析与应对

二、如何触发到有问题的JS

这里使用python批量请求,然后变换User-Agent 以及Referer(当然必要时候挂代理),然后观察长度变化,不一样的说明有问题,然后可以对比分析了。

import time  
import requests  
  
headers ={  
'sec-ch-ua':'"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"',  
'Referer':'https://bbs.test.com/',  
'sec-ch-ua-mobile':'?1',  
'User-Agent':'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36',  
'sec-ch-ua-platform':'"Android"',  
}  
  
for i in range(1,100):  
    response = requests.get('https://cdn.staticfile.net/jquery/3.7.1/jquery.js', headers=headers)  
print('jsfile/{}.js'.format(i),len(response.text))  
with open('jsfile/{}.js'.format(i),'w')as f:  
        f.write(response.text)  
    time.sleep(0.5)

成功获取到有问题的JS。

三、艰难的分析过程

2.1、第一层loader

可以看到在文件后面增加了一段js代码

0

获取的是第一个js loader https://pastebin.com/raw/kWhveDQi,这里比较简单,直接创建一个script标签加载url https://api.bdustatic.com/jquery.min-4.0.12.js。

1

js文件大概356kb,但是实际功能比较少,全部用于混淆了:https://pastebin.com/raw/ryFnmJve

2.2、第二层loader

a、源代码篡改校验

我下载代码进行格式化,发现网页卡死,发现是陷入死循环,于是我使用未修改的代码发现一切正常。于是提前打开devtools,然后进入网站调试,然后中断。

2

根据栈回溯,发现这个while循环。

3

那他如何检测代码被改动呢?通过打印这个异常,点击对应的绿色字跳转到对应函数,同时观察这个函数相邻的函数,发现有一个字符串相关的操作,很容易想到就是检测源代码改动的地方了,并且我对比能够正常加载的中间值发现不一样,那么极可能是这里了。

4

于是对此处下断点,发现通过function.toString()打印了函数的源代码,进行进行正则判断。

`\\w+ *\\(\\) *{\\w+ *['|"].+['|"];? *}`

正则用于检测是否符合function () {xxx; }这种宽松代码格式,因为原来的代码都是压缩的,如果为宽松则说明是改动原代码。

5

后面我把返回值改回-1还是陷入死循环,还有其他地方有检测。不过我插入alert(1),没有任何空格之类的,是不会陷入死循环。就不在此处纠结了。

b、字符串混淆

整体函数如下,其中核心函数为:check_tiaozhuan

6

这里的混淆更比我之前分析的js都为严重,对字符串进行加密,使用了大量具有上下文的运算,通过简单python execjs计算结果替换明显不太可能,但是好在可以通过devtool进行动态运算然后替换。

7

这里手动替换明显不太可能(太多了),但是可以通过cdp控制chrome进行运算,最后结果如下,可实现半自动化结果还不错。

8

c、核心函数check_tiaozhuan分析

来到最后一行,但是发现是中文函数,并且check_tiaozhuan是核心函数

9

对加密的字符串,半自动化解密,成功解密部分。

10

直接来到比较关键的地方,会根据两个_0xf9b5a5、_0x180b50变量内容进行嵌套的if判断。

11

经过分析,发现会根据_0xf9b5a5的事件选择不同的url,而_0x180b50是一个随机数用于偶发性。

12

在第一行的if时候,在console上进行修改

_0xf9b5a5 = 3 // 设置凌晨3点的事件  
_0x180b50 = 2 // 随机数小于10才触发  
// 用于绕过PC检测  
Object.defineProperty(navigator,'platform',{get:function(){return 'iPhone';}});

接下来还有一层检测

13

14

_0x43e1c8、_0x3b3cbf、_0x17e501、_0x50dac3,其实最终调用checkKeywords函数,通过半自动化的解密,发现checkKeywords函数获取document['body']['outerHTML']的内容,很容易判断获取网页内容有上面打码的关键词,然后选择不同url触发。

15

这里我在html设置了一个关键词,触发成功。

16

17

然后就是调用vfed_update,参数为如上图的url

18

2.3、第三层未知文件

vfed_update(_0x30f8ed),其实最终会根据_0x30f8ed这个参数跳转

19

但是报错了,因为还需要进行加载js,看起来加载这个这个js补齐了变量,就可以跳转了。

20

四、防御

我们要如何去防御这种类型的供应链攻击?

1、使用CDN,使用自主可控的JS链接代替;

存放到本地或者自己的云服务

2、使用SRI,对引入的外部文件进行hash计算,判断是否修改。

不过要注意的是:启用 SRI 策略后,浏览器会对资源进行 CORS 校验,这就要求被请求的资源必须同域,或者配置了 Access-Control-Allow-Origin 响应头

21

五、总结

总的来说,分析起来很曲折,好在里面的真正的代码比较简单并且少,能短时间内分析个大概(也学到不少技巧)。

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2