Full Report
FortiGate is an SSL VPN. Recently, they described a vulnerability in their firmware that could lead to RCE. So, the authors of this post diffed the two versions, found the bug and exploited it. First, they obtained the firmware from somewhere (likely online) between the newest and a previous version of the software. Once they had decompiled the code, they looked for changes in different locations. One of them that caught their eye was an HTTP parsing change. In particular, some changes to the amount of chunks that were allowed on transfer-encoding and the size of these chunks. So, with this, they had a potential vulnerability. After some effort with playing with these values, they got a crash. What was the crash about? The value 0x0a0d could be written to an arbitrary offset on the stack. The debugging environment was interesting to me. The standard shell was very restricted and there were various protections in place to prevent changes. After reviewing the /bin/init binary, they found a signature check being performed but assumed more checks were in it. So, they patched the function do_halt() to not exit. For the kernel checks, they modified the kernel build to allow for debugging with GDB. In GDB, they found the check, wrote a script to setup a breakpoint then specified a proper return value. From there, they copied a bunch of binaries to make their life easier. The primitive was only a two byte write to an arbitrary address on the stack with the bytes 0xXXXXX0a0d. With this return addresses, saved base points and locals did not seem like get paths to hit. So, they decided to target a heap address that was on the stack that contained function pointers. The binary didn't have PIE setup. So, they used this static address alongside heap spraying to reference the system function. Eventually, they got this working with a payload to run one of the limited commands in the shell. They eventually came up with a more complicated ROP chain to get a shell though. Overall, an interesting post! Taking a seemingly difficult primitive to code execution is pretty nice!
Analysis Summary
# Vulnerability: FortiGate SSL VPN Out-of-Bounds Write RCE
## CVE Details
- **CVE ID:** CVE-2024-21762
- **CVSS Score:** 9.8 (Critical)
- **CWE:** CWE-787 (Out-of-bounds Write)
## Affected Systems
- **Products:** Fortinet FortiGate Next-Generation Firewalls
- **Versions:**
- FortiOS 7.4 (7.4.0 through 7.4.2)
- FortiOS 7.2 (7.2.0 through 7.2.6)
- FortiOS 7.0 (7.0.0 through 7.0.13)
- FortiOS 6.4 (6.4.0 through 6.4.14)
- FortiOS 6.2 (6.2.0 through 6.2.15)
- FortiOS 6.0 (All versions)
- **Configurations:** Systems with the SSL VPN component enabled.
## Vulnerability Description
The vulnerability is an out-of-bounds write in the HTTP parsing logic of the SSL VPN component, specifically related to **Chunked Transfer Encoding**. During the processing of chunked messages, the `ap_getline` function (within the `init` binary) fails to properly validate lengths when decoding chunk sizes and processing HTTP trailers. This allows an attacker to write the two-byte value `0x0a0d` (a CRLF sequence) to an arbitrary offset on the stack.
## Exploitation
- **Status:** Exploited in the wild; PoC available and documented.
- **Complexity:** High (Requires bypassing kernel checks and pivoting from a restricted shell).
- **Attack Vector:** Network (Pre-authentication).
- **Technical Note:** While the primitive is only a two-byte write (`0x0a0d`), researchers demonstrated that redirecting stack pointers to heap-sprayed memory containing function pointers allows for a full ROP chain execution despite the lack of PIE (Position Independent Executable) in the target binary.
## Impact
- **Confidentiality:** Total (Full system access)
- **Integrity:** Total (Ability to modify system configuration and binaries)
- **Availability:** Total (Ability to crash the service or halt the appliance)
## Remediation
### Patches
Fortinet has released updates to address this flaw. Recommended minimum versions include:
- FortiOS 7.4.3 or higher
- FortiOS 7.2.7 or higher
- FortiOS 7.0.14 or higher
- FortiOS 6.4.15 or higher
- FortiOS 6.2.16 or higher
### Workarounds
- **Disable SSL VPN:** If patching is not immediately possible, disabling the SSL VPN service on the appliance is the most effective mitigation.
## Detection
- **Indicators of Compromise:** Monitor for unexpected Node.js processes or unusual child processes spawning from `/bin/init`.
- **Log Analysis:** Check for crashes in the `sslvpnd` process.
- **Detection Methods:** Use external vulnerability scanners to identify unpatched FortiOS versions on exposed interfaces.
## References
- **Vendor Advisory:** [https://www.fortiguard.com/psirt/FG-IR-24-015](https://www.fortiguard.com/psirt/FG-IR-24-015)
- **Research Post:** [https://www.assetnote.io/resources/research/two-bytes-is-plenty-fortigate-rce-with-cve-2024-21762](https://www.assetnote.io/resources/research/two-bytes-is-plenty-fortigate-rce-with-cve-2024-21762)