你好,我是王昊天。

在上一节课程中,我们学习了XSS攻击的利用方式,从攻击者的角度来说这是非常友好的,因为我们可以用BeEF实现多种有趣的攻击行为,并且它的利用方式还非常简单。

但是另一方面,这对于Web应用开发者来说,却是非常害怕看到的,毕竟没有人想自己的Web应用受到别人的攻击。所以应用的安全维护人员会进行一些安全措施来抵御XSS攻击。

所以这节课,我们首先会学习XSS攻击的检测方法,了解如何判断一个页面是否存在XSS攻击。学习完XSS的检测方法后,我们会继续了解XSS的防御技术和缓解方法,看看Web应用是如何抵御这个简单却很有威力的攻击方式。最后,我会介绍JavaScript混淆技术,它可以将一个JavaScript字符转化为极其复杂的乱码,并且可以保留原代码的功能。

下面,就让我们进入到对XSS攻击的检测学习中。

XSS攻击的检测

在对XSS攻击的检测中,我们需要借助工具的帮忙。现在已经有了很多的XSS检测工具,这给我们带来了极大的便利,不再需要我们手动注入尝试了。

下面我会介绍一款好用的XSS检测工具——XSStrike,它的大多数payload都是由作者精心构造出的,具有极低的误报率。XSStrike会根据我们的输入,智能地生成合适的payload进行探测。这里,让我们一起看一个XSStrike的使用示例,来加深对它的理解。

首先,我们来看看它的用法。

图片

其中比较重要的配置项,我将它们列举如下:

-h                #提示信息
-u                 #目标地址
-data             #通过post方式上传数据
--headers          #配置请求头信息,包括cookie等
sudo python3 xsstrike.py -u 'http://b6b7183d85ac4d36bb9449cb938ef977.app.mituan.zone/level1.php?name=test' 

这段代码就是用参数u配置了一个目标地址,其中在请求中通过get方式上传了参数name,这样XSStrike可以识别到这个通过get方式上传的参数,可以看到应用有如下输出:

图片

从输出中,我们可以知道它会首先判断是否有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代码的生效。

针对这一点,我们可以将输出中的危险内容进行编码,例如将<编码为&lt,将>编码为&gt,这样就会使得<script>变为&ltscript&gt,自然我们注入的JavaScript负载就无法生效,所以这也是可以有效防御XSS攻击的。

选择的使用标签

在一些博客网站中,用户的输入是需要包含HTML标签的,而允许输入HTML标签就会给XSS攻击可乘之机。

这时候,一个比较经典的处理方法就是将可能有害的HTML标签例如<button>以及JavaScript过滤掉,仅仅将用户输入的安全标签进行输出。但这个方案也不是完美的,因为这可能会导致突变XSS的发生。

就像我们小时候看过的僵尸片,里面的正常人类会因为被僵尸咬伤,导致自己也变为僵尸。突变XSS就和人变为僵尸的过程非常类似,它是因为应用的处理问题,将不能引起XSS攻击的输入,转变为了一个有害的payload,从而引起XSS攻击。

下面让我们看一个示例,来加深一下对它的理解。

#正常输入
<listing>&lt;img src=1 onerror=alert(1) &gt;</listing>
#突变为
<LISTING><img src=1 onerror=alert(1) ></LISTING>

可以看到,这个Web应用允许HTML标签<listing>的输入,这本是个安全的HTML标签,可神奇的是,输入被Web应用解析为了一个XSS语句,并且成功发起了XSS,即所谓的突变型XSS。

XSS缓解措施

当XSS攻击,绕过了我们所有的防御措施后,我们还可以利用CSP,即content security policy内容安全策略,去限制XSS的攻击行为,以减少XSS攻击的影响。

我们可以加上Web应用的响应头Content-Security-Policy,并将它的内容设置为我们想要实现的策略,这样就能让CSP成功生效。说到这里,你可能有点懵不太理解,没关系,下面让我们进入到一个示例中,相信看完它你就能理解了。

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-src 'none'; base-uri 'none';

这条CSP策略成功实现了对Web应用页面中内容的加载限制。它仅仅允许页面中的资源文件,例如图片、脚本请求主页中的资源,这样就使得攻击者无法加载准备好的服务器中的恶意资源。这可以大大降低XSS对我们Web应用的危害。

知识拓展

到这,我们已经学习了如何防止XSS攻击的发生,这个防范看上去可能会比较容易,但事实上攻击者还是有很多方法来绕过,可谓防不胜防。为了加深你的理解,我们一起来看下面这个例子:

# 原始代码
<script>alert(1)</script>
# 混淆后的代码
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()(([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+[]]+(![]+[])[!+[]+!+[]+!+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+(!![]+[])[+[]]+([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]]+([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+[]]+(![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]+!+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+(!![]+[])[+[]]+([]+[])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[!+[]+!+[]])

这个例子是一个JavaScript代码混淆示例,我们可以将一个非常明显的JavaScript转化为一堆乱码,神奇的是这串乱码和特征明显的JavaScript语句具有一样的功能。这样攻击者就可以将一个很容易被黑名单、白名单以及WAF检测出来的负载改为了难以被检测出来的负载,从而成功发起XSS攻击,实现自己想要的恶意行为。

总结

在这节课程中,我们首先学习了一个好用的XSS检测工具XSStrike,这样我们在判断一个页面是否存在XSS漏洞时,就不用手动输入负载检测了,这极大地提高了我们的效率。

然后我们全面地学习了XSS攻击的防御方案,其中包括有黑名单检测、白名单检测、输出编码以及使用标签的选择。我们知道了每种防御方法的实现原理,以及各自的优缺点。

当防御方案失效时,我们还学习了一个减轻XSS攻击影响的缓解措施,它是对抗XSS攻击的最后一道防线——CSP,即内容安全性策略,我们可以通过它来限制攻击者的行为,使得攻击者无法进行某些恶意破坏。

最后,我们一起了解了JavaScript混淆技术,来拓展我们的视野,这种技术将一个特征非常明显的JavaScript代码变化为了一堆看起来类似于乱码的代码,攻击者可以用它来绕过防御XSS的检测措施。这也让我们明白,防范XSS攻击还是很困难的。

思考题

你可以想一想黑名单检测如何避免混淆后的JavaScript代码注入?

欢迎在评论区留下你的思考。如果觉得今天的内容对你有所帮助的话,也欢迎你把课程分享给其他同事或朋友,我们共同学习进步!