一次发卡系统代码审计

admin 2025年2月25日14:45:43评论45 views字数 2062阅读6分52秒阅读模式

前言

之前在群里有个老兄求助帮忙审计一个自助发卡系统的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多台,不过这个地方是未授权,后端没有检测,不需要登陆,两个包直接入魂,也算不错了。

原文始发于微信公众号(zz学安全):一次发卡系统代码审计

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月25日14:45:43
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   一次发卡系统代码审计https://cn-sec.com/archives/1016961.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息