[zkaq靶场]XXE(XML外部实体注入)

XXE(XML外部实体注入)

XML

描述

XML 被设计用来传输和存储数据,其焦点是数据的内容。

XML标签没有被预定义,XML具有自我描述性。

示例:



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

<note>
<to>Toveto>
<from>Janifrom>
<heading>Reminderheading>
<body>Don't forget me this weekend!body>
note>

第一行是 XML 声明。它定义 XML 的版本(1.0)和所使用的编码,中间是文档定义类型(DTD),最后是文档元素。

XML不会做任何事情,仅仅用来存储与传输数据。我们需要程序才能发送,接受和显示XML数据。

结构

XML是一种树结构,XML 文档必须包含根元素。该元素是所有其他元素的父元素。

XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端。

所有的元素都可以有子元素。

DTD

DTD 的目的是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构。

DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。

以上 DTD 解释如下:

  • !DOCTYPE note (第二行)定义此文档是 note 类型的文档。
  • !ELEMENT note (第三行)定义 note 元素有四个元素:“to、from、heading,、body”
  • !ELEMENT to (第四行)定义 to 元素为 “#PCDATA” 类型
  • !ELEMENT from (第五行)定义 from 元素为 “#PCDATA” 类型
  • !ELEMENT heading (第六行)定义 heading 元素为 “#PCDATA” 类型
  • !ELEMENT body (第七行)定义 body 元素为 “#PCDATA” 类型

这是DTD定义被包含在xml源文件中,也可以使用外部文档声明。

外部文档声明

假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:

这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD。




 Tove
 Jani
 Reminder
 Don't forget me this weekend!

这是包含 DTD 的 “note.dtd” 文件:

为什么使用DTD:

通过 DTD,每一个 XML 文件均可携带一个有关其自身格式的描述。

通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。

而应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。

还可以使用 DTD 来验证您自身的数据

DTD实体

实体可以理解为一个变量,该变量用于定义文本或字符。

内部实体声明:

DTD 实例:

XML 实例:

&writer;©right;

writer变量的值是Donald Duck,copyright变量的值是Copyright baidu.com。

在xml引用实体:&writer;

外部实体声明

DTD 实例:

XML 实例:

&writer;©right;

上面介绍完了xml外部实体,下面开始介绍一下xxe攻击是怎么完成了,怎么利用xml外部实体进行注入攻击(用户输入的数据被当作代码执行)。

原理

有了XML实体,关键字’SYSTEM’会令XML解析器从URI中读取内容。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)

[zkaq靶场]XXE(XML外部实体注入)_第1张图片

PHP中用来处理xml的函数是simplexml_load_string():将xml字符串转换为对象。第一个参数就是xml字符串。

除了可以使用file协议,还可以使用一些其他协议:

[zkaq靶场]XXE(XML外部实体注入)_第2张图片

示例:


$string = <<<XML
 

 Forty What?
 Joe
 Jane
 
  I know that's the answer -- but what's the question?
 

XML;

$xml = simplexml_load_string($string);

print_r($xml);
?>

输出:

SimpleXMLElement Object
(
  [title] => Forty What?
  [from] => Joe
  [to] => Jane
  [body] =>
   I know that's the answer -- but what's the question?
)

读取文件:

但是读取文件没有回显的时候应该怎么办呢?

需要将读取的数据外带,然后进行保存。

外带就是利用http发起请求,请求我们自己在公网上的服务器,然后让其保存。



 
%remote;
%send; 
]>

1.xml

"
>
%all;

2.php


靶场

通过对靶场使用的cms进行审计:

搜索simplexml_load_string函数:

[zkaq靶场]XXE(XML外部实体注入)_第3张图片

发现/weixin/index.php中可以存在xxe。

[zkaq靶场]XXE(XML外部实体注入)_第4张图片

分析:

$postArr来源于file_get_contents(“php://input”)

file_get_contents()函数是用来将文件的内容读入到一个字符串中的首选方法。

php://input简单点来说就是当Content-Type不等于”multipart/form-data”时,读取post数据,此时等于$_POST.

如果我们能够访问到/weixin/index.php,那么就可以构造post数据包,也就意味着可以控制 p o s t A r r , postArr, postArrpostArr是一个xml字符串,然后利用simplexml_load_string()函数解析xml字符串,在xml字符串中构造攻击语句,就完成了xxe攻击。

注意这段代码上的if条件:需要 s i g n a t u r e 不 等 于 空 , signature不等于空, signatureechostr等于空。

步骤

靶场cms首页:

[zkaq靶场]XXE(XML外部实体注入)_第5张图片

访问weixin/index.php,然后将包转换为post包。

[zkaq靶场]XXE(XML外部实体注入)_第6张图片

获取到base-64的conn.php

image-20210429200216359

解码

[zkaq靶场]XXE(XML外部实体注入)_第7张图片

根据审计,找出数据库管理后台,登录数据库管理后台

[zkaq靶场]XXE(XML外部实体注入)_第8张图片

查询管理员的密码

[zkaq靶场]XXE(XML外部实体注入)_第9张图片

解密出管理员的密码

[zkaq靶场]XXE(XML外部实体注入)_第10张图片

admintestv1就是flag。

你可能感兴趣的:(zkaq靶场,xml,xxe,渗透测试,外部实体)