首页 > 其他分享 >unseping

unseping

时间:2023-11-20 14:13:39浏览次数:34  
标签:__ 函数 args wakeup unseping array 序列化

[来源 : 江苏工匠杯-难度1

image-20231118151559821


考点:

简单的php反序列化


00前置芝士:

反序列化漏洞

1.什么是序列化?(serialize)

image-20231118181007039

看不懂了,唉,简单来说就是将我们熟知能够看得懂的对象转化我们看不太懂的字符串,,,,例如这样的

O:4:"ease":2:{s:12:" ease method";s:4:"ping";s:10:" ease args";a:1:{i:0;s:24:"ca$@t$IFS$2`find${IFS}.`";}}

2.什么是反序列化?(unserialize)

image-20231118181544746

简单来说就是把字符串还原成开始的对象 ,,,逆过程

3.什么是反序列化漏洞?

image-20231118181729219

简单来说,就是存在unserialize()函数的地方,而这个反序列化的变量参数值,又是可控的(是由用户输入的,或者是用户可以进行修改),那这个地方可能就会有反序列化漏洞

魔术方法

1.__construct

在PHP中,__construct 方法用于在创建一个新的对象实例时进行初始化操作。当使用 new 关键字实例化一个类时,PHP会自动寻找并调用这个类中的 __construct 方法,从而执行一些初始化的工作,比如设置初始属性值、连接数据库、加载配置等等。例如:

class a_class {
    public function __construct() {
        echo 'Constructor called!';  //  构造函数调用!
    }
}

$obj = new a_class(); // 输出 "Constructor called!"

当实例化 a_class 类时,__construct 方法会被自动调用,输出 "Constructor called!"。

创建对象的时候调用__construct,也就是说,他是第一个

2. __destruct

__destruct 是另一个特殊的方法,它在面向对象编程中扮演着与 __construct 相反的角色。与 __construct 在对象实例化时执行初始化操作相对应,__destruct 方法则用于在对象即将被销毁时执行一些清理工作。

在许多编程语言中,包括PHP、Python等,都支持类似的析构函数(Destructor)的概念。在PHP中,当一个对象不再被引用或脚本执行结束时,PHP的垃圾回收机制会自动调用该对象的 __destruct 方法。

示例:

class a_class {
    public function __construct() {
        echo 'Constructor called!'; //  构造函数调用!
    }

    public function __destruct() {
        echo 'Destructor called!'; //析构函数调用!
    }
}

$obj = new a_class(); // 输出 "Constructor called!"
unset($obj); // 输出 "Destructor called!",当 $obj 变量被 unset 时,对象的 __destruct 方法会被调用

//unset()函数用于销毁给定的变量。

$obj 对象被销毁时(通过 unset($obj)),PHP会自动调用该对象的 __destruct 方法,执行一些清理工作,比如释放资源、关闭文件等。

通过在 __destruct 方法中进行清理工作,可以确保在对象生命周期结束时,相关的资源得到及时释放和清理,从而避免内存泄漏和资源泄露。

销毁对象的时候,或者结束的时候,执行__destruct 最后一个

4.__wakeup

在PHP中,__wakeup 是一个魔术方法(magic method),用于序列化反序列化过程中的特殊处理。当一个被序列化的对象进行反序列化时,如果该对象定义了 __wakeup 方法,PHP 反序列化机制会在完成反序列化后自动调用该方法。

__wakeup 方法可以用来重新初始化在序列化时可能被临时修改或清除的对象属性,以确保对象在反序列化后恢复到正确的状态。

//本题如果设置了重新初始化属性值,就gg了,只能尝试绕过_wakeup

示例:

class a_class {
    public $name;
    public $age;

    public function __wakeup() {
        echo "Object has been unserialized, performing custom wakeup actions.\n";
        //对象已经序列化,正在执行自定义_wakeuo操作。
        $this->age = 18; // 重新初始化年龄为 18 岁
    }
}

$data = serialize(new a_class());
$obj = unserialize($data);  //unserialize函数执行之前,调用__wakeup
// 输出 "Object has been unserialized, performing custom wakeup actions."

在上述示例中,当对序列化后的数据进行反序列化时,由于 MyClass 类定义了 __wakeup 方法,因此在反序列化完成后会自动调用 __wakeup 方法,执行一些自定义的操作,比如重新初始化对象属性。

通过使用 __wakeup 方法,可以在对象反序列化时执行一些特定的逻辑,确保对象在恢复状态时能够进行必要的处理和修正,从而增强程序的健壮性和灵活性。

就是说,__wakeup 方法在unserialize函数执行之前,自动优先执行

例子

<?php
class a_class {
    public $name = 'kecy';
    public $age = '520';
    
    public function __wakeup() {
        $this->name= 'kecy' ;
        $this->age = '520' ;
        echo '重新初始化成功!'."\n"; //换行用双引号包裹
    }
   public function find(){
        echo $this -> name."\n";
        echo $this -> age ."\n";
   }
}
$obj1 = new a_class('gaoleng','5201314');
$data = serialize($obj1);
$obj2 = unserialize($data); // 输出 "Object has been unserialized, performing custom wakeup actions."
$obj2 -> find();   // -> 是 PHP 对象成员访问符

这段输出结果是:

重新初始化成功!
kecy
520

也就是说,在反序列化执行之前,就已经执行了__wakeup方法了,,,如果这个地方自定义重新初始化值的话,我们自己构造的payload就没用了,,,(涉及到__wakeup函数的绕过

题目是没有的,题目的这里传递变量到waf去检测(如果能直接绕的话,本题都不用绕waf了,直接就绕__wakeup了)

涉及到的一些函数

1.call_user_func_array()

回调函数

回调函数是指在编程中作为参数传递给其他函数的函数。换句话说,它是一种被传递到其他函数中以供后者在合适的时机调用的函数。

在很多编程语言中,函数可以作为一等公民(first-class citizen),也就是说函数本身可以作为参数传递、赋值给变量、作为返回值返回,因此可以将函数作为参数传递给其他函数,这样的函数就被称为回调函数。

回调函数常用于异步编程、事件处理、处理列表或集合等场景。例如,在JavaScript中,回调函数经常用于处理异步请求的响应;在PHP等语言中,回调函数常用于对数组的每个元素执行相同的操作。

总的来说,回调函数为编程提供了一种灵活的方式,使得代码能够动态地根据需要去执行特定的逻辑。

//GPT回答

总结:回调函数是指作为参数传递给其他函数的函数。

call_user_func_array()是PHP中的一个函数,用于调用一个回调函数,并将参数以数组的形式传递给该函数。

它的语法如下:

call_user_func_array(callback $callback, array $param_arr): mixed

其中,$callback表示要调用的回调函数,可以是一个函数名的字符串、一个对象方法的数组或一个类的静态方法的数组$param_arr是一个包含参数的数组

call_user_func_array会将参数数组中的元素作为独立的参数传递给回调函数,并返回回调函数的返回值。

示例:

<?php
function talk($name,$age){
    echo 'my name is '.$name."\n";
    echo 'my age  is '.$age."\n";

}

$params = ['kecy', '520'];
$result = call_user_func_array("talk", $params);

输出:

my name is kecy
my age  is 520

2.exec()

命令执行函数 ,

exec(string $command, array &$output, int &$return_var);
  • $command 参数是要执行的系统命令。
  • $output 是一个可选参数,用于存储命令的输出结果。如果提供了这个参数,命令的输出将被存储在这个数组中。
  • $return_var 也是一个可选参数,用于存储命令执行后的返回值。

3.var_dump()

var_dump 是 PHP 中用于打印变量的结构信息的函数,通常用于调试目的。

它可以显示变量的数据类型和值,以及变量所包含的元素个数(对于数组)等详细信息。

var_dump 函数的基本语法如下:

var_dump(mixed $expression, mixed ...$expressions)
  • $expression 是要打印的变量或表达式。
  • 可以传入多个 $expressionvar_dump 会逐个打印它们的信息。
  • mixed 是 PHP 语言中的一个数据类型标识符,表示一个可以包含多种不同类型值的变量。它表示变量可以是任意类型的值,包括整数、浮点数、字符串、数组、对象等。

4.preg_match_all

preg_match_all 是 PHP 中用于执行正则表达式匹配的函数之一。它可以在一个字符串中查找所有匹配指定正则表达式的子串,并将匹配结果存储在一个数组中。

preg_match_all 函数的基本语法如下:

int|false preg_match_all(string $pattern, string $subject, array &$matches, int $flags = 0, int $offset = 0)
  • $pattern 参数是要匹配的正则表达式。
  • $subject 是要搜索的字符串。
  • $matches 是一个用于存储匹配结果的数组。所有的匹配结果都将被存储在这个数组中。
  • $flags 是一个可选参数,用于指定正则表达式的匹配模式。
  • $offset 是一个可选参数,用于指定搜索的起始位置。

示例

$string = "flag{03423e14a8787eb026fde25d03fb94b4} ";
$pattern = "/flag/";

preg_match_all($pattern, $string, $matches);

var_dump($matches);

运行上述代码后,会输出如下结果:

array(1) {
  [0]=>
  array(1) {
    [0]=>
    string(4) "flag"
  }
}

//对应:
//$array = array(
//    0 => array(
//        0 => "flag"
//    )
//);

emm暂时没有了,,,


WP

1.题目

进去之后直接就是一长串源码,emm

image-20231118151758942

还是直接copy下来,放sublime,,,,舒服多了

标签:__,函数,args,wakeup,unseping,array,序列化
From: https://www.cnblogs.com/GaolengDeKecy/p/17843735.html

相关文章

  • CTFer成长记录——CTF之Web专题·攻防世界—unseping
    一、题目链接  https://adworld.xctf.org.cn/challenges/list二、解法步骤  本题主要是代码审计和反序列化;代码审计:首先我们需要知道整个题的基本执行顺序:post传参——>base64编码——>反序列化——>调用__wakeup()魔术方法——>执行waf()方法过滤——>调用析构方法()。......
  • [攻防世界][江苏工匠杯]unseping
    打开靶机对应的url上来就是代码审计<?phphighlight_file(__FILE__);classease{private$method;private$args;function__construct($method,......
  • 攻防世界-unseping(序列化,Bash shell)
    这是一道序列化的题目,结合了LinuxBashshell知识一、基础知识点序列化  序列化的概念:  序列化(Serialization)是将对象的状态信息转换为可以......
  • unseping
    unseping很明显一个反序列化进行的RCE但是中间的坑很多本来想着桡过wakeup函数,但是没有绕过,可能是php版本比较高于是绕着过滤硬上,发现过滤还好不是很多空格过滤了......
  • 攻防世界-unseping
    题目<?phphighlight_file(__FILE__);classease{private$method;private$args;function__construct($method,$args){$this->metho......
  • 江苏工匠杯unseping(反序列化+Linux命令执行{$(printf '\154\163')})
    <?phphighlight_file(__FILE__);classease{private$method;private$args;function__construct($method,$args){$this->method=$m......