<?php
$function = @$_GET['f'];
//定义了一个函数,将敏感字符串替换为空。
function filter($img){
$filter_arr = array('php','flag','php5','php4','fl1g');
$filter = '/'.implode('|',$filter_arr).'/i';
return preg_replace($filter,'',$img);
}
//如果设置了session,就清空session
if($_SESSION){
unset($_SESSION);
}
//赋值
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;
//首先说明一下extract()的作用,他已经在$_SESSION中复制了,我再次在POST中传入SESSION中传入user和function,那么我的值就覆盖他的值。
extract($_POST);
if(!$function){
echo '<a href="index.php?f=highlight_file">source_code</a>';
}
//判断是否img_path赋值
if(!$_GET['img_path']){
$_SESSION['img'] = base64_encode('guest_img.png');
}else{
$_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
}
//调用filter函数,过滤。
$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']));
}
贴一下源码。
分析一下。
1,首先查看下phpinfo
看到了d0g3_fllllllag
2,现在就是如何让file_get_conment()读取了。
先贴一个php
从上述例子可以看出来,当序列化再反序列化后,依旧可以根据键名的到值。键名就是img。
但是他给出的例子中并没有$_SESSION[img'],这时候就需要利用到php反序列化逃逸。
举一个简单的例子。
反序列化中的对象是以{}作为开头结尾的,并且有对象名,对象的类型,对象的长度。问题就出现在对象的长度上面。
在这道题中是将falg,php.......等字符串替换为空,替换完成后对象名,对象的类型,对象的长度都没变,但是内容没了。再次序列化时他还是会依据这些来序列化。那么他就会依据长度吧后面的内容给囊括进去。
巧合地是,这时候又变成了一个完整的反序列化内容,又可以被解析,于是我们就可以依据这点来利用。
他不是只让穿user和fuction嘛,那我们就自己构造一个。
buuctf-[安洵杯 2019]easy_serialize_php (小宇特详解)_buuctf easy_serialize_php-CSDN博客
贴一下师傅的文章。
[安洵杯 2019]easy_serialize_php - 何止(h3zh1) - 博客园 (cnblogs.com)
这两位师傅讲述得非常清楚。