[来源 : 江苏工匠杯-难度1
考点:
简单的php反序列化
00前置芝士:
反序列化漏洞
1.什么是序列化?(serialize)
看不懂了,唉,简单来说就是将我们熟知能够看得懂的对象转化我们看不太懂的字符串,,,,例如这样的
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)
简单来说就是把字符串还原成开始的对象 ,,,逆过程
3.什么是反序列化漏洞?
简单来说,就是存在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
是要打印的变量或表达式。- 可以传入多个
$expression
,var_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
还是直接copy下来,放sublime,,,,舒服多了
标签:__,函数,args,wakeup,unseping,array,序列化 From: https://www.cnblogs.com/GaolengDeKecy/p/17843735.html