题目地址:
打开页面发现是一个注册于登录页面,注册登录发现是个类似网盘的功能,初始时在登录和注册页面尝试sql注入发现不行,然后在下载功能尝试下载发现登录和注册位置对数据库操作进行了prepare()的预处理,网盘有个下载功能,尝试下载,尝试任意下载,抓包,将下载内容改为源码(有index.php class.php upload.php download.php login.php register.php),为啥要加../../呢??前期我也不知道,看了别人题解发现,下载源码发现download.php,限制了切换了目录,同时没法下载其他目录,这就是后来为啥要用delete功能来phar://,那个位置没有进行目录的切换,然后想尝试文件上传来getshell,首先上传时进行了后缀判读,而且我们不知道上传后了路径,所以考虑其他方法
查看delete.php,new file()其用了delete()函数,到class.php中查看detele()使用unlink()来删除,而unlink()函数是phar反序列化受影响函数,那么下面我们想要的就是构造就是打开显示flag.txt文件,为啥flag在flag.txt中我就不知道了,可能ctf选手直觉,有点玄学了,如果你知道可以评论告诉我感谢,继续,在class.php中发现close()中File类file_get_contents(),但是没法调用,然后发现user类中的析构函数调用了close类,如果我们令$db=new File();的化,但是虽然我们打开了文件,但是没用回显,所以还是看不见文件内容,所以要构造其他的pop链,然后发现FileList()中存在魔法函数_call,如果调用了不存在的函数就会执行,call函数的作用: public function __call($func, $args) { array_push($this->funcs, $func); //如果调用了不存在的方法,将改方法放到funcs数组中 foreach ($this->files as $file) { //再从files数组中取出方法,利用这个元素去调用funcs中新增的func $this->results[$file->name()][$func] = $file->$func(); //因为调用了不存在的键值close(),所以func=close,所以$file->$func相当于调用close()函数 } }
而close函数打开$this->filename文件,所以我们构造File中的filename=./flag.txt就能打开该文件,而且该文件的内容存储到了results数组键值中,然后我们查看
File类中的析构函数,发现:
这里对result的键值进行了输出,所以就能得到flag.txt中的内容
最后payload:
session用于跟踪用户的行为,保存用户的信息和状态等等
session当用户第一次访问网站时,session_start()函数就会创建唯一的sessionid,通过HTTP响应将sessionid保存到用户的cookie中。同时在服务器创建一个sessionid命名的文件,用于保存这个用户的会话信息。当用户再次访问这个网站时,也会通过http请求将cookie中保存的session再次携带,但是服务器不会再创建同名文件,而是硬盘中寻找sessionid的同名文件,且将其读取出来。
服务器session_start()函数作用
当会话开始或通过session_start()开始时,php内部会通过传来的sessionid来读取文件,php会自动序列化sessio文件内容,并将其填充到超全局变量$_SESSION中。如果不存在对应的会话数据,则创建一个sessionid的文件。如果用户为发送sessionid,则创建一个由32个字母组成的phpsessionid,并返回set-cookie