前言

之前在群里有个老兄求助帮忙审计一个自助发卡系统的cms(还是1块钱买来的) 基于tp5开发 我反正没事 于是看了一下o-o 找到了几种getshell的方法 这里就介绍一种,还有一个更神奇的地方,最后发现这位老兄竟然是我的学弟,真的是缘分让我们相遇不是意外.....太神奇了.................让我们一起日了这个站

正文

这个系统的后台上传是有两个步骤首先会调用 admin模块plugin控制器的update方法 通过 post的md5 和 filename 生成一个加密token 这个token会用于后面的检验

对应源码

再来看看第二步 当然就是上传文件拉 下面就是个平常的上传文件包

看看对应的源码

这里

if ($this->request->post('token') !== md5($filename . session_id()))

这一个判断是可以绕过的 因为这里

$filename = join('/', $md5) . ".{$ext}";

而 $md5是可以控制的 ext 也是可以控制的 所以$filename可以控制 而且 post 的token也可以控制 这样当然可以绕过 具体的生成方法就是利用上传文件的第一步 自己可以随意构造post的md5值 并且没有检验针对post的md5参数 这是getshell的背景之一

然后关键点在

$info = $file->move('static' . DS . 'upload' . DS . $md5[0], $md5[1], true))

这个move函数里 跟进这个move函数 在这个move函数里有一个关键的调用

$saveName = $this->buildSaveName($savename);
        $filename = $path . $saveName;

我们来看看这个buildsavename函数

protected function buildSaveName($savename)
    {
        // 自动生成文件名
        if (true === $savename) {
            if ($this->rule instanceof \Closure) {
                $savename = call_user_func_array($this->rule, [$this]);
            } else {
                switch ($this->rule) {
                    case 'date':
                        $savename = date('Ymd') . DS . md5(microtime(true));
                        break;
                    default:
                        if (in_array($this->rule, hash_algos())) {
                            $hash     = $this->hash($this->rule);
                            $savename = substr($hash, 0, 2) . DS . substr($hash, 2);
                        } elseif (is_callable($this->rule)) {
                            $savename = call_user_func($this->rule);
                        } else {
                            $savename = date('Ymd') . DS . md5(microtime(true));
                        }
                }
            }
        } elseif ('' === $savename || false === $savename) {
            $savename = $this->getInfo('name');
        }
        if (!strpos($savename, '.')) {
            $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION);
        }
        return $savename;
    }

兄弟萌 看见没 hh 关键点就在 最后一个if判断上 判断 $savename里是否有. 有的话就会直接 return $savename 那么这个savename是什么呢 看前面的调用发现 这个savename就是 调用move函数的第二个参数 也就是 $md5[1] 这个是咱们可以控制的 而且看move函数后面是将这个作为文件名了的 那么我们将$md5[1]设置成xxxx.php(要长与16位) 是不是已经成了!!! hh

还需要注意一下 上传的时候 png图片前面一部分的格式需要保留 因为有检测 php代码丢后面就好 或者直接用图片马什么的

你别看它返回的是上传失败 其实已经上传成功了 路径就是 xxxxx/static/upload/$md5[0]/$md5[1]

我刚开始百思不得其解为什么会上传失败 一切都这么的流畅.... 最后看了几遍找不出错在哪,不得已自己在本地搭建了环境,然后实验,偶然间,去瞟了一眼上传目录,发现......其实已经上传成功了..... 应该自己去访问一下的 这个地方有点傻了

最终

弄了个phpinfo上去

看了一下disabled function 并不恐怖 而且是php 7 直接用 php7的bug 就能执行命令


最后尝试了一波提权,因为没什么三方应用用来提的比如redis啊啥的,只有硬刚,然后果然的失败了,希望有大佬教教我提linux.
在fofa上搜了一下不是很多,有100多台,不过这个地方是未授权,后端没有检测,不需要登陆,两个包直接入魂,也算不错了,关键是竟然遇到了学弟,hhhhhhhhhh

点击收藏 | 2 关注 | 1
登录 后跟帖