BUU40 [安洵杯 2019]easy_serialize_php

题目源代码

php 复制代码
<?php

$function = @$_GET['f'];

function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
//implode 函数将数组 $filter_arr 中的元素用 | 连接成一个字符串。
// |在正则表达式中表示或的关系,所以连接后的字符串类似于 php|flag|php5|php4|fl1g。
// 前后的 / 表示正则表达式的定界符,末尾的i表示不区分大小写匹配
//最终的效果就是正则表达式匹配字符串中出现的任意一个过滤词
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}


if($_SESSION){
//unset()销毁整个会话数组
    unset($_SESSION);
}
//将user会话设置为guest表示当前用户为访客
$_SESSION["user"] = 'guest';
$_SESSION['function'] = $function;

//将 $_POST 数组中的元素提取出来,使其成为单独的变量。
//如果 $_POST 中有一个键为 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']));
}

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

源代码中提示我们在phpinfo里面有好东西,去看看

这个意思也就是说会在php解析完了以后包含d0g3_f1ag.php,大概率flag在这里

先从头捋一下:

GET\['img_path'\]不存在的时候---_SESSION'img'=base64-en("guest_img.png")

正常的逻辑就是,你这里$_SESSION'img'的值是guest_img.png定死了的,不会读取到flag文件

那怎么办呢,有两条路,第一条路是前面POST提交一个img是flag的值【这里提交变量为_SESSION这样进去就变成了_SESSION就能混进本来的超级全局变量里头去了,好好好这么玩是吧】,第二条路就是利用php的反序列化字符串逃逸减少的情况,将原本的_SESSION'img'=base64-en("guest_img.png")吞掉(变成前一个键的值),然后后面顺理成章接着我们构造的新的$_SESSION'img'的值

很明显第一条路中后面 $_SESSION'img' = base64_encode('guest_img.png');还会再赋值一次,这样就覆盖了之前提交的img值,不行,所以利用字符串逃逸减少

先写个序列化php,但是像原来那么写死活编译不出来,应该就是变量名不能是_SESSION的事

这样不对!!

php 复制代码
<?php
class _SESSION
{
    $public img='Z3Vlc3RfaW1nLnBuZw==';//guest_image.png
    $public user='guest';
    $public function='show_image';
}
$a=new _SESSION();
echo serialize($a);
?>

学习到个新的写法,就是直接写$_SESSION'xxx'

php 复制代码
<?php
$_SESSION["user"] = 'kkk';
$_SESSION['function'] = 'show_image';
$_SESSION['img'] = base64_encode('guest_img.png');
echo serialize($_SESSION);

//a:3:{s:4:"user";s:3:"kkk";s:8:"function";s:10:"show_image";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}
?>

(后来发现这里头function的值可以随便取。。。)

就先试试user的值为n*php,function的值为;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==

原本想这么构造,但是又发现一个很傻的问题就是,序列化前面有三个属性,对应不上

然后改成这样

这样做了还是不行,后来发现好像是顺序错了.......

.....

换个顺序重新来

过滤后的字符串,标蓝的是php以为的user的字符串,标黄的是实际输入的function的值

再将/d0g3_fllllllag编码后提交,长度都是20不用改

拿到flag

相关推荐
Scott9999HH2 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社3 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海3 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖4 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区7 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大7 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai7 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜8 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa8 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio