什么是 XMLXML的特点1. 是一种可扩展标记语言
2. 被设计来进行数据传输
3. 标签没有被预定义,需要自行定义标签 <title> <xxe>xxe>
4. 具有层级结构
5. 具有自我描述性
XML作用1. 简化数据共享
2. 简化数据传输
3. 简化平台变更
4. 使数据更加有用
5. 把数据从 HTML 分离
XML 和 HTML 之间的差异XML:用来传输和存储数据,其焦点是数据的内容,旨在传输信息。
HTML: 用来显示数据,其焦点是数据的外观,旨在显示信息。
(1)元素/节点 1. 根元素: 有且必须只有一个根元素
2. 子元素: 可以嵌套,可以重复
3. 每个元素必须成对出现
(2)属性 1. 每个元素/节点可以有多个属性
2. 属性以键值对的方式出现:名称=“值”。属性的值添加双引号,多个属性以空格分开。
(3)实体DTD
<bookstore>
<book category="COOKING"> 名称=“值”
<title lang="en">Everyday Italiantitle>
<author>Giada De Laurentiisauthor>
<year>2005year>
<price>30.00price>
book>
<book category="CHILDREN">
<title lang="en">Harry Pottertitle>
<author>J K. Rowlingauthor>
<year>2005year>
<price>29.99price>
book>
<book category="WEB">
<title lang="en">Learning XMLtitle>
<author>Erik T. Rayauthor>
<year>2003year>
<price>39.95price>
book> <book> BooK>
1. 开闭合元素一致 大小写敏感
2. 属性值必须加引号,单双都可
3. 标签必须正确嵌套
4. XML中空格会被保留,不像html中只保留一个
XML不会做任何事情, 仅仅是纯文本 , 有能力处理纯文本的软件都可以处理 XML。
我们需要编写软件或者程序,才能传送、接收和显示出这个文档。
DTD全称是The document type
definition,即是文档类型定义,可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。DTD 可被成行地声明于
XML 文档中,也可作为一个外部引用。
(1)内部DTD
1.内部的 DOCTYPE 声明
语法格式:
DOCTYPE 内部实体名称(根元素名称) [
元素声明
]>
DOCTYPE note [ //!DOCTYPE note 定义此文档是 note 类型的文档
<!ELEMENT note (to,from,heading,body)> //!ELEMENT note 定义 note 元素有四个元素:"to、from、heading,、body"
<!ELEMENT to (#PCDATA)> //!ELEMENT to 定义 to 元素为 "#PCDATA" 类型
<!ELEMENT from (#PCDATA)> //!ELEMENT from 定义 from 元素为 "#PCDATA" 类型
<!ELEMENT heading (#PCDATA)> //!ELEMENT heading 定义 heading 元素为 "#PCDATA" 类型
<!ELEMENT body (#PCDATA)> //!ELEMENT body 定义 body 元素为 "#PCDATA" 类型
]>
//pcdata 解析字符数据 < ? !
<note>
<to>Georgeto>
<from>Johnfrom>
<heading>Reminderheading>
<body>Don't forget the meeting!body>
note>
(2)外部DTD
DTD 位于 XML 源文件的外部
语法格式:
DOCTYPE 外部实体名称 SYSTEM、PUBLIC(根元素名称) "URI/URL'">
DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Georgeto>
<from>Johnfrom>
<heading>Reminderheading>
<body>Don't forget the meeting!body>
note>
//这是位于 XML 源文件的外部的 DTD "note.dtd" 文件:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
1.实体定义:实体是用于定义引用普通文本或特殊字符的快捷方式的变量,实体可在内部或外部进行声明。
语法: <!ENTITY entity-name "entity-value">
DTD 实例:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
XML 实例:
<author>&writer;©right;author>
语法:
DTD 实例:
<!ENTITY writer SYSTEM "http://www.runoob.com/entities.dtd">
<!ENTITY copyright SYSTEM "http://www.runoob.com/entities.dtd">
XML example:
<author>&writer;©right;</author>
关键字:
system:表示实体来自本地计算机
public:表示实体来自公共计算机
支持协议类型:
外部引用不同版本支持协议不同,具体如下:

.net 就是aspx
语法:<!ENTITY % 实体名称 [SYSTEM] "URL">
DOCTYPE author[
<!ENTITY % writer "Donald Duck.">
]>
<author>%writer;author>
注意: 实体引用由三部分构成: 一个和号 (&,%), 一个实体名称, 以及一个分号 (;)

PCDATA: 解析字符数据。 XML 的特殊字符(&、< 和 >)在 PCDATA 中可以识别,并用于解析元素名称和实体。PCDATA(字符数据)区域被解析器视为数据块,从而允许您在数据流中包含任意字符。

XXE(xml external entity injection)即xml外部实体注入漏洞。
XXE是针对应用程序解析XML输入类型的攻击。也就是说服务端接收和解析了来自用户端的xml数据,而又没有做严格的安全控制,从而导致xml外部实体注入。
攻击者通过向服务器注入指定的xml实体内容,从而让服务器按照指定的配置进行执行,导致问题。
xxe漏洞核心就是允许了引入外部实体的加载,导致程序在解析xml的时,可以加载恶意外部文件,从而造成文件读取等危害。
实验一 相关靶场环境:pikachu
1.通过数据包判断是否存在xml相关传参

2.修改xml参数,写入xml相关标签代码,放包,可以看到页面有回显,说明存在回显式xxe漏洞


3.利用内部实体进行输出
payload构造
xml version="1.0"?>
<!DOCTYPE poc [
<!ENTITY aa 'xxe' > ]>
<na>&aa;</na> //对实体aa进行引用,不是标签poc

4.利用外部实体读取相关文件xml version="1.0"?>
<!DOCTYPE ANY [
<!ENTITY aa SYSTEM "file:///E:/3.txt" >
]><x>&aa;</x>
//file:///path/to/file.ext
//http://url/file.ext
//php://filter/read=convert.base64-encode/resource=conf.php

还可以利用file:///etc/passwd或者其他支持伪协议,获取密码等其他敏感文件
实验二、相关靶场环境:xxe-php
$USERNAME = 'admin'; //账号
$PASSWORD = 'admin'; //密码
$result = null;
libxml_disable_entity_loader(false);//
$xmlfile = file_get_contents('php://input'); //对文件进行相关读取
//file_put_contents(1.txt,'dddddd');文件写入
try{ //捕获程序中的异常,匹配后进行相关输出
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
$username = $creds->username;
$password = $creds->password;
if($username == $USERNAME && $password == $PASSWORD){
$result = sprintf("%d%s ",1,$username);
}else{
$result = sprintf("%d%s ",0,$username);
}
}catch(Exception $e){
$result = sprintf("%d%s ",3,$e->getMessage());
}
header('Content-Type: text/html; charset=utf-8');
echo $result;
?>
涉及相关函数:libxml_disable_entity_loader(false):允许xml加载外部实体
file_get_contents():把整个文件读入一个字符串中 file_put_contents() 函数把一个字符串写入文件中。
try catch :
1.功能:程序异常捕获
2.语法:
LIBXML_NOENT: 替代实体。将 XML 中的实体引用 替换 成对应的值 LIBXML_DTDLOAD: 加载外部子集。 加载
DOCTYPE 中的 DTD 文件
通过php://input协议获取POST请求数据,然后把数据通过file_get_contents()函数,放在$xmlfile变量中。
simple_import_dom():
1.功能:把 DOM 节点转换为 SimpleXMLElement 对象。对xml进行实体化 如果失败,则该函数返回 false。
2.语法:simplexml_import_dom(data,class)
3.相关参数:
4.实例:
输出:John1.抓包对数据包进行分析

3.payload构造
XML与DTD语法结构:xml声明
DTD实体
xml部分

xml version="1.0"?>
<!DOCTYPE note [ //note标签:指定公开文本描述,即对引用的公开文本的唯一描述性名称。!DOCTYPE note 定义此文档是 note 类型的文档
<!ENTITY poc SYSTEM "file:///E:/3.txt"> //entity实体
]>
<user><username>&poc;</username><password>qwe</password></user>
对实体进行引用 (实体相当于变量)

==3.相关工具 ==

寻找相关函数 如:simplexml_load_string();检测XML是否会被解析。
抓包,看报文是否包含 xml传参,如果是xml格式的body,则发送一个数据查看是否能回显, 有则直接攻击,无则参考无回显的xxe攻击。

3. 直接传xml代码, 检测服务器是否支持外部实体。
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))