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
目录下index.php 内容较多,不过分析了一波,首先映入眼帘的是
file_put_contents
方法,参数没有进行过滤,存在目录穿越。那我们可以通过目录穿越写 session 文件了。PHP的session默认是以文件的形式进行存储,而且文件名是以 sess_ 开头的,后面的值为,为我们Cookie中 PHPSESSID=xxxxxxxxxxxxx 的 xxxxxxxxxxxxx。也就是我们以 PHPSESSID=xxxxxxxxxxxx 访问站点,PHP会在 /var/lib/tmp/php 之类的目录创新一个名为 sess_xxxxxxxxxxxxx 的文件,内容为序列化后的数据。
但题目过滤了字符
h
正常来说,我们是没法目录穿越至存放 session 的路径的,毕竟有
/php
有 h
,但,题目中 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 文件,内容为
先构造 session
然后访问一下这个文件,记得看请求的 Cookie: PHPSESSID 的值,然后到本地找到文件,把生成的内容复制一下,粘贴到 content 字段。因为php session 都是sess开头的,所以通过目录穿越写入 sess_tari
写入session后
实例化时,实际是实例化了
SplFileObject("/tmp/flag")
然后就会输出任意我们想输出的文件内容了
搞定~
参考链接
[1] https://www.freebuf.com/articles/web/263710.html
[2] https://mp.weixin.qq.com/s/ucjyuXnWn4PkiD_40Eydkw