# 23|XSS(下):检测与防御方案解析 你好,我是王昊天。 在上一节课程中,我们学习了XSS攻击的利用方式,从攻击者的角度来说这是非常友好的,因为我们可以用BeEF实现多种有趣的攻击行为,并且它的利用方式还非常简单。 但是另一方面,这对于Web应用开发者来说,却是非常害怕看到的,毕竟没有人想自己的Web应用受到别人的攻击。**所以应用的安全维护人员会进行一些安全措施来抵御XSS攻击。** 所以这节课,我们首先会学习XSS攻击的检测方法,了解如何判断一个页面是否存在XSS攻击。学习完XSS的检测方法后,我们会继续了解XSS的防御技术和缓解方法,看看Web应用是如何抵御这个简单却很有威力的攻击方式。最后,我会介绍JavaScript混淆技术,它可以将一个JavaScript字符转化为极其复杂的乱码,并且可以保留原代码的功能。 下面,就让我们进入到对XSS攻击的检测学习中。 ## XSS攻击的检测 在对XSS攻击的检测中,我们需要借助工具的帮忙。现在已经有了很多的XSS检测工具,这给我们带来了极大的便利,不再需要我们手动注入尝试了。 下面我会介绍一款好用的XSS检测工具——XSStrike,它的大多数payload都是由作者精心构造出的,**具有极低的误报率**。XSStrike会根据我们的输入,智能地生成合适的payload进行探测。这里,让我们一起看一个XSStrike的使用示例,来加深对它的理解。 首先,我们来看看它的用法。 ![图片](https://static001.geekbang.org/resource/image/21/3b/2157baf6cfe748d183634b2ed2f9923b.png?wh=1856x534) 其中比较重要的配置项,我将它们列举如下: ```python -h #提示信息 -u #目标地址 -data #通过post方式上传数据 --headers #配置请求头信息,包括cookie等 ``` * h参数是用来输出提示信息的,当我们不知道要如何使用XSStrike时,就可以用这个参数来快速获取它的使用方式; * u参数是用来设置被测试目标的链接,所以它是进行检测时必须的一个参数; * 如果在测试中需要用POST方式上传一个参数,那么就需要用到data参数来进行上传; * headers参数也是一个非常重要的参数,我们可以用它来配置请求头信息,其中包括了我们熟悉的cookie信息的配置。 在了解完它的参数使用之后,**我们选用谜团中的XSS跨站脚本攻击作为靶场进行测试**。它是一个Python脚本,所以兼容性很好,我们使用XSStrike的代码为: ```bash sudo python3 xsstrike.py -u 'http://b6b7183d85ac4d36bb9449cb938ef977.app.mituan.zone/level1.php?name=test' ``` 这段代码就是用参数u配置了一个目标地址,其中在请求中通过get方式上传了参数name,这样XSStrike可以识别到这个通过get方式上传的参数,可以看到应用有如下输出: ![图片](https://static001.geekbang.org/resource/image/8a/64/8a63d2258f7ca226a2edcc51d3255f64.png?wh=1111x675) 从输出中,我们可以知道它会首先判断是否有WAF存在,然后对参数进行测试,获取到页面的响应,并据此生成payload。**这和我们之前学习的sqlmap非常类似,因为它们本质上其实都是注入检测工具。** 生成payload之后,XSStrike会将它们按照Confidence的值从大到小进行排序,之后按照顺序逐一对它们进行检测。这里你可能会好奇Confidence是什么,事实上,它代表的是XSStrike开发人员对于这个payload成功的信心,它的取值范围为0-10,值越高代表注入成功的可能性就越大。 之后XSStrike根据注入的payload以及它们响应的内容,会给这个payload生成一个评分即Efficiency,**这个评分越高,代表这个payload实现XSS攻击的成功率越大**。如果评分高于90,就会将这个payload标记为成功,并将它输出在命令行中,否则就会认为这个payload无效。 到这里,你已经学会了XSS攻击的检测方法,接下来让我们进入到XSS攻击防御方案的学习之中。 ## XSS防御方案 总体来说,对于XSS攻击的防御思路可以概括为一句话:对输入参数进行过滤拦截,对输出内容进行处理。下面,让我们先来学习对输入参数的过滤。 ### 对输入参数的过滤 由于XSS攻击本质上就是JavaScript代码的注入,而注入问题的核心就是需要**对用户的输入保持怀疑与警惕**。针对用户的输入,有两种不同的解决方案,即黑名单过滤和白名单过滤机制。 黑名单过滤即判断输入的内容中,是否有黑名单中的内容,如果有就拒绝处理这个输入。对应到XSS攻击,我们需要将黑名单设为攻击需要用到的字符,例如<、>、script以及 \\ 等。这样可以有效地拦截一些XSS注入负载。不过黑名单拦截有时候是不够全面的,我们很难将所有危险字符全部考虑到,并将它们禁用。 这时,我们就可以用白名单过滤机制,设定我们允许输入的字符,例如仅仅允许输入数字,那这样就可以百分百限制XSS注入的发生。可是出于实际情况考虑,严格的白名单过滤往往会让一些,带有危险字符的正常输入被拦截,所以这个方法也是存在局限性的。 接下来,让我们学习XSS攻击防御的另一种方案——对输出内容进行处理。 ### 对输出内容编码 XSS攻击生效的原因除了输入外,还有Web应用将内容直接放到输出中,导致了JavaScript代码的生效。 针对这一点,我们可以将输出中的危险内容进行编码,例如将<编码为<,将>编码为>,这样就会使得 # 混淆后的代码 [][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()(([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+[]]+(![]+[])[!+[]+!+[]+!+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+(!![]+[])[+[]]+([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]]+([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+[]]+(![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]+!+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+(!![]+[])[+[]]+([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[!+[]+!+[]]) ``` 这个例子是一个JavaScript代码混淆示例,我们可以将一个非常明显的JavaScript转化为一堆乱码,神奇的是这串乱码和特征明显的JavaScript语句具有一样的功能。这样攻击者就可以将一个很容易被黑名单、白名单以及WAF检测出来的负载改为了难以被检测出来的负载,从而成功发起XSS攻击,实现自己想要的恶意行为。 ## 总结 在这节课程中,我们首先学习了一个好用的XSS检测工具XSStrike,这样我们在判断一个页面是否存在XSS漏洞时,就不用手动输入负载检测了,这极大地提高了我们的效率。 然后我们全面地学习了XSS攻击的防御方案,其中包括有黑名单检测、白名单检测、输出编码以及使用标签的选择。我们知道了每种防御方法的实现原理,以及各自的优缺点。 当防御方案失效时,我们还学习了一个减轻XSS攻击影响的缓解措施,它是对抗XSS攻击的最后一道防线——CSP,即内容安全性策略,我们可以通过它来限制攻击者的行为,使得攻击者无法进行某些恶意破坏。 最后,我们一起了解了JavaScript混淆技术,来拓展我们的视野,这种技术将一个特征非常明显的JavaScript代码变化为了一堆看起来类似于乱码的代码,攻击者可以用它来绕过防御XSS的检测措施。这也让我们明白,防范XSS攻击还是很困难的。 ## 思考题 你可以想一想黑名单检测如何避免混淆后的JavaScript代码注入? 欢迎在评论区留下你的思考。如果觉得今天的内容对你有所帮助的话,也欢迎你把课程分享给其他同事或朋友,我们共同学习进步!