一种基于状态转换图的XSS漏洞检测方法技术领域
本发明涉及一种基于状态转换图的XSS漏洞检测方法,属于计算机软件领域。
背景技术
互联网技术高速发展,将人们的生活和工作连接在一起。信息化越来越发达的社
会,使人们体验到了前所未有的方便和快捷。人们通过互联网购买商品、发送Email、银行转
账、访问社交网站等行为都需要同Web应用进行大量的数据交互,正是这些大量的数据交互
引起了很多Web安全问题。其中跨站脚本(Cross-Site Scripting,XSS)漏洞被人们广泛关
注,却屡禁不止。在权威Web安全组织开放式Web应用程序安全项目(Open Web Application
Security Project,OSWAP)于2010年发布的Top 10漏洞排名中,XSS漏洞排名第二位,在其
2013年发布的Top 10漏洞排名中,XSS漏洞排名第三位。同时,随着互联网进入Web2.0时代
之后,html5、css3以及异步JavaScript和XML技术(Asynchronous Javascript And XML,
AJAX)等技术的发展迅速,Web应用与用户之间的交互变的越来越复杂,XSS漏洞检测越来越
困难。
Web应用需要用户输入数据来决定返回什么信息,XSS漏洞正是由于Web应用程序
对用户输入(包括恶意和非恶意)考虑不足而产生的。XSS漏洞可以造成危害的最大的原因
是用户浏览器可以执行脚本代码。攻击者利用XSS漏洞,将恶意代码注入到网页中,提交给
Web应用,如果Web应用没有将恶意代码过滤掉,而是当作正常数据存储起来,在正常用户访
问相关页面时,将恶意代码发送给了正常用户,恶意代码就会偷偷执行,造成对正常用户的
攻击。XSS所造成的伤害并不仅仅像很多人理解的弹出一个恶意对话框那样简单,它还可能
收集用户的敏感信息(如Cookie、历史访问记录等)、劫持会话、传播蠕虫、将用户作为傀儡
机器发送DDos攻击、影响页面正常渲染(如强制弹广告)、恶意操作(如恶意删除用户信息)
等。因此防治XSS漏洞非常重要。
综上,针对动态页面的XSS漏洞检测注入点发掘过程主要存在以下问题:首先,扫
描程序要能够全面覆盖Web应用的各个状态,包括动态生成的状态;其次,扫描程序要能够
判断某输入点是否符合XSS注入点条件从而发现注入点;最后,扫描程序要尽可能自动化和
具有较强通用性,从而可以减少开发人员的工作量。
发明内容
本发明的目的在于提出一种基于状态转换图的XSS漏洞检测方法来解决目前XSS
漏洞检测工具发现注入点能力不足的问题,该检测方法的内容主要为:提出了一种基于状
态转换图的Web应用模型,该模型很好的表示一个Web应用的各种不同状态,提高了对Web应
用的注入点特别是隐藏注入点的搜索能力。提出了一种准确率很高的攻击结果判定方法。
对相关模型和判断方法进行了测试,验证了其有效性。
本发明方法采用动态建模、动态攻击、动态判断的方式对Web应用进行XSS漏洞检
测,希望达到准确度高、覆盖率全等目的。
为达到以上发明目的,经过研究讨论和反复实践,本系统确定最终方案如下。
一种基于状态转换图的XSS漏洞检测方法,该方法为一种基于状态转换图的Web应
用模型,分为Crawler模块、Fuzzing模块、Report模块和Browser层。
如图1所示,三个模块之间的连接关系为:Crawler模块负责对Web应用构建状态转
换图模型,在模型的构建过程中,挖掘XSS漏洞注入点。Fuzzing模块对Crawler模块挖掘的
注入点使用攻击向量进行攻击。Report模块对Fuzzing模块的攻击结果进行判定,并收集结
果,输出漏洞报告。三个模块都需要对浏览器进行操作,这些操作通过统一的Browser层进
行统一管理。
(1)Crawler模块:该模块实现了网站爬取、构造状态图和注入点的搜索的功能。
Crawler模块通过模拟用户操作,自动爬取Web应用的各个页面(包括动态生成的页面),并
采用识别方法识别注入点。该识别方法同传统方法不同,首先分析页面中的带参url和form
表单,若有则记录为注入点。之后对页面中的所有元素尝试模拟用户的动作,一旦有事件触
发且有网络请求,截断此请求,分析该请求是否携带数据信息,若是则判定该页面是一个注
入点,记录该页面和所触发的元素的位置为一个注入点。
(2)Fuzzing模块:该模块使用攻击向量对Crawler模块收集的注入点进行模拟攻
击。经过Fuzzing模块的攻击后,浏览器会呈现一定的状态,再通过设计的攻击结果对象对
浏览器页面进行判断,识别XSS攻击是否成功。不同攻击向量,浏览器所呈现的状态不同。本
方法将结果状态分两种:其一为脚本执行型,本方法用弹出带有特殊字符串的对话框表示;
其二为资源请求型,本方法用判断第三方服务器资源是否变动来表示。
(3)Report模块:该模块收集Fuzzing模块攻击的结果,生成结果报告xml文件。
(4)Browser层:Browser层是对Selenium API的进一步封装,用来被三大模块进行
调用,其功能包括在页面执行动作、执行脚本、判断页面状态等。
运行环境
本系统采用Java语言编写,调用Selenium API操作不同的浏览器。开发环境为
Windows 7 64bit,在Windows 7 64bit机器和Ubuntu 14.04 LTS 64bit机器上运行顺畅。
系统原型采用Selenium版本为2.63.1,经验证正常驱动Firefox 50.0.2。
软件系统可根据实际情况改变的内容
由于本系统具有较强的通用型,在设计之初就考虑到了对其它操作系统的支持。
依赖库包括selenium、jgrapht、xmlunit以及各种浏览器驱动库等,这些库都是独
立的jar包,利用java的平台无关性,保证在各种操作系统下正常运行。
由于selenium和浏览器之间版本可能会出现不兼容的情况,因此,实际情况中,可
根据selenium不同的版本选择兼容的浏览器版本。
附图说明
图1系统总体架构
图2一个简单的Web应用状态图样例
具体实施方式
本系统的原理是调用Selenium API对Web服务器的黑盒测试,它由Crawler模块、
Fuzzing模块和Report模块三个模块组成。系统架构如图1所示。
Crawler模块
Crawler模块实现构建状态图和挖掘注入点功能。算法采用深度优先的方式创建
状态图。该算法描述如算法1所示。
算法1.构建状态图和挖掘注入点算法
输入:起始网站URL
输出:状态图和注入点列表
0.初始化一个空的url_list,将url添加至url_list
1.若url_list中不存在未处理url,否则跳至步骤10
2.取出一个未处理url,分析该url是否带有参数,若该url未跳出域且所标记资源
不是图片、文件等则请求该资源,并标记该url为已处理。
3.构造DOM状态图的初始节点,分析页面中的form表单,将该状态加入队列state_
list。
4.若state_list不为空则,则取出一个状态记为cur_state,并将cur_state中所
有DOM节点记为dom_list。
5.若dom_list为空,则返回步骤4。
6.从dom_list取出一个DOM节点记为cur_dom,通过模拟用户行为,尝试触发事件。
若没有事件触发返回步骤5。
7.若触发get或post等http请求继续步骤8,否则跳至步骤9。
8.判定请求是否符合疑似注入点特征,若符合则记录该注入点;若是新的url,则
将新的url添加至url_list
9.事件完成方法调用后,判定DOM结构是否发生状态,若是则构造新的状态和DOM
转换条件,添加到状态转换图中,并将新状态添加到state_list队尾。跳至步骤5。
10.结束
算法1的步骤8中判定一个请求是一个注入点需满足一定的条件。浏览器同服务器
进行信息交互大都使用http协议,http请求报文的结构如下:
请求行-通用信息头-请求头-实体头-报文主体
其中请求行又包括请求方法、URI和协议版本,当URI中存在参数或请求报文存在
报文主体时,该请求报文可向服务器提交数据。在URI的参数或报文主体中注入探子向量,
若服务器返回的信息中包含了探子向量,则说明该请求是一个注入点,否则不是注入点。探
子向量采用特殊字符串加随机序列的组合形式,使用(((XSS_PROBE)))+系统当前时间戳作
为探子向量。
本文用如下结构保存注入点信息:
url–state(condition_list)–dom(xpath)–event–method
其中,url指发生http请求的页面url,state(condition_list)指http请求发生时
该url所处于的状态以及由根状态到该状态的路径,dom(xpath)指引起http请求发生的事
件源DOM,event指引起http请求的事件,method指请求方法。
将Web应用前端页面的一些元素的属性变化不归为DOM结构的变化,元素的属性变
化为背景颜色的变化、长宽变化、DOM元素内容变化等。若将这些变化识别为DOM结构的变
化,有可能出现状态爆炸问题。因此算法1的步骤9中,需要对整个页面进行预处理再进行
hash计算,来判定页面状态是否发生变化。其算法描述如算法2所示。
算法2.DOM结构hash值计算算法
输入:html页面
输出:DOM结构hash值
0.将页面中body标签之间的内容提取出来作为待计算文本
1.编码预处理
2.脚本预处理
3.节点属性预处理
4.节点内容预处理
5.标签统一化处理
6.空格预处理
7.计算hash值
8.结束
Fuzzing模块
(1)模拟攻击:Fuzzing模块负责对Crawler模块找到的注入点进行模拟攻击,模拟
攻击的方式为自动填充攻击向量、自动提交表单以及自动拼接url参数和请求。
自动填充攻击向量需要考虑文本内容、单选按钮和复选按钮的情况。文本内容使
用selenium的WebElement类的sendKeys方法进行填充;单选按钮使用selenium的
WebElement随机选择相同组的单选按钮中的一个进行模拟点击;复选按钮同样使用
selenium的WebElement处理,对同一组的所有复选按钮按50%概率决定是否点击。
自动提交表单,则根据注入点的类型模拟浏览器的动作,只考虑点击按钮的情况。
自动拼接url参数则将url中参数的值用攻击向量替代,并发送给服务器。
对于每个注入点,循环使用所有攻击向量进行攻击。
(2)表单属性过滤:在填充表单前,需要对表单中的某些属性进行清除,从而去除
前端一些对数据格式的要求,以免导致数据提交不成功。当一个textarea标签设置了
maxlength属性时,攻击向量不能够输入到该textarea。对form表单中元素种类和要清除的
属性如表1所示。
表1 form表单中元素种类和要清除的属性
元素
要清除的属性
textarea
maxlength、min
input[type=text|password|hidden]
maxlength、min
input[tpye=submit|button]
onsubmit、onfocus、onclick
input[type=*]
disabled
(3)攻击结果判定:传统攻击结果判定方法为查看攻击字符串是否出现在结果页
面中,而这种方式非常不准确。结果返回的是重定向或者服务器对攻击向量做了部分但不
完全的过滤,都将导致结果页面中不会出现与攻击向量匹配的字符串,即检测不到XSS漏
洞。对于每个攻击向量,都设计一个攻击结果与之匹配,该攻击结果是一个Java对象,实现
统一的接口。Fuzzing模块在输入攻击向量并提交之后,对结果页面进行判定,判断是否执
行了恶意代码,是对攻击结果更直接和更可靠的度量。
Report模块
Fuzzing模块对注入点进行攻击之后,调用Report模块对攻击结果进行收集。
Report模块使用xmlunit库将结果保存为xml文件,最终生成一个漏洞报告。报告的内容包
括:注入点总数、漏洞总数、漏洞列表等。漏洞列表包括漏洞的位置、注入的攻击向量的类型
以及攻击结果的截图等。Report模块处理攻击结果的流程如算法3所示。
算法3.Report模块处理攻击结果
输入:攻击结果对象和浏览器句柄
输出:攻击结果记录
0.以浏览器句柄为参数,调用攻击结果对象的match方法
1.若match方法返回为false跳至第3步,否则继续第2步
2.对浏览器进行截图,将前一状态、当前状态、攻击向量、等内容组成一条插入结
果xml文件中。
3.若浏览器有弹窗,关闭弹窗;若攻击对数据库有修改,抹掉修改
4.结束。