代码编织梦想

前言

最近遇到了这个知识点,网上找了好几篇这方面的好像都不太仔细,自己来总结下

0x01 序列化和反序列化

serialize()

所有php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。
序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字
如下面的:

<?php
class people{
	public $name = 'lonmar';
	protected $age = 99;
	private $sex = 'man';
}
$lonmar = new people();
var_dump(serialize($lonmar));
// string(88) "O:6:"people":3:{s:4:"name";s:6:"lonmar";s:6:"<0x00>*<0x00>age";i:99;s:11:"<0x00>people<0x00>sex";s:3:"man";}"	

在这里插入图片描述
对于对象,序列化后的格式为:
O:strlen(类名):类名:类的变量个数:{类型:长度:值;类型:长度:值…}

其他类型的数据序列化后的格式为:

String类型 :s:size:value;
Integer类型 :i:value;
Boolean类型 : b:value;(保存1或0)
Null型 :N;
Array :a:size:{key definition;value definition}

对象中成员的形式,不同属性的差别主要体现在key上,而且key一定是string,直接给出模式,具体形式可以参考上面的示例:

public: s:size:value size是string长度
protected: s:size+3:<0x00>*<0x00>value 这里<0x00>是一个字符,十六进制为00
private: s:size+strlen(class_name)+2:<0x00>class_name<0x00>value

还有需要注意的点是;分割不同字段}结尾,这对反序列化很重要

unserialize()

unserialize() 对单一的已序列化的变量进行操作,将其转换回 PHP 的值

反序列化特点

  1. php在反序列化时,底层代码是以 ;作为字段的分隔,以 } 作为结尾

这会造成,随便在序列化数据后添加一些无用字符,反序列化的时候也会被忽略,因为遇到了;}会忽略后面的字符
在这里插入图片描述

  1. unserialize根据长度判断内容,长度不对应的时候会报错
    在这里插入图片描述
    或者下面这个例子:
    在这里插入图片描述

  2. 可以反序列化类中不存在的元素

在这里插入图片描述

0x02 字符逃逸

字符逃逸某种角度上和sql注入类似,都是通过构造闭合的方式构造payload,只不过字符逃逸构造闭合注意点在长度,因为闭合标志固定,都是;}

前面提到在unserialize的时候, 当你的字符串长度与所描述的长度不一样时就会报错.比如 s:3:"Tom"变成s:4:"Tom"或s:2:"Tom"就会报错. 可以通过拼接字符串的方式来使它不报错

所以字符逃逸又分为两类

  1. 字符变多
  2. 字符变少

字符变多

例子:

<?php
highlight_file(__file__);
function filter($str){
    return str_replace('l', 'll', $str);
}

class person{
	public $name = 'lonmar';
	public $age = '100';
}
$test = new person();
$test = serialize($test);
echo "</br>";
print_r($test);
echo "</br>";
$test = filter($test);
print_r($test);
print_r(unserialize($test));

在这里插入图片描述

因为替换过后,实际长度为7,而描述长度为6,少读了一个r 所以失败

这种字符增多是反序列化失败是因为漏读了字符串的value,如果构造恶意的value,再故意漏读

如令$name='lonmar";s:3:"age";s:2:"35";}'

如果再进行替换,lonmar=>llonmar,后面的}又读不到

再多几个l,lllllllllllllllllllllonmar=>llllllllllllllllllllllllllllllllllllllllllonmar ,";s:3:"age";s:2:"35";}就又读不到

只能读到lllllllllllllllllllllonmar这样后面的;s:3:“age”;s:2:“35”;}就逃逸掉了,逃逸掉的字符串可以把原来后面的正常序列化数据提前闭合掉.(闭合条件";}

;s:3:"age";s:2:"35";}长度是22 , 所以只需要22个l
如下:

<?php
function filter($str){
    return str_replace('l', 'll', $str);
}

class person{
	public $name = 'llllllllllllllllllllllonmar";s:3:"age";s:2:"35";}';
	public $age = '100';
}
$test = new person();
$test = serialize($test);
var_dump($test);
$test = filter($test);
var_dump($test);
var_dump(unserialize($test));

这里类名做了替换people=>person 因为people里也有l

在这里插入图片描述
可以观察到age变成了35,
name不是llllllllllllllllllllllllllllllllllllllllllllonmar";s:3:"age";s:2:"35";} 而是 llllllllllllllllllllllllllllllllllllllllllllonmar
因为;s:3:“age”;s:2:“35”;}逃逸,之后终止标志变成了;s:3:“age”;s:2:“35”;}里的;} 后面的就被忽略了

字符减少

字符减少,反序列化的时候就会多读

<?php
highlight_file(__file__);
function filter($str){
    return str_replace('ll', 'l', $str);
}

class person{
	public $name = 'lonmar';
	public $age = '100';
}

同样的,如果构造恶意的age,让反序列化的时候多读,把age一部分读进去 同样可以达到某种目的

正常的数据 O:6:"person":2:{s:4:"name";s:6:"lonmar";s:3:"age";s:3:"xxx";}

如果做替换,让也";s:3:"age";s:3:"被读进name,再把xxx替换为;s:3:“age”;s:3:“100”;}

$age=123";s:3:"age";s:3:"100";}

O:6:"person":2:{s:4:"name";s:47:"llllllllllllllllllllllllllllllllllllllllllonmar";s:3:"age";s:26:"123";s:3:"age";s:3:"111";}";}

多读的为 ";s:3:"age";s:26:"123 长度 21

构造(l*42)nmar, 就多吞了部分字符串,

