记:一次全新UI众帮悬赏任务系统漏洞分析

xiao1star2025-11-16文章来源:SecHub网络安全社区


记:一次全新UI众帮悬赏任务系统漏洞分析

资产测绘

fofa

"static/home/mobile/css/style.css"

202409051855300.png

文件上传漏洞分析

app\home\controller\Feedback.php有一个umimg方法。用于实现图片上传的操作

202409051927221.png

分析:该方法利用request()->file(upimg)获取到前端传来了的name为upimg的文件信息,之后调用了qiniuupload方法实现对文件的上传操作,接着将文件上传的信息通过json格式打印出来

进入到file方法中,该方法用于提取上传的文件,并根据提供的参数返回文件信息

public function file($name = '') { if (empty($this->file)) {//非空判断 $this->file = isset($_FILES) ? $_FILES : []; } if (is_array($name)) {//是否为数组 return $this->file = array_merge($this->file, $name);//将这个数组与 $this->file 合并,并更新 $this->file } $files = $this->file; if (!empty($files)) { // 处理上传文件 $array = []; foreach ($files as $key => $file) {//遍历filename数组,将其每个值赋值给file,每个元素代表一个上传的文件 if (is_array($file['name'])) {//是数组进入下面语句中 $item = []; $keys = array_keys($file); $count = count($file['name']);//得到上传文件的数目 for ($i = 0; $i < $count; $i++) {//多个文件上传,遍历每一个文件 if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) { //跳过任何临时文件名为空或不指向实际文件的条目 continue; } $temp['key'] = $key;//创建临时数组用于存储当前文件的信息 foreach ($keys as $_key) {//遍历文件的所有属性 $temp[$_key] = $file[$_key][$i]; } $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp);//创建一个新的 File 对象,并设置上传信息 } $array[$key] = $item; } else {//不是数组 if ($file instanceof File) {//判断属于File类的一个实例 $array[$key] = $file;//$file赋值给数组的$key键 } else { if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) { continue;//跳过临时文件名为空或不指向实际文件的条目 } $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file);//创建一个新的 File 对象,并设置上传信息将结果赋值给数组的$key键 } } } if (strpos($name, '.')) { list($name, $sub) = explode('.', $name);//如果name包含了点,进行$name的分割 } if ('' === $name) {//判断参数是否为空 // 获取全部文件 return $array; } //如果只指定了数组键,并且该键存在,返回特定的文件信息 elseif (isset($sub) && isset($array[$name][$sub])) { return $array[$name][$sub]; } elseif (isset($array[$name])) { return $array[$name]; } } return; }

分析:这个方法的设计允许它处理单个文件上传和多文件上传,并且可以根据需要返回整个文件数组或特定的文件信息。

接着进入到qiniuupload方法中,本以为该方法会直接上传到七牛云中,没想到是先进行本地服务器的上传操作

202409052013917.png

分析:这个方法真的很鸡肋

$filePath = $file->getRealPath(); $ext = pathinfo($file->getInfo('name'), PATHINFO_EXTENSION); //后缀 $info = $file->move(ROOT_PATH . 'public' . DS . 'uploads'); if($info){ return '/uploads/'.$info->getSaveName(); }else{ return false; } die;

首先会得到文件的真实路径,之后获取到文件的后缀名,然后调用move方法进行文件上传操作,如果上传成功,那么就返回上传的文件路径,反之返回false。在进行完本地文件的上传之后无论上传是否成功都会return返回内容,也就是说代码根本就不会往下进行七牛云的上传操作。

全程没有对文件上传进行任何过滤,并且将文件上传到七牛云中,而是上传到了本地,真的是无比鸡肋!!!

后台权限绕过分析

首先进入到app/admin/controller/Auth.php中,这里有一个login()方法

202409052049356.png

**分析:**若是AJAX请求登录则先是得到前端请求中post方式传输过来的信息,之后调用getInfoByUsername方法将前端传来的username参数机械能数据库查询赋值给$administrator,之后就是对检查密码是否正确,然后进行将$administrator进行base64编码之后赋值给administrator从而进行cookie的设置。接着清除缓存,验证成功提供跳转到首页的链接。如果请求不是 AJAX 请求,它将删除 Cookie 并渲染当前函数名对应的视图。

在admin后台的php中都继承了Base类,那么才行鉴权函数是在该类中

202409052104269.png

而在Base类中的__construct魔术方法中调用了_checkLogin检验是否登录的方法,

202409052106433.png

查看该_checkLogin方法

202409052106001.png

分析:该方法首先是判断是否存在字段为administrator的Cookie,若存在就将其base64解码并转为json格式赋值给该类的administrator属性,接着检查当前请求的控制器是否不是 Auth 控制器,并且 $this->administrator 数组是否为空或不合法。Auth 控制器可能用于处理认证,因此不需要登录即可访问。那么我们伪造一个COOKIE使其不经过if(!in_array(request()->controller(),['Auth']) && !check_array($this->administrator))的语句中即可

漏洞实战

前台漏洞上传

进去一看,非常垃圾的灰黑网站,直接开干

202409051906145.png

进入它的https://xxx.xxx.xxx.xxx/home/Feedback/upimg路由中,该路由时是对文件上传的操作,我们对其进行抓包处理

上传一个1.php文件,内容是phpinfo(),发现成功得到上传文件的路径

202409052024798.png

访问该路径,成功显示phpinfo()内容

202409052025430.png

后台权限绕过

经过验证我们发现仅需要 id username avatar 这三个字段即可绕过登录 (其实少了avatar也行,但是大部分接⼝就不能用了,会报错)将我们的json数据进行base64编码,得到eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsImF2YXRhciI6IjEucG5nIn0=

202409052115492.png

接着用Hackbar,伪造Cookie发现成功访问了admin/recharge/index的内容

202409052117229.png