2021红帽杯线下赛WEB upload题解
2021-7-30
| 2024-2-3
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
虽然没参加,不过有个师傅跑过来讨论了,就顺便搞搞,第一题是opensns的nday,这里主要分析下第二题upload。还挺有意思,原来一开始想着用像 [CVE-2021-3129](https://tari.moe/2021/06/03/laravel8-debug-rce/ 的方式写入可控的 session文件,结果 h 被过滤了。。

upload

源码
 

源码分析

关键文件有两个:index.php 和 info.php
info.php 主要是告诉我们,session存在 /tmp 目录下
notion image
index.php 内容较多,不过分析了一波,首先映入眼帘的是 file_put_contents 方法,参数没有进行过滤,存在目录穿越。那我们可以通过目录穿越写 session 文件了。
PHP的session默认是以文件的形式进行存储,而且文件名是以 sess_ 开头的,后面的值为,为我们Cookie中 PHPSESSID=xxxxxxxxxxxxx 的 xxxxxxxxxxxxx。也就是我们以 PHPSESSID=xxxxxxxxxxxx 访问站点,PHP会在 /var/lib/tmp/php 之类的目录创新一个名为 sess_xxxxxxxxxxxxx 的文件,内容为序列化后的数据。
但题目过滤了字符 h
正常来说,我们是没法目录穿越至存放 session 的路径的,毕竟有 /phph,但,题目中 session.save_path 在 /tmp 目录,而且写入的内容没有限制,也就是说我们可以任意伪造 session 了。
75行处看似可以调用函数
仔细一分析… 这里 ${} 原来是一种简单语法,也就是先获取$_SESSION['func']的值,作为变量名,然后作为函数名去调用,当然可以构造 $_SESSION['func']_SESSION["paths"] 然后 $_SESSION["paths"]system 之类的,但 $pathinfo 是数组…. 暂时没发现啥方法是传入数组进行利用的。
所以另辟蹊径,发现56行 new 了一个对象
下面有个直接输出
echo 对象会触发对象的 __toString 魔术方法,如果能找到啥对象实例化后的 __toString魔术方法,会对 $path 进行一些利用(如输出这个参数文件内容,执行这个参数命令之类的)就好了。
刚好找到一个脚本 (
可以查看PHP原生类即内置类,查看拥有所需魔术方法的类如下
这里只获取 __toString,所以把其他注释了
运行结果
看到一些反射之类的,当然发现了一个 SplFileObject 类,发现他的 __toString 方法是 SplFileObject::fgets 方法的别名,作用是一行行文件读取。 flag 文件一般是一行,刚好满足要求。

实际利用

创建一个 flag 文件,内容为
notion image
先构造 session
然后访问一下这个文件,记得看请求的 Cookie: PHPSESSID 的值,然后到本地找到文件,把生成的内容复制一下,粘贴到 content 字段。因为php session 都是sess开头的,所以通过目录穿越写入 sess_tari
notion image
写入session后
notion image
实例化时,实际是实例化了 SplFileObject("/tmp/flag")
notion image
notion image
然后就会输出任意我们想输出的文件内容了
notion image
搞定~

参考链接

[1] https://www.freebuf.com/articles/web/263710.html
[2] https://mp.weixin.qq.com/s/ucjyuXnWn4PkiD_40Eydkw
  • CTF比赛
  • Writeup
  • 人工智能在网络安全领域的技术和应用2021强网杯 Web Writeup
    • GitTalk
    目录