name:
llllllllllllllllllllllllllllllllllllllllllonmar =>
lllllllllllllllllllllonmar";s:3:"age";s:26:"123

age:

123";s:3:"age";s:3:"111";}
=>
111
在这里插入图片描述

总结

大致就像前面例子那样,根据字符增多或者减少,让该成员反序列化时,部分字符逃逸或者吞掉后面成员的部分字符达到一定目的

具体题目: https://blog.csdn.net/weixin_45551083/article/details/111084908

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/weixin_45551083/article/details/111085944

渗透测试之信息收集-爱代码爱编程

信息收集 在安全测试中,信息收集是非常重要的一个环节,此环节的信息将影响到后续的成功几率,掌握信息的多少将决定发现漏洞机会大小和攻击面的多少,换言之信息收集决定着你是否能完成目标的测试任务。也可以很直接的说:渗透测试的思路就是从信息收集这里开始,你与大牛的差距也是从这里开始的! 我把信息收集大致分为两种情况,有CDN和没有CDN,初学者大都还不明白CD

Linux安全基线Centos7-爱代码爱编程

安全基线检查 扫描用户和时间: user_id=whoami echo “当前扫描用户:${user_id}” scanner_time=date '+%Y-%m-%d %H:%M:%S' echo “当前扫描时间:${scanner_time}” echo “***************************” echo “账号策略检查中…” ec

ActiveMQ 任意文件写入漏洞(CVE-2016-3088)复现-爱代码爱编程

ActiveMQ 任意文件写入漏洞(CVE-2016-3088)复现 导语 ActiveMQ的web控制台分三个应用:admin、api和fileserver,其中admin是管理员页面,api是接口,fileserver是储存文件的接口。admin和api都需要登录后才能使用,fileserver无需登录。 fileserver是一个RES

关于计算ico文件hash值脚本-爱代码爱编程

如何利用ico文件查找出网站的真实IP地址,分享一个计算网站ico文件hash值的工具(python2和python3双版本代码) python2的工具脚本代码python3的工具脚本代码 python2的工具脚本代码 import mmh3 import requests response = requests.get('https://w

SQL注入写入一句话php(outfile方式)&中国菜刀连接-爱代码爱编程

通过SQL注入漏洞上传一句话 前言一、先读取路径二、用outfile写入1.关闭windows系统防护三、上传成功之后可以用某刀或者蚁剑 前言     具体原理不做讲解,直接开门见山此次试验全部在dvwa靶场实现,这里以dvwa的low级别为例 一、先读取路径 1' union select @@datadir,2# 二、用out

DVWA-文件包含全等级绕过方法-爱代码爱编程

dvwa文件包含File Inclusion全等级绕过 前言一、Low级别1.1分析文件包含漏洞测试网页1.2 构造URL暴露重要信息1.3 测试本地脚本运行1.4 测试远程脚本运行1.5 包含一句话木马文件,并用菜刀连接1.5.1 一句话木马1.6 上菜刀二、Medium级别2.1双写绕过2.2大小写绕过2.3 绝对路径绕过三、High级别3.1

【PHP】函数echo,print,print_r,var_dump的区别-爱代码爱编程

var_dump()函数 判断一个变量的类型与长度,并输出变量的数值,如果变量有值,输出的是变量的值,并返回数据类型。此函数显示关于一个或多个表达式的结构信息,包括表达式的类型和值。数组将递归展开值,通过缩进显示其结构。 $a = "Hello"; //字符串 $b = 1433223; //整型 $c = array("Apple","Orang

强制修改/移除 WordPress 主题底部版权标识-爱代码爱编程

目录: 一、常用的方法——直接在主题编辑器里面改 二、万能的方法——在 Linux 系统中改 php 内容 一、常用的方法——直接在主题编辑器里面改 1、打开 WordPress 后台管理,点击【外观】 2、点击【主题编辑器】 3、在主题文件栏,选中【主题页脚】footer.php,这是页脚的 php 文件 4、找到 printf 函数,将后面括号里的

PHP 8 的新特性(续)-爱代码爱编程

新增 fdiv() 函数 pr 新的 fdiv() 函数的作用类似于fmod() 和 intdiv() 函数,它们可以除以 0。视情况而定,将得到 INF,-INF 或 NAN。 新增 get_debug_type() 函数 rfc get_debug_type() 返回变量的类型,听起来好像跟 gettype() 的作用一样啊?get_debug_

sqli-labs靶场1-4关-爱代码爱编程

第一关 判断注入点: ?id=1 回显正常?id=1’ 回显错误可以判断出是基于单引号注入 然后and判断一下 ?id=1’ and 1=1 回显正常?id=1’ and 1=2 回显错误证明存在注入漏洞 则or 相反 ?id=1’ or 1=2 --+ (回显正常) ?id=1’ or 1=1 --+ (回显错误,证明存在注入漏洞)//(暂时没验证)

sqli-labs靶场5-6关(双查询注入)-爱代码爱编程

知识点 双查询注入的知识点 原理:双注入查询需要联合着MYSQL的BUG报错来进行报错注入 BUG:当在一个聚合函数,比如count函数后面如果使用分组语句就会把查询的一部分一错误形式显示出来; 双查询在命令行中直观显示出来 select count(*),concat((select user()),(floor(rand() * 2))) as

sqli-labs靶场7关(知道根目录的注入)-爱代码爱编程

知识点 首先要掌握一下相关的函数和知识点 函数: load_file()函数 是MySQL读取本地文件的函数(读取) into outfile()函数 是用来导出文件的(写入) @@basedir函数 查询当前路径 @@datadir函数 查询数据库安装路径 1.load_file()函数用法2.into outfile()函数用法查看