货拉拉在逻辑漏洞自动化检测的实践
四、建设方案
(一)
准备工作
网关把测试环境的HTTP Request 发到 kafka 。扫描器去 kafka 上消费。
鉴权位置就是 Cookie 或者 token,需要提供收集核心业务的鉴权位置是在 URL 的参数、Request header、或者在 Request 的 body 里面。 后面都以 token 来指代鉴权参数。
做越权漏洞检测时需要不同的账号去做测试,从而生成需要不同的账号对应的 token。
不同的业务系统的鉴权参数生成方式不同,核心业务的鉴权参数是从账号中心统一生成,接入账号中心后即可自动生成 token。
申请测试账号,用于安全测试。
4、回显判断相同
在判断水平越权时,如果越权成功,回显就是相同的,但是回显中可能包含一些时间戳、traceid 之类的信息,影响判断。不能完全使用 rsp1.body==rsp2.body 的方式来判断。
这里我们采用了模糊哈希(fuzzy hash)算法,可以参考http://ssdeep.sourceforge.net/。模糊哈希算法是基于哈希算法的,和哈希算法的不同点在于,哈希算法是将整个文件作为定义域来求算结果,而模糊哈希算法则是先对文件进行分块,计算每一块的哈希值,然后将得到的一系列哈希值利用比较函数与其他哈希值进行比较,来确定相似程度。运营一段时间后,取一个最优的相似度即可。
5、相同 API 定义
API 的去重,关系到扫描测试的周期和推送漏洞时的去重。
如 admin/index.php?id=1 和admin/index.php?id=2 会判定为 相同 API。
但是如 index.php?_m=index&_a=push 和 index.php?_m= index&_a=pull 则要判定为不同 API。
(二)
基于DAST的黑盒检测
基于不同的越权逻辑,需要采用不同的重放逻辑。(如图3)
图3 检测判断逻辑
1、未授权访问
无鉴权参数
原始数据包req0重放
判断逻辑:
如果原始请求本身未包含 token,但是响应中确包含敏感数据,就判定为是一个未授权访问漏洞(无鉴权参数)。
如果原始请求本身包含 token,且响应包包含敏感数据,进入其他检测逻辑。
无效的鉴权参数
删除 token 的数据包req1重放
如果 req1的响应包包含敏感数据,就判定为一个未授权访问漏洞(无效的鉴权参数)(如下图4)
判断逻辑:
2、多账号水平越权测试
使用测试账号生成的 token 替换原始 token 做重放req2
如果 rsp0.body 与 rsp2.body 相似度达到一定的阈值,就判定为一个水平越权漏洞(如图5)
判断逻辑:
图5 水平越权漏洞测试
前期工作
req0请求时将其参数缓冲到 redis
req1 第二个请求来到,如果和 req0属于相同 API,如果属于不同的 token 下的则进行检测
发包逻辑:
id=1&user=b 作为req2
id=2&user=a 作为req3
假设 req0的参数是 id=1&user=a,req1 的参数是id=2&user=b。需要对参数做一个去重的笛卡尔积计算,然后去掉原始的参数,最终得到这些组合。
判断逻辑
先比较 req1 和 req2 ,如果它们的响应体的框架结构相同,且不是空结果如{"ret":1,"success":true},则判定为漏洞,问题参数是 id。否则进入下一步。
接着比较 req1 和 req3 ......
如果参数多的情况下,可能 user 参数有问题,然后 user和 pwd 同时存在时也有问题,则冒泡取参数多的参数上报。(如图6)
4、总结
(三)
公共API识别
通过对一段时间内不同 API 的body_bytes_sent 做标准差计算,获取标准差为 0 的 API,则这部分API 被判断为公共 API。(如图7)
(四)
API安全分析平台
2、接口去噪
http.response.code <400and not (http.response.code == 307)and not (http.user_agent matches "scaninfo@paloaltonetworks\.com")and not (http.request.method matches "HEAD|OPTIONS")and not (http.request.uri.path matches "\.js\.map|\.css|\.png|\.jpg|\.jpeg|\.ico|\.pdf|\.svg|\.bcmap|\.woff|\.ttf|\.xlsx|\?|\*|\.\.|@|:|;")and not (http.response.headers["location"] matches "sso.xxx.cn|in-sso.xxxx.com")and not (http.host matches ".*@.*oastify\.com.*")
自动识别
图9 TF-IDF的计算公式
在该思路的指导下,我们可以将客户端向服务端某个时段发送的所有URL条请求视为文档(documents),然后将计算单条的URL文档下的关键词。以某个登录API为例:api.example.com/login/238,其中/login/238是URL组成部分中的path,定义了资源在服务器上的路径,“238”是本次请求所携带的可变参数。
人工合并
对于一些接口请求量小的,可能无法达到预定阈值的,可以通过人工添加合并规则的方式进行 API 合并。(如图10)
图10 人工API合并
新增API监控:第一时间 发现新增API,进行风险 评估
僵尸API监控:一段时间内 PV持续为 0 的接口,排查是否下线,减少暴露面
API 清单:可以更加方便的做横向排查和渗透测试
推进防护能力接入:SIEM、签名等
(五)
结合IAST的调用堆栈
此处只是使用了 IAST 的插桩原理,并未部署 IAST。CI 的监控系统运行比较稳定,插桩覆盖率也比较高,也有 traceid 可以做全链路的追踪。如图12是一个完整的链路信息,包含埋点的调用堆栈、执行的 SQL。
五、不足与改进
API覆盖率不全
自动化程度有待提高
目前全自动化的场景需要做很多的加白操作,垂直越权场景还未覆盖
复杂的场景无法自动完成,如需要多个接口配合完成的场景
目前对不含敏感数据的越权漏洞还不支持检测
参考:
越权漏洞自动化治理实践
https://security.immomo.com/blog/215