甲方安全建设中有一个很重要的环节,即业务迭代上线前的安全检测。大部分公司的产品研发部门都会配备一个或多个质量测试工程师负责把关软件质量。
然而术业有专攻,质量测试工程师能够得心应手地应对软件功能方面的缺陷,却由于自身安全领域专业知识的缺失导致很难识别安全风险。
针对这一问题常采用的做法就是由甲方安全人员定期对业务线进行安全检查,但这种做法有很强的滞后性,一个业务从上线到最后被发现安全问题可能跨越了很长的周期。最理想的效果是在业务上线之前能够将安全风险“扼杀”,于是很多公司在业务上线会安排人工进行安全测试,但这种做法不够节省人力。上述提到的两个做法都有一定的弊端,一种更好的方案是在发布流程中加入自动化安全扫描,方案框架如下:
业务部门迫切希望安全团队能够在业务上线之初就发现安全问题,但每天面对大量集成发布,安全人员在“人力匮乏”的情况不太可能都将人力参与进来。即便如此,保障公司几百个业务系统的安全,仍然是我们团队的重要使命。
安全团队考虑在整个CI/CD流程中加入自动化安全检测(分为白盒和黑盒,这里暂时只探讨黑盒)。常见的做法是由安全团队提供一个在线的web漏洞扫描器。现代的web漏洞扫描器检测原理如下:
发布流程中会有质量测试工程师对业务中更新的功能进行测试,如果能够抓取到质量测试工程师在质量测试过程产生的流量并进行安全检测,就能完美地解决上面提到的两个问题。
业界常见的方式是利用网络代理(通过配置浏览器网络代理)捕获流量再进行安全测试,这种方式具有可跨平台的优势。中通安全团队决定在利用传统方式(通过配置浏览器网络代理)的同时加入另外一种全新的方式-利用浏览器插件捕获流量并作为和后端交互的媒介。利用浏览器插件比直接通过网络代理具有如下优势:
下面会讲解这种方式具体的实现细节。
系统定名为hunter,寓意是能够像猎人捕获猎物一样敏锐地发现漏洞。服务器端持久化存储使用了MySql数据库,消息队列选择RabbitMQ,在扫描结束之后会发送提醒通知。整个扫描器架构设计如下:
用户新建任务时,需要对浏览器插件中的抓取规则进行配置,配置完成之后会将用户的请求流量发送到API(Application Programming Interface,应用程序编程接口),为hunter安全检测提供数据源。
主要包含接收浏览器发送的流量、sso中心鉴权、创建停止任务、将捕获而来的流量推送到消息队列、提供扫描结果。
由于sql注入检测和xss检测需要较长的时间,故使用rabbitmq提供的Fanout Exchange模式绑定到多个queue。Sql注入检测和xss检测的queue被专门的consumer消费。
采用分布式部署方案,可以部署多个消费节点。消费节点从queue中消费到浏览器发送的流量之后进行单url多poc的检测方式。
检测引擎在执行完成之后会对使用者进行邮件、钉钉、微信等方式的通知。
在hunter的最初版中,扫描报告只会在检测引擎执行完成之后通过邮件发送。质量测试同事反映日常工作邮件太多很容易堆压扫描报告邮件,希望我们提供一个平台展示用户的所有历史任务和安全扫描报告。
主要模块分为四个部分:QA人员、浏览器插件、RESTfulAPI、分布式分析检测引擎,各模块之间的详细交互流程如下:
后续的开发进度和思路也是依据此图展开,下面将分析各个模块,并重点讲解浏览器插件和分布式分析检测引擎的实现(姑且将浏览器插件称为客户端,以下都以chrome插件为例)。
结合上图3分析可知,在每次新建任务时,用户使用客户端会在当前网页弹出用户协议。用户需要在阅读协议并同意授权之后才能新建扫描任务。
客户端要想在当前网页窗口弹出用户协议,必须要获得整个页面上下文。翻阅Google Chrome Extensions文档可知,在content-script.js中可以实现这个功能。实现思路比较简单:在content-script.js中可以通过$("html")直接增加对话框并显示。
除此之外,用户在每次扫描开始之前需要配置一些基本信息:正则匹配规则(抓取哪个域名下的请求),任务名和抄送邮箱(扫描结束之后会抄送邮件通知)。因为一次扫描过程的接口范围可能是未知的(大部分情况下,A域名系统只会调用A域名下的接口,但是还有可能A域名系统调用B域名接口,这点可能是用户提前未知的),所以需要每个新任务的正则匹配规则是可以动态设置的。
可以在background.js中调用chrome.webRequest.onBeforeRequest和chrome.webRequest.onBeforeSendHeaders来抓取chrome的网络请求。(具体做法可以参考
https://developer.chrome.com/extensions/webRequest)
这里需要注意的是任何函数在background.js只要被调用,就会一直常驻在chrome后台。所以在用户点击停止任务之后,客户端一定要移除监听器。content-script.js和background.js之间的通行可以通过chrome.runtime.sendMessage函数。
客户端将捕获到的网络请求封装之后会发送到RESTful API服务端,服务端会解析请求并判断请求中的待检测接口是否属于合法白名单范围(例如白名单为测试环境网段,防止向生产环境写入脏数据)。在通过白名单检测之后,会推送到rabbitmq中等待分析引擎节点消费。
在每次新建任务时,客户端会向RESTful API发送一条包含新建任务标识和正则匹配规则的消息。同理在每次结束任务时也会发送一条带有结束任务标识的消息。分析检测引擎在消费到结束任务标识之后会通过邮件等方式通知相关人员。
因为SQL注入检测和XSS检测相对需要较久的时间,所以决定通过Fanout Exchange模式绑定到单独的queue。通用类的漏洞(大型CVE、服务弱口令等)检测往往不需要太久的时间,可以直接放入到一个queue。整个扫描引擎是采用POC插件形式,在后续漏洞检测拓展方面比较灵活。网上关于此类的文章很多,这里不做展开。我将会重点讲下检测存储型XSS方面的思路。
反射型/DOM 型XSS检测可以利用后端的chrome headless进行检测。检测xss的思路为:
具体的实现由于篇幅较长,网上也有很多资料,故这里不打算展开。猪猪侠在先知白帽大会分享的web2.0启发式爬虫实战详细地提到过检测反射/DOM xss检测原理。
反射型XSS的输入和输出在同一个网页中,可以直接构造检测。但是对于存储型XSS(这种输入和输出位置分开的情况)直接检测并不一帆风顺,难点在于XSS检测引擎并不知道具体的输出位置。可以利用客户端是浏览器插件这一特性,让其具备检测XSS的能力。
客户端(浏览器插件)除了具有捕获网络请求并发送到服务端RESTful API的功能,还有另外一个功能就是检测当前网页中是否触发了XSS。客户端会去分析质量测试工程师打开的网页中是否触发已经提前构造的(由后端的chrome headless 检测时插入的污染字符)payload。客户端在检测到payload之后会向RESTful API发送一条检测到XSS的消息,其中包含具体的输入位置(payload中包含输入请求的requestid)。
通过chrome headless后端检测反射性/DOM型XSS,客户端检测存储型XSS这两种方式可以基本覆盖到所有XSS类型的漏洞检测。
既然客户端是基于浏览器插件开发而成,那么将赋予了我们更多的想象力和可能性。这里脑洞开一下,比如在检测到漏洞之后利用插件自动截图或者生成小视频并发送到服务端进行保存,以便后续更加方便的复盘、查阅。
在每次新建任务的时候,用户需要配置正则抓取规则、抄送邮件、任务名称。
配置完成之后,质量测试工程师进行正常的接口测试即可。在每次扫描结束之后,用户可以自行登录hunter后台进行查看历史扫描记录。如果质量测试同学对漏洞信息感兴趣,可以单独查看每一条漏洞详细信息。
Hunter现已开发完成并在公司内部推广使用,同时发现质量测试工程师在检测出漏洞之后会表现出前所未有的亢奋(阴险脸)。
目前hunter能够发现除越权漏洞之外的所有常见web漏洞(关于越权检测我们团队有一些想法正在实践,如果您有兴趣的话可以投简历,加入我们团队和我们一起探讨哦!)。未来的工作是不断增加扫描插件、加强线上运营、结合内部权限系统进行越权漏洞方面的检测。希望能够通过多种维度的扫描和检测尽可能将安全风险在上线之前扼杀。很多质量测试同事在使用hunter发现漏洞之后对信息安全兴趣高涨,我们也会挑选经典的案例整理成wiki提供给感兴趣的同事查阅。未来我们计划将hunter系统开源,希望能够帮助到更多的企业。
Chrome extensions 开发文档
https://developer.chrome.com/extensions/webRequest
WEB2.0启发式爬虫实战
https://xzfile.aliyuncs.com/upload/zcon/2018/11_WEB2.0%E5%90%AF%E5%8F%91%E5%BC%8F%E7%88%AC%E8%99%AB%E5%AE%9E%E6%88%98_%E7%8C%AA%E7%8C%AA%E4%BE%A0.pdf
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.