ctfshow_反序列化初识

学习新知识!反序列化!启动!

目录

web254

web255

serialize()/unserialize()

web256

web257

        (这里强调一下,必须用php内部的urlencode函数编码,不能用bp的编码,两者不一样)

web258

preg_match()绕过

web261

web262

反序列化字符串逃逸

web263


web254

        很长的题目,有类的运用,正好最近也有学java面向对象,这里尝试解读一下

        给出一个ctfshowuser类

其中拥有成员:账号、密码、是否为会员

拥有方法:检查是否为会员、会员账号登录、是vip就给你flag

        然后是主体

GET方式登录账号,检查是否为vip,决定输不输出flag

(这道题目好像就是考察对类的了解,还没涉及到反序列化)

然后答案就是构造/?username=xxxxxx&password=xxxxxx


web255

 

        题目把isvip的赋值取消了

                但是主体的uesr那有个unserialize()函数,这就是反序列化函数

serialize()/unserialize()

        简单来说就是可以将一个类的对象转化为字符串/可以将字符串转化成一个类的对象

具体格式是这样的

空字符        null --------> N;

整形            666 -------> i:666;

浮点型        66.6 ------->d:66.6;

布尔型        true -------->b:1;

                   false ------->b:0;

字符串        'shab' ------>s:4:"shab";

        这里的cookie里有反序列化的函数,我们可以通过cookie传入我们需要的对象。

题目里需要一个有vip的账号,所以我们传入的对象里就要有isvip=true

        去本地自己写自己运行一下

        得到pyload

O:11:"ctfShowUser":3:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";s:5:"isVip";b:1;}

         hackbar失败了,bp的话url编码一下就行


web256

        不仔细看还真看不出来,在vipOneKeyGetFlag方法里多了一层条件判断,就是username和password不能相等

        然后和之前一样去本地序列化一下就行

然后和刚刚一样的bp上传,不过我这里好像一直传不上去,也不知道为什么QAQ


web257

         这里开始,就有点反序列化的影子了,我们看到backDoor中有eval()函数,那么这里肯定是命令执行的地方,从主类开始看,可以__construct构造函数时创建新对象,然后__destruct析构函数时调用成员class里的getInfo函数,不过backDoor函数中也有getInfo函数。所以我们自己本地写代码时,需要把成员class改为backDoor,然后构造一下backDoor函数里code的参数

        (注意一下,魔术方法都是两个"_")

        然后和之前一样,通过bp传cookie的参数

        (这里强调一下,必须用php内部的urlencode函数编码,不能用bp的编码,两者不一样)


web258

 
        比起上一个题目,多了preg_match()过滤,过滤了形似o:123,c:123的字符串。

        这道题主要是想告诉我们,反序列化也可以通过php函数进行过滤,所以php特性一定要学好

(这个是我自己以前做的,这里提及一下)

preg_match()绕过

        除此之外还可以根据函数内的正则进行绕过

        这里在o:后面加一个+,这样就可以绕过o:8的限制了。

        虽然但是,我本地一直绕不过,也不知道什么原因,这里先放这里把。


 web259太难了,先放一放,之后专门写一篇写它,260太简单了也不写了

web261

         发现__invoke()函数里存在eval()函数,但是没有什么好的方式调用这个函数,然后__destruct()函数里有文件写入file_put_contents()函数

        解释一下:

        __invoke() —— 用调用函数的方式调用对象的时候的回应方法

        file_put_contents(a,b) —— 将b数据写入a文件

        然后同时存在__wakeup()__unserialize()两个魔术方法,这里注意,同时存在的话是只会调用__unserialize()。所以不用担心__wakeup()的die

        所以我们构造一下pyload

GET传入后打开877.php

        开始命令执行这部分不做详细解释。



web262

        一脸懵,题解师傅说上面的注释写了看message.php

        那么就从这里开始分析,首先一个主类,有四个成员,一个用与赋值的构造方法。

        主体是Cookie上传一个参数,并把它base64解码后进行反序列化,之后,如果该对象的token值为admin,那么就输出flag。

那么构造一下pyload

奇怪的是,别的师傅的wp说是字符串逃逸。

        好吧,好像是我这是非预期解。

        毕竟是学习,我这里还是学一下关于反序列化的字符串逃逸

反序列化字符串逃逸

        我们将对象序列化之后,会得到类似以下字符串

O:11:"ctfShowUser":3:{s:8:"username";s:6:"lierni";s:8:"password";s:6:"xxxxxx";s:5:"isVip";b:1;}

        我们来看这一段   s:8:"username";   意思是长度为8的字符串,内容为"username"。

        当存在某些函数将反序列化的字符串替换时,比如将username改为usernames,多加了一个字符,但是s的长度为8,这是对象在序列化的时候固定的,所以最后一个字母“s”就不会被读取,实现了逃逸

        那么当我们传入的username足够多,就有足够多可操作的字符可以构造我们想要的对象成员。

        举个例子,还是上面的代码  s:8:"username"; 

        我们传入25个username加上";s:4:"pass";s:6:"hacker";}(这些共计25个字符)然后username全被替换成usernames

        s:214:"usernameusername.........uesrname";s:4:"pass";s:6:"hacker";将会被替换成

        s:214:"usernamesusernames.......usernames";s:4:"pass";s:6:"hacker";

        因为字符会被"给制止,所以这里我们通过字符串逃逸,将一个成员变成了三个成员

        当然字符串逃逸还有字符减少情况,这里先不做赘述。

        回到题目中,我们可以上传三个值,但是不能改变token的值。题目中还有一个把fuck换成loveU的函数,那么我们就可以通过字符串逃逸改变token的值。

        我们需要构造";s:5:"token";s:5:"admin";}放在最后,总计27位,也就是说,我们需要传入27个fuck,这样就可以实现

构造

?f=123&m=123&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

        传入!

        然后访问message.php就行


web263

        搞这么帅,暂时没什么思路,direarch一下

        发现了check.php、flag.php、ww.zip

        这里进入一下www.zip,下载了源码

        我去,有种做大题目的感觉,然后有很多.php代码

inc.php

class User{
    public $username;
    public $password;
    public $status;
    function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }
    function setStatus($s){
        $this->status=$s;
    }
    function __destruct(){
        file_put_contents("log-".$this->username, "使用".$this->password."登陆".($this->status?"成功":"失败")."----".date_create()->format('Y-m-d H:i:s'));
    }
}

index.php

        分析一下可知,Cookie中的limit在base64解码后会传入session,然后调用inc.php里面的user类,这里可以看到user类里面有__destruct(),里面有文件写入函数,那么这里就是突破口啦。

        构造以下

        然后存入Cookie,带着cookie一起访问inc/inc.php,就会生成log-1.php,访问即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值