XSS学习
XSS
xss简介
XSS叫跨站脚本攻击,英文缩写应该是CSS,但是因为CSS这个缩写已经用过了,所以改成XSS。
XSS是什么?
XSS就是指恶意攻击者在Web页面中插入恶意JS代码,当用户浏览网页的时候,嵌入其中Web里面的JS代码会被执行,就可以达到恶意攻击用户的目的。
XSS漏洞通常是通过php的输出函数将js代码输出到html页面中,通过用户本地浏览器执行的,所以xss漏洞关键就是寻找参数未过滤的输出函数。
php中常见的输出函数有:
echo
printf
print
print_r
sprintf
die
var-dump
var_export
xss类型
1.反射型XSS; 一次性,不存储,一般比如查询页面
2.存储型XSS; 存在数据库永久存储,一般比如留言板,注册页面
3.DOM型XSS; 完全不与服务器后台交互,纯前端,dom就是js那个内容吧,这个和反射型还是区别一下(这个DOM在js上面学的是通过document对象操作网页上的内容)
单独解释一下DOM型XSS:简单来说就是通过修改页面的DOM节点形成的XSS。他和另外两种XSS的区别在于他的XSS代码并不需要服务器解析响应的直接参与,触发XSS靠的就是浏览器端的 DOM 解析,可以认为完全是客户端的事情。
漏洞形成原因
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
实例
拿到这类题目我们首先要做的是测试一下特殊字符有没有被过滤掉
这里使用pikachu漏洞靶场平台
反射型xss(get)
这种是最简单的
可以看到输入的”和<>还有数字都没被过滤,直接打印在下面了
我们直接尝试输入
1 |
|
发现有输入限制,只能输入限制数量的字符,应该是前端显示,看一下源代码
限制了20个字符,改成大一点就行了
成功利用
反射型xss(post)
这里是需要登陆的,因为第一关暴力破解那边是得到了几个账号的,其中一个账号是admin密码是123456所以这边试一试登陆成功了
直接输入上一关的代码直接利用了
1 |
|
为什么方法和上一题一样?
因为xss类型都是一样的,就是get和post两种提交方式的差别罢了,get的话会在url上面带上请求,post不会
存储型xss
一般就是留言板之类的
用之前最简单的payload试一下
成功弹出
DOM型xss
这样一个界面,不知道输什么,就随便测试一下
下面多了一句话,而且是一个a标签,点击无法访问
于是看一下源代码
我们发现我们输入的内容进入了a标签的href属性中,因为是在a标签里面,所以不好使用js代码,因为a标签有个onclick事件,所以我们可以直接尝试用这个弹窗
1 |
|
这里发现闭合必须用单引号,用双引号不行
于是点击下面的a标签成功弹窗
Pikachu上面关于DOM型还有一题,其实和上面这题几乎一样,就是a标签要点两次
源代码这里,显示的先是下面的a标签,然后onclick到一个domxss()函数然后生成上面的a标签
这就是domes()函数
xss利用
我们之前讲了关于xss的三种类型,并且给了实例,但是我们的实例都只是做了一个弹窗,这个弹窗当然没什么表面上的危害,我们需要通过这个进一步利用,这才是我们的目的,所以接下来就演示一下xss的利用
xss的利用分成三种方法:
cookie的窃取和利用
钓鱼攻击
xxs获取键盘记录
cookie利用
环境搭建
这里先讲一下前期的环境配置。我们如果要获取其他用户的cookie,那么我们必须要有一个地方来保存我们获取到的cookie,并且因为其他用户是外网,所以如果我们有办法获取他们的cookie,那么肯定是他们要发自己的cookie给我们,这就需要我们有一个公网的网站来接收他们发来的cookie
因为现在是靶场,都是内网,所以pikachu提供了一个网站给我们接受cookie,我们不需要自己搭公网的网站了。
这里有个xss后台,我点进去
单独安装配置一下即可,数据库账号密码都是root
首页是这样的
给出了账号密码,直接登陆
这边直接给出了我们刚刚说的xss的三种利用方式,我们先看第一个cookie搜集
这样一个界面
这里我们需要改一下这个xss后台的一个cookie的api界面
这里的重定向我们改成把网址改成127.0.0.1/pikachu-master/index.php
先这样改,等会说为什么这样改
好了,我们现在已经完成了环境的搭建。
payload编写测试
我们回到第一题
这里我们用这样一个payload
1 |
|
然后就可以看到在我们刚刚那个xss后台这里获取到了一个cookie
这里解释一下payload
因为alert可以弹窗,说明可以执行js代码,那么我们这边就执行一个获取当前cookie的代码,即document.cookie然后利用document.location重定向把获取到的cookie发送到那个xss后台里去
现在我们只需要把referer里面的链接发给别人就可以获取到别人的cookie了
1 |
|
可能一下子没反应过来为什么这样做,我把整个cookie利用流程理一遍
利用流程梳理
首先,我们发现了某个网址存在xss漏洞,如图
我们发现插入js代码可以直接弹窗
1 |
|
上面的payload只是我们测试是否存在xss漏洞的,如果要利用漏洞,我们需要用一个利用漏洞的payload
这里我们使用这样一个payload,我们想要获取到其他用户的cookie
1 |
|
这样一个payload输入到刚刚的地方,会被执行,于是在我们自己网址的后台就可以看到刚刚我们测试的自己的cookie出现在了我们的后台
于是我们把这里的referer的网址复制出来,然后发给别人,这个网址就是我们刚刚执行xss漏洞的请求。如果别人点击了这个网址,因为他们是有自己的cookie的,就相当于他们把自己的cookie获取到然后发给我们。
简单来说就是对方点击我们发的这个链接就会完成xss执行的操作,即自动在下面这里输入那个payload
那么只要他点击了就会把它的cookie发送到我们的xss后台
那么现在有两个问题
一、对方为什么会点我们发的链接?
1 |
|
二、如何让对方点击后依然不知道自己的cookie被泄漏了?
1 |
|
post提交方法
我们刚刚用的是get方式的反射型xss漏洞,那么如果是post那么就不能把payload附带在url上面了,所以我们需要单独写一个页面
这个pikachu的xss后台里面已经写好了一个html
我们可以这个post.html里面其实就是一个表单,然后会自动提交这个表单,表单里面就是js代码,把cookie发送到xss后台。其实原理和get肯定是一样的,只不过不能在url上面带payload于是就写在单独的一个页面里面了,到时候直接把这个页面的链接发给被攻击者就好了,这里就不演示了。
钓鱼攻击
我们之前的存储型xss就是把用户输入的内容永久的存储到服务器,所以这里就非常容易弄钓鱼攻击
在这里输入一个payload
1 |
|
然后就弹出一个登陆框
这里如果输了账号密码提交了,那就直接传给后台了,这就是钓鱼攻击,上面的cookie利用拿的是对方的cookie,这里的钓鱼攻击直接拿到账号密码的明文。
刚刚那个payload其实就是访问fish.php这个页面
源码是这样的,意思就是说会出现一个弹窗,然后提示用户输入账号密码,然后把账号密码发送给后台
后台就是xss后台里面有个钓鱼结果搜集的后台
xxs获取键盘记录
所需知识:跨域
当协议(http/https)、主机(主域名xxx.com,子域名www)、端口中的任意一个不相同时,称为不同域
我们把不同的域之间请求数据的操作,称为跨域操作
同源策略
所有浏览器的约定。两个不同域名之间不能使用js进行相互操作
如果想要进行跨域操作,则需要管理员进行特殊的配置
比如通过:header(“Access-Control-Allow-Origin:x.com”)指定
注意:下面这些标签跨域加载资源(资源类型时有限制的)是不受同源策略限制的
1 |
|
为什么要有同源策略?
我登录了淘宝,如果攻击者给我发一个带有恶意js的链接,我打开了,可能对方就可以获取到我淘宝的cookie
我们试一下
1 |
|
我们把这个payload放到那个存储型xss那题目里面
注意一下接收键盘记录的xss后台的代码需要改一下
改成如图这样,不然请求的地址是错误的
因为改的是js,浏览器默认是缓存js的,所以改完记得强制刷新一下网页
现在只要在页面上随便敲键盘,键盘记录就都可以被记录下来(可以看一下Newwork的发包情况)
xss盲打
意思就是我们输入的内容只是会发送给后台,不会在前端输出,这样是不是意味着我们不能加入js代码了?
其实可以给后台管理员加js代码,同样可以执行js代码
这也是一个留言板,我们提交之后前台是没有反应的,因为没在前台输出,但是如果管理员登陆了后台,在后台看我们的留言的时候,会执行这个js代码。
所以我们去后台看一下(这个题目右边有个提示按钮,给了后台地址)
一登陆就看到刚刚我们的js代码被执行了
所以说xss盲打意思就是xss攻击管理员后台,让后台执行我们的js代码
xss绕过
1 |
|
比如这里的题目
1 |
|
我们试一下大小写,成功绕过了
xss之htmlspecialchars
这个其实是一个php的函数,这个函数的作用是把预定义的字符转换为html实体
预定义的字符是
&(和号)成为&
“(双引号)成为"
‘(单引号)成为'
<(小于)成为<
>(大于)成为&
例如:$ok=htmlspecialchars($_GET[‘message’])
可用的引号类型:
ENT_COMPAT -默认。仅编码双引号
ENT_QUOTES -编码双引号和单引号
ENT_NOQUOTES -不编码任何引号
一般情况的话,管理员都会因为懒,把引号类型设为默认,但是这种情况的话只编码了双引号,这种时候我们就可以用单引号来代替双引号。所以如果作为安全工程师保护网站安全的话我们应该注意这个函数,把引号类型改成ENT_QUOTES这种才是最安全的。
看这题
我们的输入到了a标签的href里面
如果我们想要利用的话,必须把这个href给闭合了,所以用引号试一下
这样就成功了,注意这个payload需要加一个q这种字符在单引号前面,然后最后没有单引号
然后我们点击一下这个a标签就可以利用了
下面是源代码,确实没有对这个函数添加引号类型
xss之href输出
这题和上题一样,输入到href里面去了
但是这题把单引号和双引号都过滤了
那么这题可以用javascript协议来执行js
1 |
|
利用成功
阶段总结:如何防范a标签的href漏洞
这里需要总结一下如何防范a标签的href漏洞,可能面试会问到,我们要做的就是首先限制a标签只允许http和https,这样可以防止javascript然后再用htmlspecialchars函数编码双引号和单引号,防止闭合href用onclick
xss之js输出
我们发现输入的内容会输出在js里面
那么我们可以闭合js
1 |
|
我们这样输入payload在源代码里面发现成功闭合了js
成功利用
源代码里面给了一个说明,就是说js输出点应该使用反斜杠对特殊字符进行转义
xss常见防范措施
总的原则:输入做过滤,输出做转义
过滤:根据业务需求进行过滤,比如输入点要求输入手机号,则只允许输入手机号格式的数字。
转义:所有输出到前端的数据都根据输出点进行转义,比如输出到html中进行html实体转义,输入到JS里面进行js转义
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!