xxe注入学习笔记
前言
这段时间学习了下xxe注入的一些知识,这里做下总结
xml语言和xxe介绍
xml是一种类似html但对闭合要求更严格的标记符号语言,主要用于数据传输。
下面是一段xml的实例
1 | <!--声明--> |
这个文档有以下几部分,文档声明,文档定义,文档元素,第一部分是声明,之后跟着的是文档定义,<!DOCTYPE 文档名 [内容]>,文档定义中嵌套实体,文档定义内可以嵌套实体定义,格式如下,<!ENTITY 实体名 “内容”>。定义结束后由文档定义的元素作为该文档的根元素,之后的所有元素需要正确嵌套入根元素内。
xml的实体共有五种,这里我们需要注意的主要有三种:
外部实体,区别主要是是在实体名后如果跟着SYSTEM关键词,关键词后面跟着的外部文件的url,而外部实体的内容则是引用文件内的内容,可以通过&实体名;的形式来引用实体。
内部实体 ,主要指的是在实体中嵌套另外一个实体,类似
于1
需要注意的是被嵌套实体中的 % ,< 等字符需要进行html实体编码,16或者8进制皆可。
参数实体,类似于
1
%remote;
%all;
%send;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
参数实体的声明时的实体名前有%关键字,而引用时应用%实体名;来引用。
  xxe,xxe指的是外部实体注入,上面的实体定义不仅可以定义内部实体,也可以定义外部实体,引用远端的xml中定义的实体,并解析。并且可以根据不同的协议扩展为ssrf,任意命令执行,任意文件读取,ddos等等。
## xxe注入演示
### 实验环境交代
windows server 2008 r2 phpStudy php 5.3.29 libxml 2.7.8(libxml 2.9.4以及以上版本无效)
### 实验代码
+ reference: https://github.com/c0ny1/xxe-lab 中的php_xxe
关键代码如下
```php
$USERNAME = 'admin'; //账号
$PASSWORD = 'admin'; //密码
$result = null;
libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');
try {
$dom = new DOMDocument();
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
$creds = simplexml_import_dom($dom);
$username = $creds->username;
$password = $creds->password;
if ($username == $USERNAME && $password == $PASSWORD) {
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>", 1, $username);
} else {
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>", 0, $username);
}
} catch (Exception $e) {
$result = sprintf("<result><code>%d</code><msg>%s</msg></result>", 3, $e->getMessage());
}
header('Content-Type: text/html; charset=utf-8');
echo $result;
回显注入
先正常登录一次,抓包
可以看到这里username和password是以xml文档的形式提交的,这段文档将会被simplexml_import_dom方法解析为dom。这个过程中因为load_XML设置了LIBXML_DTDLOAD和LIBXML_NOENT,所以可以加载解析外部实体,并且会回显username。我们改包试一下。
非回显注入
payload:
eval.dtd:
1 |
2.php:
1 |
|
这里要注意三个实体的解析顺序不能乱,读取的数据将被发送到2.php上。
报错注入
首先解析eval和f1实体,解析完后继续解析error实体,报文件不存在将f1内容回带。
漏洞验证流程
应当先验证实体是否能被解析,然后验证是否能加载外部实体,最后可以尝试是否能报错。
总结
总得来说,xxe的思路还是和sql注入有些类似,从回显的union注入到盲注,报错,结果外带,由于时间有限的缘故,只写了一文件包含的利用,不过对于入门来说,足够了。