PHP反序列化二

1.反序列化基础利用

2.pop链

POP链: POP(面向属性编程)链是指从现有运行环境中寻找一系列的代码或指令调用,然后根据需求构造出一组连续的调用链。

反序列化利用就是要找到合适的POP链。其实就是构造一条符合原代码需求的链条,去找到可以控制的属性或方法,从而构造POP链达到攻击的目的。

寻找POP链的思路:

A.寻找unserialize0函数的参数是否可控;

B.寻找反序列化想要执行的目标函数,重点寻找魔术方法(比如 wakeup()和 destruct())

C.一层一层地研究目标在魔术方法中使用的属性和调用的方法,看看其中是否有我们可控的属性和方法

D.根据我们要控制的属性,构造序列化数据,发起攻击

解题思路:

A.构造利用链,就要找到头和尾。再想办法把头和尾连接起来。

B.sid和config是用户输入可以控制的,这是利用链的头部。

C.最终目的是读取flag.php文件,就要从源代码中需要可以读文件或者执行系统命令的地方。Read->get_file和Show->show可以读取文件,但是Show->show函数不允许出现flag。因此,Read->get_file就是POP链的尾部,

D.如何触发Read->get_file呢?搜索get_file发现,Show-> tostring中存在代码:content=this->class1->get_file(this-\>var);那么只需要让this->class1=new Read;$this->var='flag.php'即可触发get_file,得到flag.php

E.那么如何触发Show->tostring呢?本题存在手动触发函数的命令config-\>sid;,参数是用户控制的(POP链的头部),因此可以令:config=new Show;sid='__toString';这样就完成了pop链的构造

解法一:

解法二:

由于_tostring是魔术方法,还可以自动触发,触发条件为"把对象当成字符串使用",那么就需要寻找使用字符串的地方,传入对象,就可以触发_tostring了。本题中preg_match函数的参数就是字符串,因此需要

$this->source=show;//this就是当前的类,因此本题要生成两个show对象,其中一个Show对象的source属性值为另一个show对象

再利用config-\>sid触发Show->Change或者Show->show方法即可。

3.畸形序列化字符串

(1)认识畸形序列化字符串

畸形序列化字符串就是故意修改序列化数据,使其与标准序列化数据存在个别字符的差异,达到绕过一些安全函数的目的。

应用领域:

a.绕过 wakeup( )

b.快速析构(fast destruct):绕过过滤函数,提前执行_destruct

(2)绕过_wakeup

由于使用unserialize( )函数后会立即触发_wakeup,为了绕过_wakeup中的安全机制,可以用修改属性数量的方式绕过wakeup方法。受影响版本:

php5.0.0~ php5.6.25

php7.0.0 ~ php7.0.10

绕过方法:

反序列化时,修改对象的属性数量,将原数量+n,那么_wakeup方法将不再调用。比如:

//标准序列化数据

0:3:"BUU":2:{s:7:"correct";N;s:5:"input";R:2;}

//修改为:

0:3:"BUU":3:{s:7:"correct";N;s:5:"input";R:2;}

(3)快速析构

快速析构的原理:当php接收到畸形序列化字符串时,PHP由于其容错机制,依然可以反序列化成功。但是,由于你给的是一个畸形的序列化字符串,总之他是不标准的,所以PHP对这个畸形序列化字符串得到的对象不放心,于是PHP就要赶紧把它清理掉,那么就触发了他的析构方法(_destruct( ))。

应用场景:某些题目需要利用_destruct才能获取flag,但是_destruct是在对象被销毁时才触发(执行顺序太靠后),_destruct之前会执行过滤函数,为了绕过这些过滤函数,就需要提前触发_destruct方法

畸形字符串的构造方法:

A.改掉属性的个数

B.删掉结尾的 }

(4)例题

解题思路:

A.明确POP的起点:unserialize($ GET['poc'])

B.明确POP的终点:Demo2-> tostring()

C.怎样连接起点和终点?

DemoX->_destruct( )//不能执行DemoX->wakeup( )

DemoX->_tostring( )

Demo2->_tostring( )

D.怎样执行绕过DemoX->_wakeup( )?先生成正常的序列化数据,再改变属性个数。

E.通过对比,定位到属性个数为2的数据,然后修改为3,得到payload:

O%3A5%3A%22DemoX%22%3A3%3A%7Bs%3A7%3A%22%00%2A%00user%22%3BO%3A5%3A%22Demo2%22%3A1%3A%7Bs%3A13%3A%22%00Demo2%00fffl4g%22%3Bs%3A8%3A%22flag.php%22%3B%7Ds%3A6%3A%22%00%2A%00sex%22%3Bs%3A3%3A%22xxx%22%3B%7D

检查页面源代码得:

4.指针问题

解题思路:

A.构造POP链,就要找到头和尾,再想办法把头和尾连接起来

B.$p是用户输入的,是可控的,这是POP链的头部

C.最终目的是要读取flag.php,就要从源代码中找到可以读文件或者执行系统命令的地方。通读后可知Alize->getFlag( )可以读取文件。

echo @highlight_file($this->f,true);

那么,只需要令

$this->f='flag.php';

this-\>t1 === this->t2:

因此 Alize->getFlag( )就是POP链的尾部。

D.如何触发Alize->getFlag( )呢?搜索 getFlag,发现 Seri->_destruct( )中存在代码$this->alize->getFlag();

那么,只需要令

$this->alize=new Alize;

这样就完成了POP链的构造。

相关推荐
网络安全许木7 小时前
自学渗透测试第21天(基础命令复盘与DVWA熟悉)
开发语言·网络安全·渗透测试·php
菩提小狗7 小时前
每日安全情报报告 · 2026-04-22
网络安全·漏洞·cve·安全情报·每日安全
爱学习的小囧7 小时前
ESXi VMkernel 端口 MTU 最佳设置详解
运维·服务器·网络·php·虚拟化
WangJunXiang68 小时前
GFS分布式文件系统
开发语言·php
Chockmans10 小时前
图片马合成保姆级教程
web安全·网络安全·系统安全·网络攻击模型·安全威胁分析·安全架构·春秋云境
Chengbei1111 小时前
红队专属Bing Dork自动化工具,敏感信息侦察效率拉满、自动生成可视化信息泄露审计报告
java·人工智能·安全·web安全·网络安全·自动化·系统安全
C2H5OH12 小时前
PortSwigger SQL注入LAB3
网络安全
treesforest12 小时前
IP 反欺诈查询怎么落地更稳?Ipdatacloud 适用场景与实战决策闭环
网络·数据库·网络协议·tcp/ip·网络安全
Chasing__Dreams12 小时前
Redis--基础知识点--29--Redis瓶颈
数据库·redis·php
Suckerbin13 小时前
vulnyx-Care靶场渗透
安全·web安全·网络安全