XXE
XML简单介绍
XML全称可扩展标记语言(EXtensible Markup Language)。
XML和HTML的语言风格很像,都是标记语言,有对应的tag,唯一不同的就是作用,XML侧重于数据传输,HTML注重与标记语言
XML的基本格式
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><!--xml文件的声明-->
<bookstore> <!--根元素-->
<book category="COOKING"> <!--bookstore的子元素,category为属性-->
<title>Everyday Italian</title> <!--book的子元素,lang为属性-->
<author>Giada De Laurentiis</author> <!--book的子元素-->
<year>2005</year> <!--book的子元素-->
<price>30.00</price> <!--book的子元素-->
</book> <!--book的结束-->
</bookstore>
上面就是一个标准的XML格式,其实看起来就是HTML没错,代码块里看的可能不清楚:
在IDEA里缩进就可以看清楚,XML是有父节点和子节点的,和HTML一样
- 所有 XML 元素都须有关闭标签。
- XML 标签对大小写敏感。
- XML 必须正确地嵌套。
- XML 文档必须有根元素。
- XML 的属性值须加引号。
在XML中也有几种预定义实体
即用< > & ' "
替换 < > & ' "
DTD(document type definition)
DTD是XML的一部分,他用来给XML定义一种格式规范,比如自定义一种标签
DTD用来为XML文档定义语义约束。可以嵌入在XML文档中(内部声明),也可以独立的放在另外一个单独的文件中(外部引用)。是XML文档中的几条语句,用来说明哪些元素/属性是合法的以及元素间应当怎样嵌套/结合,也用来将一些特殊字符和可复用代码段自定义为实体。
DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块。DTD 可以在 XML 文档内声明,也可以外部引用。
1、内部DTD
假如在XML中定义了DTD,那么就要严格遵循DTD里的规范,毕竟DTD是对XML的一种限制,如下面的例子:
<?xml version="1.0"?>
<!DOCTYPE note [<!--定义此文档是 note 类型的文档-->
<!ELEMENT note (to,from,head,body)><!--定义note元素有四个元素-->
<!ELEMENT to (#PCDATA)><!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)><!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)><!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)><!--定义body元素为”#PCDATA”类型-->
]>
<note>
<to>Boogipop</to>
<from>is</from>
<head>Learning</head>
<body>XXE</body>
</note>
- PCDATA
PCDATA的意思是被解析的字符数据。PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。
被解析的字符数据不应当包含任何&,<,或者>字符,需要用& < >实体来分别替换。 - CDATA
CDATA意思是字符数据,CDATA 是不会被解析器解析的文本,在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
在上述例子中我们只定义了四种标签,因此不能再有其他标签,否则会报错,如果要添加新的标签,首先得在DTD中定义
2、外部DTD
(1)引入外部的dtd文件
<!DOCTYPE 根元素名称 SYSTEM "dtd路径">
(2)使用外部的dtd文件(网络上的dtd文件)
<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文档的URL">
当使用外部DTD时,通过如下语法引入:
<!DOCTYPE root-element SYSTEM "filename">
示例代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root-element SYSTEM "test.dtd">
<note>
<to>xxr</to>
<from>is</from>
<head>Learning</head>
<body>XXE</body>
</note>
test.did
<!ELEMENT to (#PCDATA)><!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)><!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)><!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)><!--定义body元素为”#PCDATA”类型-->
3、DTD属性
属性声明语法:
<!ATTLIST 元素名称 属性名称 属性累型 默认值>
DTD实例:
<!ATTLIST payment Luckey CDATA "Q">
XML实例:
<payment Luckey="Q" />
以下是 属性类型的选项:
默认属性值可使用下列值:
其实跟HTML标签属性原因
4、DTD实体
一般实体和参数实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量
实体引用是对实体的引用
实体可在内部或者外部进行声明
可以理解DTD实体就是定义应该变量,给标签内的元素赋值
DTD实体假如按照参数有无,可以分为两种,一般实体、参数实体
一般实体的声明:<!ENTITY 实体名称 "实体内容">
参数实体的声明:<!ENTITY % 实体名称 "实体内容">
一般实体在代码块中引用通过&名称
进行引用,而参数实体是通过%名称
进行引用的
另外需要注意的是他们引用的位置,一般实体直接在代码块进行引用如:
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
<!ENTITY writer "Dawn">
]>
<test>&writer;</test>
如上,直接给元素进行赋值
而参数实体是在DTD内部进行引用,如:
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
<!ENTITY %writer "Dawn">
%writer
]
>
<test>test</test>
内部实体和外部实体
假如按照引用来划分,可以分为内部实体和外部实体,引用方式和引用内部DTD和外部DTD一样
- 外部实体:
外部实体,用来引入外部资源。有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机。
<!ENTITY 实体名称 SYSTEM "URI/URL">
或者
<!ENTITY 实体名称 PUBLIC "public_ID" "URI">
例如:
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
<!ENTITY file SYSTEM "file:///etc/passwd">
<!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
]>
<author>&file;</author>
外部实体的引用是支持协议的,如file协议,http协议,对于PHP的话支持的协议更多,比如filter,data,php等等…..
- 内部实体
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE test [
<!ENTITY writer "Dawn"> #这个就是内部实体,其实和上面的一般实体一样
]>
<test>&writer;</test>
参数实体+外部实体组合拳
参数实体和外部实体可以直接组合在一起使用
<!ENTITY % 实体名称 SYSTEM "URI/URL">
,如:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY % file SYSTEM "file:///etc/passwd">
%file;
]>
XML注入
XML注入和SQL注入有异曲同工之妙,原理就是闭合标签,达到闭合的效果,其实XML注入比较简单
如下XML是用于注册访问用户,其中用户名是由用户自己输入的。
<?xml version="1.0" encoding="UTF-8" ?>
<user role="guest">用户输入</user>
攻击者在输入用户的时候,可以构造" user1 < /user> < user role=“admin”>user2"数据去拼接XML,之后整个XML字符串将会变成如下格式。这样就添加了一个管理员权限的用户。
<?xml version="1.0" encoding="UTF-8" ?>
<user role="guest">user1</user>
<user role="admin">user2</user>
XXE外部实体注入
外部实体注入的利用有很多,下面是大佬的例子(尝试搭建没有成功,还是理解一下吧)
file协议来读:
<?php
libxml_disable_entity_loader (false);
$xmlfile = file_get_contents('php://input');
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
echo $creds;
?>
payload:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE creds [
<!ENTITY goodies SYSTEM "file:///c:/windows/system.ini"> ]>
<creds>&goodies;</creds>
XXE内部实体注入
主要方式就是外部实体加参数实体,通过报错带出参数
XML内部实体是实体的内容已经在Doctype中声明。内部实体格式:内部 实体攻击比较常见的是XML Entity Expansion攻击,它主要试图通过消耗目标程序的服务器内存资源导致DoS攻击。外部实体攻击和内部实体扩展攻击有不同的防护措施(禁止DTDs解析可以防护外部实体和内部实体攻击)。
Xpath基本语法
先说下Xpath的基本术语:
-
Parent:父节点
-
Child:子节点
-
Sibling:同胞节点
-
Ancestor:先辈节点
-
Descendant:后代节点
非常简单,我们用大佬的图理解一下就行
标签:XML,外部,实体,DTD,引用,XXE From: https://www.cnblogs.com/solitude0-c/p/17602647.html