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 的目的是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
以上 DTD 解释如下:
这是DTD定义被包含在xml源文件中,也可以使用外部文档声明。
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD。
Tove
Jani
Reminder
Don't forget me this weekend!
这是包含 DTD 的 “note.dtd” 文件:
通过 DTD,每一个 XML 文件均可携带一个有关其自身格式的描述。
通过 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解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)
PHP中用来处理xml的函数是simplexml_load_string():将xml字符串转换为对象。第一个参数就是xml字符串。
除了可以使用file协议,还可以使用一些其他协议:
示例:
$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函数:
发现/weixin/index.php中可以存在xxe。
$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, postArr,postArr是一个xml字符串,然后利用simplexml_load_string()函数解析xml字符串,在xml字符串中构造攻击语句,就完成了xxe攻击。
注意这段代码上的if条件:需要 s i g n a t u r e 不 等 于 空 , signature不等于空, signature不等于空,echostr等于空。
靶场cms首页:
访问weixin/index.php,然后将包转换为post包。
获取到base-64的conn.php
解码
根据审计,找出数据库管理后台,登录数据库管理后台
查询管理员的密码
解密出管理员的密码
admintestv1就是flag。