⚠ TLP:AMBER — Restricted Distribution — CVE-2026-31431 Copy Fail — Active Exploitation Confirmed
◈ CVE-2026-31431 · CVSS 7.8
COPY FAIL / CVE-2026-31431
Linux Kernel LPE · authencesn AEAD · AF_ALG socket · splice() · Page-Cache Overwrite · 100% Reliable · PoC Public
Active Exploitation — PoC Public Since April 29 2026
732-byte Python script → root on any unpatched Linux (kernel 4.13–6.18). No race condition. 100% reliable. Zero disk writes. Affects every major distro since 2017. Patch now.
CVSS 7.8 HIGH T1068 LPE PoC Public 9-Year Scope Zero Disk Writes AI Detectable
CVE ID
CVE-2026-31431
Vulnerability Type
Linux Kernel LPE
Affected Kernels
4.13 → 6.18+
Exploit Reliability
100% — No Race
PoC Size
732 bytes Python
Disclosed
29 April 2026
Attack Pattern — Kernel Memory Exploitation Chain
CVE-2026-31431 · authencesn AEAD · AF_ALG · splice()
KERNEL MEMORY / PAGE CACHE KERNEL SPACE · CRYPTO SUBSYSTEM USER SPACE /usr/bin/su setuid binary page-cache (read-only) +s ELF Entry Point 4-byte overwrite page-cache → shellcode ptr WRITTEN uid=0 ✓ root shell achieved execve(modified_su) AF_ALG socket socket(AF_ALG=38, SOCK_SEQPACKET) algif_aead module VULN authencesn AEAD template forgets SCATTERLIST_BIT_ MUTABLE flag pipe buffer page-cache pages referenced (not copied) Python PoC 732 bytes · uid>0 copy_fail_exp.py 732 bytes SYSCALL CHAIN ➀ open(O_RDONLY) ➁ splice(fd → pipe) ➂ socket(AF_ALG=38) ➃ splice(pipe → alg) ➄ sendmsg()+recvmsg() ➅ execve(su) → root ① open() ② splice ③ splice ④ sendmsg() ⑤ 4-byte overwrite! ⑥ execve() User Space call splice() chain Vulnerability write path Privilege escalation Vulnerability node Hover nodes for details · No race condition · 100% reliable
🚨 Day Zero — What To Do RIGHT NOW ACTIVE EXPLOITATION
Step 1 · Am I Vulnerable?
Check kernel version and module status. If kernel is between 4.13–6.18 and algif_aead is accessible — you are exposed.
## Quick check: uname -r grep CONFIG_CRYPTO_USER_API_AEAD \ /boot/config-$(uname -r) ## =y means BUILT-IN (high risk) ## =m means MODULE (can blacklist)
Step 2 · Am I Already Exploited?
Check auditd and auth.log for exploitation artifacts. No disk trace — only log-based detection works.
## Check auditd for AF_ALG: ausearch -sc socket -i 2>/dev/null \ | grep 'family=38' ## Check auth.log (Wiz signal): grep -P 'su\[\d+\]:\s+\(to root\)\s+on' \ /var/log/auth.log
Step 3 · Protect Now
Apply mitigation immediately. Then schedule kernel patch within 48 hours for critical systems.
## Debian/Ubuntu: echo 'install algif_aead /bin/false' \ > /etc/modprobe.d/disable-algif.conf ## RHEL-family (modprobe won't work!): grubby --update-kernel=ALL \ --args="initcall_blacklist=algif_aead_init" reboot
↓ After completing these 3 steps, use the IR phases below if exploitation is confirmed ↓
7.8
CVSS Score (HIGH)
100%
Exploit Reliability
9 yrs
Vulnerability Window
732
Bytes to Root
0
Disk Writes (Stealth)
18
Hunt Queries
Vulnerability Profile
What Is Copy Fail
CVE-2026-31431 «Copy Fail» is a logic flaw in the Linux kernel's authencesn AEAD cryptographic template that allows any unprivileged user to overwrite the in-memory content of setuid binaries via a chain of three legitimate syscalls: socket(AF_ALG) + splice() + execve().

The vulnerability exists because the authencesn template fails to clear the SCATTERLIST_BIT_MUTABLE flag when accepting pipe-sourced pages into its AEAD destination scatterlist — allowing page-cache pages marked read-only to be written to. The attacker splices a setuid binary's read-only pages through a pipe into an AF_ALG socket, triggers the AEAD write path, and achieves a controlled 4-byte overwrite of the binary's ELF entry point in page-cache.

The result: any low-privileged user becomes root in a single script execution with 100% reliability, no race condition, and zero forensic artifacts on disk.
Why This Is Different
No Race Condition
Deterministic — first run always succeeds. No timing, no luck, no retries. Any script kiddie with a copy of the PoC can root your server.
Zero Disk Writes
Page-cache modification only. inotify silent. No EDR file-write alert. No audit trail for the payload. Looks like a ghost root process.
Universal Portability
Same 732-byte Python PoC. Same result. Ubuntu 22, RHEL 9, Debian 12, SUSE 15, Alpine, Amazon Linux — all vulnerable until patched.
Exploit Chain — 6 Steps to Root
Step 1
Open SUID Binary
open(/usr/bin/su, O_RDONLY) — read-only FD to setuid binary in page-cache
Step 2
Splice to Pipe
splice(fd, pipe) — page-cache pages referenced in pipe buffer
Step 3
Open AF_ALG Socket
socket(AF_ALG=38, SOCK_SEQPACKET) + authencesn algorithm bind
Step 4
Splice to Socket
splice(pipe, alg_socket) — pages enter AEAD dst scatterlist
Step 5
Trigger Write
sendmsg()+recvmsg() — authencesn writes 4 bytes to page-cache read-only page (ELF entry point)
Step 6
Execute → ROOT
execve(modified_setuid) — kernel loads from page-cache → shellcode runs as uid=0
Affected Environments
K8s nodes, CI/CD runnersCRITICAL
Multi-user SSH serversCRITICAL
Cloud VMs with shell accessHIGH
Container hosts (any runtime)HIGH
Dev laptops (single user)MEDIUM
Patch Information
Kernel Commit
a664bf3d603d
Fix Description
Reverts 2017 zero-copy optimization — pages from pipe now deep-copied instead of referenced in AEAD dst scatterlist
Ubuntu/Debian
apt update && apt install linux-image-generic
RHEL/Amazon Linux
yum update kernel -y
SUSE
zypper update kernel-default -y
Immediate Mitigation (No Reboot)
# Blacklist algif_aead module — blocks exploit Step 3 # Deploy NOW while preparing kernel patch echo 'blacklist algif_aead' | tee \ /etc/modprobe.d/blacklist-copy-fail.conf # Unload if currently loaded modprobe -r algif_aead 2>/dev/null # Verify — must return empty lsmod | grep algif_aead # Ansible fleet-wide deployment: ansible all -m shell -a "echo 'blacklist algif_aead' \ >> /etc/modprobe.d/blacklist-copy-fail.conf \ && modprobe -r algif_aead 2>/dev/null" -b
Phase 1 of 6 — Preparation
Objective
Deploy AF_ALG syscall monitoring, run kernel inventory, push algif_aead blacklist fleet-wide, prepare patching infrastructure. Target: all CRITICAL systems mitigated within 4 hours.
System Inventory (0–4h)
  • Run kernel version inventory across entire Linux fleet: for host in $(cat inventory.txt); do ssh $host 'echo "$HOSTNAME: $(uname -r)"'; done > kernel_versions.txt
  • Identify vulnerable systems (kernels 4.13–6.18): flag all unpatched as CRITICAL — report count to CISO within 2 hours
  • Categorize by risk tier: K8s nodes / CI-CD runners → CRITICAL · Multi-user servers → HIGH · Cloud VMs → HIGH · Developer laptops → MEDIUM
  • K8s clusters: kubectl get nodes -o wide — SSH to each node, run uname -r. Every node = CRITICAL if unpatched
  • Document total vulnerable count by tier for compliance reporting
Immediate Mitigation (0–4h)
  • Deploy algif_aead module blacklist to ALL CRITICAL systems via Ansible (see command in Overview tab)
  • Verify mitigation: ansible all -m shell -a 'lsmod | grep algif_aead; echo CLEAR' -b — any non-empty lsmod result = not mitigated
  • For Kubernetes: apply seccomp profile blocking socket(AF_ALG) to all pod specs via admission webhook or manual annotation
  • Update initramfs to persist blacklist across reboots: update-initramfs -u (Ubuntu/Debian) or dracut --force (RHEL/SUSE)
  • Identify apps using AF_ALG for legitimate crypto (rare) — coordinate with owners before blacklisting on those systems
Monitoring Setup
  • Deploy auditd AF_ALG rule: auditctl -a always,exit -F arch=b64 -S socket -F a0=0x26 -F uid!=0 -k copy_fail_afalg
  • Deploy auditd splice rule: auditctl -a always,exit -F arch=b64 -S splice -F uid!=0 -k copy_fail_splice
  • Deploy auditd LPE rule: auditctl -a always,exit -F arch=b64 -S execve -F uid!=0 -F euid=0 -k copy_fail_lpe
  • Forward auditd logs to SIEM in real-time via audisp-remote or rsyslog — do NOT rely on periodic polling
  • Deploy eBPF real-time monitor: bpftrace -e 'tracepoint:syscalls:sys_enter_socket /args->family==38 && uid>0/ { printf("AF_ALG: pid=%d uid=%d comm=%s\n",pid,uid,comm); }'
  • Configure SIEM alert: uid=0 process with no sudo/su ancestor in last 60s — core LPE detection rule, deploy immediately
Patch Infrastructure
  • Set up lab test environment — clone representative VMs (Ubuntu 22.04, RHEL 9, Debian 12, SUSE 15) and test patch before production rollout
  • Pre-download patched kernel packages to avoid bandwidth issues during rollout: apt-cache show linux-image-generic | grep Version
  • Document Kubernetes rolling update procedure: cordon → drain → patch → reboot → uncordon — one node at a time, not parallel
  • Raise emergency change request in ITSM — priority EMERGENCY, SLA 48h CRITICAL / 7 days HIGH tier systems
  • Verify patch verification command: uname -r shows patched version + lsmod | grep algif_aead returns empty
Phase 2 of 6 — Identification
Objective
Detect active exploitation via AF_ALG syscall monitoring and uid=0 transition analysis. Hunt for Copy Fail IOCs in pre-patch audit logs (from April 22 onward). Preserve forensic evidence before any containment action.
Evidence Preservation — Act First
  • IF ACTIVE COMPROMISE SUSPECTED: capture memory first — insmod lime.ko path=/mnt/mem.lime format=lime before any other action
  • Export auditd logs to external storage immediately: cp -a /var/log/audit/ /secure/evidence/$(hostname)_$(date +%Y%m%d)/
  • Capture current process list: ps auxef > /tmp/ev/ps.txt && ss -tulpna > /tmp/ev/ss.txt && lsmod > /tmp/ev/lsmod.txt
  • Check for active AF_ALG sockets now: cat /proc/*/net/af_alg 2>/dev/null — any entry from non-root uid is critical
Syscall & Kernel Detection
  • Hunt AF_ALG by non-root in auditd: ausearch -k copy_fail_afalg | grep 'uid=[^0]' — any hit = HIGH confidence exploit attempt
  • Hunt splice from Python: ausearch -k copy_fail_splice | grep python — splice from non-root Python + setuid binary FD = exploit chain confirmed
  • Check dmesg for kernel errors: dmesg | grep -iE '(aead|algif|splice.*error)'
  • Verify algif_aead not loaded: lsmod | grep algif — if loaded post-mitigation, investigate immediately (attacker or failed mitigation)
  • Check setuid binary access: find /usr/bin -perm -4000 -newer /var/log/syslog 2>/dev/null
Privilege Escalation Detection
  • Hunt uid=0 without auth path: ausearch -m EXECVE | awk '$0~/uid=0/ && $0!~/(sudo|su|login|sshd|cron)/' — this is the LPE detection signature
  • Check auth logs: grep 'session opened for user root' /var/log/auth.log — cross-reference against sudo/su entries
  • Compare /etc/passwd and /etc/shadow against backup — attacker may add backdoor root account post-exploitation
  • Hunt new SUID binaries: find / -perm -4000 -newer /var/log/boot.log 2>/dev/null
  • Review last logins: last -n 50 | head — root logins at unusual hours = suspect
Process & File Analysis
  • Hunt Python from temp dirs: ausearch -m EXECVE | grep -E '(/tmp|/dev/shm|/run/user).*python' — Copy Fail PoC always runs from temp dir
  • Hunt 732-byte Python scripts: find / -name '*.py' -size 732c -newer /var/log/dpkg.log 2>/dev/null — exact PoC size
  • Container check: kubectl exec -it <pod> -- uname -r — pod kernel = host kernel, confirm host unpatched = all pods exposed
  • Retroactive hunt: search auditd logs from April 22 2026 (7 days pre-disclosure) for copy_fail_afalg key hits — threat actors hunt for 0-days before public disclosure
Phase 3 of 6 — Containment
Objective
Eliminate the exploit path across the entire fleet. Deploy module blacklist, Kubernetes seccomp profiles, and isolate any confirmed compromised hosts before remediation begins.
Critical Warnings
  • Copy Fail modifies page-cache ONLY — rebooting clears the exploit payload but does NOT remove attacker persistence if they planted an SSH key, SUID shell, or cronjob post-root
  • If attacker achieved root: assume full host compromise — credential harvest, metadata API access, Docker socket abuse all possible within seconds of root
  • DO NOT reimage before forensic evidence capture — memory and audit logs first, then decide on remediation path
Module Blacklist — Primary Mitigation
  • Fleet-wide Ansible deployment: ansible all -m shell -a "echo 'blacklist algif_aead' > /etc/modprobe.d/blacklist-copy-fail.conf && modprobe -r algif_aead 2>/dev/null" -b
  • Verify fleet: ansible all -m shell -a 'lsmod | grep algif_aead; echo CLEAR' -b | grep -v CLEAR — any non-empty = not mitigated
  • For module in use: fuser /dev/crypto 2>/dev/null — identify process using it, coordinate with app owner before forced removal
  • Persist blacklist across reboots: update-initramfs -u (Debian/Ubuntu) or dracut --force (RHEL/SUSE)
Kubernetes Containment
  • Apply seccomp profile blocking AF_ALG socket to all pods — deploy via admission webhook or per-pod securityContext annotation
  • Enforce AppArmor/SELinux profile denying socket(family=38) — update profiles and apply to all running pods
  • Audit privileged pods: kubectl get pods --all-namespaces -o json | jq '.items[] | select(.spec.containers[].securityContext.privileged==true) | .metadata'
  • Verify all node kernel versions via debug containers: kubectl debug node/<name> -it --image=busybox -- uname -r
Network Isolation (Confirmed Compromise)
  • IF exploitation confirmed: isolate via EDR quarantine maintaining EDR management channel — do NOT full network cut if EDR needed for forensics
  • Revoke SSH keys and cloud IAM credentials for any account with a session on the compromised host
  • Cloud instances: take snapshot before shutdown for forensics, then stop instance (AWS: aws ec2 stop-instances)
  • Assess breach notification obligations — if attacker accessed regulated data (PII, PCI, health) post-root: GDPR 72h clock may be running, notify DPO immediately
Phase 4 of 6 — Remediation
Objective
Deploy kernel patches across entire Linux fleet by distro. Execute Kubernetes rolling update (zero downtime). Verify 100% patch coverage before removing temporary mitigations.
Ubuntu / Debian
# Install patched kernel apt update && apt install -y linux-image-generic # Schedule reboot (maintenance window) shutdown -r +1 'CVE-2026-31431 kernel patch' # Post-reboot verify uname -r # confirm patched version lsmod | grep algif_aead # must be empty systemctl --failed # no failed services
RHEL / CentOS / Amazon Linux
# RHEL 8/9, Rocky, AlmaLinux, Oracle Linux yum update kernel -y # Amazon Linux 2 yum update kernel -y && reboot # Amazon Linux 2023 dnf update kernel -y && reboot # Verify changelog references fix rpm -q --changelog kernel | \ grep 'CVE-2026-31431'
Kubernetes Rolling Update (Zero Downtime)
# Repeat for each node — NOT parallel kubectl cordon <node-name> kubectl drain <node-name> \ --ignore-daemonsets \ --delete-emptydir-data \ --grace-period=300 # Patch kernel on node ssh <node> 'apt update && apt install -y \ linux-image-generic && shutdown -r now' # Wait for node ready kubectl wait --for=condition=Ready \ node/<node-name> --timeout=600s # Verify and uncordon kubectl debug node/<node-name> \ -it --image=busybox -- uname -r kubectl uncordon <node-name>
Fleet Verification
  • Fleet kernel check: ansible all -m shell -a 'uname -r' -b — all outputs must show patched version
  • Fleet module check: ansible all -m shell -a 'lsmod | grep algif_aead; echo CLEAR' -b | grep -v CLEAR — any hit = module still loaded
  • Run PoC in isolated lab on patched system — should exit with ENODEV or module not found error, document result
  • Remove temporary blacklist files after patch confirmed: ansible all -m file -a 'path=/etc/modprobe.d/blacklist-copy-fail.conf state=absent' -b
  • Update CMDB/asset inventory with patched kernel versions and patch completion timestamp
Phase 5 of 6 — Recovery
Objective
Verify 100% patch coverage, forensically analyze the pre-patch audit window for signs of exploitation, restore service confidence, and activate enhanced post-patch monitoring for 30 days.
Pre-Recovery Validation
  • CISO sign-off: confirm 100% of CRITICAL/HIGH tier systems show patched kernel version before closing IR
  • Patch coverage report: vulnerable system count at T=0 vs patched at T=now — document for compliance
  • Re-enable services temporarily disabled during patching — verify clean restart: systemctl status <service>
  • Kubernetes cluster health: kubectl get pods --all-namespaces | grep -v Running — investigate any non-running pods
Forensic Analysis — Pre-Patch Window
  • Search pre-patch audit logs for AF_ALG activity from April 22: ausearch -k copy_fail_afalg --start 04/22/2026 | grep 'uid=[^0]'
  • Hunt splice from Python pre-patch: ausearch -k copy_fail_splice --start 04/22/2026 | grep python
  • Root login review: last | grep root | awk '$3!~/tty|pts/' — unexpected root sessions in the window
  • New SUID binaries: find /usr/bin /usr/sbin -perm -4000 -newer /etc/shadow — attacker post-root may add SUID persistence
  • SSH authorized_keys audit: check /root/.ssh/authorized_keys and all user ~/.ssh/ for unauthorized entries
  • Cron persistence check: inspect /var/spool/cron/crontabs/root and /etc/cron.d/ modification times vs incident window
Post-Recovery Monitoring (30 days)
  • Keep AF_ALG auditd rules active for 30 days — monitor for retry attempts from persistent attackers or script kiddies
  • Keep uid=0 transition alert active — any hit post-patch could indicate different LPE or previously planted backdoor activating
  • SIEM alert: Python execution from /tmp, /dev/shm, /run/user by non-root — keep active permanently (low FP in production)
  • Weekly setuid binary integrity check: sha256sum /usr/bin/su /usr/bin/passwd /usr/bin/sudo — diff against baseline for 4 weeks
Service Validation
  • Test crypto operations (dm-crypt/LUKS are NOT affected by algif_aead blacklist): cryptsetup status <volume>
  • TLS functionality test: openssl s_client -connect google.com:443 2>/dev/null | grep 'Verify return'
  • Container workload health: kubectl get pods --all-namespaces | awk '$4!="Running" && $4!="Completed"'
  • Application smoke tests on patched systems — verify all critical services function normally after kernel update
Phase 6 of 6 — Lessons Learned
Objective
Improve kernel patching velocity, strengthen syscall monitoring permanently, update detection rules and policy SLAs, share intelligence with the security community.
Process Improvements
  • If patch took >72h to fully deploy to CRITICAL systems: mandatory post-mortem on patching pipeline — target SLA must be revised
  • Implement automated kernel version monitoring (Wazuh, Lynis, AWS Inspector) — continuous compliance vs known-vulnerable kernel list
  • Establish kernel patch SLA policy: kernel LPE with public PoC = 48h CRITICAL tier, 7 days HIGH tier — document in vulnerability management policy
  • Implement mandatory Kubernetes default seccomp profiles: restricts AF_ALG and many other dangerous syscalls without custom policy
  • Add kernel hardening sysctl: sysctl kernel.unprivileged_af_alg=0 (if available in your kernel) — directly disables unprivileged AF_ALG
Detection Improvements
  • Promote AF_ALG socket detection to PERMANENT SIEM rule — not just during Copy Fail response. AF_ALG by non-root is always suspicious
  • Tune uid=0 transition rule: review false positive rate post-incident, adjust sudo/su/PAM exclusions — target: <1 FP per day per 1000 systems
  • Deploy Python-from-temp-dir rule permanently — low FP in production, high signal for LPE attempts
  • Schedule 30-day purple team exercise: test AF_ALG detection, LPE detection chain, post-exploit persistence detection — validate what SIEM actually catches vs what we think it catches
Community & Sharing
  • Contribute Sigma rules to SigmaHQ GitHub — share Copy Fail detection rules with community
  • Share IOCs with sector ISAC, national CERT, GCC-CERT if applicable
  • Brief executive leadership: 9-year scope, 100% reliability, zero-disk-write stealth — justifies investment in continuous kernel monitoring and faster patch pipeline
  • Publish internal post-incident report within 2 weeks: timeline, gaps identified, improvements made, metrics (MTTD, MTTR)
Metrics to Track
MTTD (Mean Time to Detect)Target: <1h
MTTM (Mean Time to Mitigate)Target: <4h
MTTP (Mean Time to Patch)Target: <48h CRIT
Patch Coverage @ 24hTarget: 100% CRIT
False Positive Rate (LPE rule)Target: <1/day/1K hosts
Intel Feed — CVE-2026-31431
Live threat intelligence, SOC detection methodology, patch status, and community findings. Updated continuously as new information emerges from vendors, researchers, and SOC teams worldwide. Last updated: 2 May 2026.
LAST UPDATED: 2026-05-02 · SOURCES: 12 · CLASSIFICATION: TLP:AMBER
🛡️ SOC Detection Methodology — VAPT vs SOC Perspective
VAPT tells you "this system is vulnerable" — kernel version check, module present. SOC must answer "has someone already exploited this?" — that answer lives in logs, process trees, and behavioral anomalies. Below is the complete SOC analyst workflow for detecting Copy Fail exploitation through log analysis.
SOC GUIDE Step-by-Step: How SOC Detects Copy Fail Exploitation from Logs Detection Playbook
STEP 1 Check auditd — AF_ALG Socket Creation (Primary Signal) HIGHEST CONFIDENCE

What you're looking for: Any non-root user creating an AF_ALG socket (family=38). This syscall has near-zero legitimate usage in production. If you see it — someone is attempting the exploit.

Log source: /var/log/audit/audit.log · Required: auditd running with Copy Fail rules deployed

# Search auditd for AF_ALG socket by non-root (last 7 days) ausearch -k copy_fail_afalg --start recent | grep 'uid=[^0]' # If auditd rules NOT yet deployed — search raw audit log: grep 'syscall=41.*a0=26' /var/log/audit/audit.log | grep -v 'uid=0' # Quick check — any AF_ALG socket created ever? ausearch -sc socket -i 2>/dev/null | grep -i 'family=38\|a0=26'
ANY HIT = P1 ALERT. Escalate immediately. Non-root AF_ALG socket creation has no legitimate use in 99.9% of environments.
STEP 2 Check auth.log — "Phantom Root" su Entry (Post-Exploitation) HIGH CONFIDENCE

What you're looking for: su log entries where the invoking username is MISSING. Normal su always logs who called it. Copy Fail corrupts the binary so PAM can't identify the caller — producing a "phantom" root entry. (Discovered by Wiz, 1 May 2026)

Log source: /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL)

✓ Normal su entry
su[1765]: (to root) alice on pts/1
⚠ Copy Fail exploitation
su[1781]: (to root) on pts/1
# Hunt for su entries with missing username grep -P 'su\[\d+\]:\s+\(to root\)\s+on\s+pts' /var/log/auth.log grep -P 'su\[\d+\]:\s+\(to root\)\s+on\s+pts' /var/log/secure # Compare: normal su entries always have a username before "on pts" grep 'su\[.*\]: (to root)' /var/log/auth.log | awk '{print}' # Splunk query index=linux_secure sourcetype=linux_secure "su" "(to root)" "on pts" | regex _raw="su\[\d+\]:\s+\(to root\)\s+on\s+pts"
STEP 3 Check auditd — UID=0 Transition Without sudo/su Ancestor HIGH CONFIDENCE

What you're looking for: Any execve() where uid≠0 but euid=0 (effective UID becomes root) — without a legitimate auth parent process (sudo, su, login, sshd, pam, polkit). This is the definitive "someone got root without authorization" signal. Works for any kernel LPE, not just Copy Fail.

Log source: /var/log/audit/audit.log · Key field: auid (audit login UID — tracks original user through privilege changes)

# Hunt: execve with uid!=0 but euid=0, excluding legitimate auth ausearch -m EXECVE -i 2>/dev/null | \ awk '/uid=/{if($0~/uid=0/) next; if($0~/euid=0/ && $0!~/(sudo|su|login|sshd|cron|pam|polkit)/) print}' # Alternative: search for copy_fail_lpe key if rules deployed ausearch -k copy_fail_lpe --start recent # Check auid field — this is the ORIGINAL login user # Even if they became root, auid stays as their real identity ausearch -m SYSCALL -sv yes 2>/dev/null | grep 'euid=0' | grep -v 'auid=0'
KEY INSIGHT: The auid (audit UID) field is immutable — it records who originally logged in. If auid=1001 but euid=0 with no sudo in the process tree, that user escalated privileges through an exploit.
STEP 4 Check Process Trees — Python from Temp Directories MEDIUM-HIGH

What you're looking for: Python3 scripts executed from /tmp, /dev/shm, /run/user, or /var/tmp by non-root users. The Copy Fail PoC is a 732-byte Python script that always runs from temp directories. In production, Python from temp dirs is almost always suspicious.

# Hunt: Python execution from temp directories ausearch -m EXECVE -i 2>/dev/null | \ grep -E 'python.*(/tmp|/dev/shm|/run/user|/var/tmp)' # Hunt: Find the exact PoC file (732 bytes) find /tmp /dev/shm /run/user /var/tmp -name '*.py' -size 732c 2>/dev/null # Hunt: Any Python scripts in temp dirs (broader search) find /tmp /dev/shm /var/tmp -name '*.py' -mtime -7 -ls 2>/dev/null # Check process history: Python with child shell running as root ps auxef | grep -A5 python | grep -E '(root|uid=0)'
STEP 5 Check Kernel Module — Is algif_aead Still Loaded? TRIAGE

What you're checking: Whether the vulnerable module is still active (exploit path open) AND whether your mitigation is actually working. On RHEL-family distros, the module is built-in — lsmod won't show it even though it's active.

# Check if algif_aead is loaded as a module lsmod | grep algif_aead # IMPORTANT: On RHEL-family, module may be BUILT-IN (not in lsmod) # Check kernel config to know if it's built-in: grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r) # If result = "=y" → BUILT-IN (modprobe blacklist will NOT work!) # If result = "=m" → LOADABLE MODULE (modprobe blacklist works) # Check if AF_ALG socket interface is accessible python3 -c "import socket; s=socket.socket(38,5); print('VULNERABLE: AF_ALG accessible')" 2>/dev/null || echo "MITIGATED" # On RHEL: check if grubby blacklist is applied cat /proc/cmdline | grep initcall_blacklist
STEP 6 Check Post-Exploitation — Persistence Artifacts POST-ROOT

What you're looking for: If exploitation succeeded, the attacker had root. They will have planted persistence within seconds. Check for new SSH keys, new SUID binaries, modified passwd/shadow, new cron entries, and new systemd services. The page-cache exploit is cleared by reboot — but persistence survives.

# 1. New SSH authorized_keys for root stat /root/.ssh/authorized_keys 2>/dev/null cat /root/.ssh/authorized_keys 2>/dev/null # check for unknown keys # 2. New SUID binaries created post-disclosure (Apr 29) find / -perm -4000 -newer /var/log/dpkg.log -ls 2>/dev/null find /tmp /dev/shm /usr/local/bin -perm -4000 -ls 2>/dev/null # 3. /etc/passwd or /etc/shadow modified unexpectedly stat /etc/passwd /etc/shadow # check Modify timestamp diff /etc/passwd /etc/passwd- # compare with backup # 4. New cron jobs for root crontab -l -u root 2>/dev/null ls -la /etc/cron.d/ /var/spool/cron/crontabs/ 2>/dev/null # 5. New systemd services find /etc/systemd/system/ -mtime -7 -name '*.service' -ls 2>/dev/null systemctl list-units --state=failed
STEP 7 eBPF Real-Time Monitor — Deploy on Suspected Systems REAL-TIME

When to use: If you suspect a system is under active attack but haven't found log evidence yet. Deploy this bpftrace one-liner for real-time alerting — it watches for AF_ALG socket creation by non-root and immediately prints attacker details.

# One-liner: real-time AF_ALG monitoring (run as root) bpftrace -e 'tracepoint:syscalls:sys_enter_socket /args->family==38 && uid>0/ { printf("⚠ COPY_FAIL: pid=%d uid=%d comm=%s\n",pid,uid,comm); }'
CHEAT SHEET SOC Analyst — Copy Fail Quick Reference
VAPT Says "Vulnerable" — What Do They Check?
• Kernel version between 4.13 and 6.18
algif_aead module loaded or built-in
AF_ALG socket family accessible
• No mitigation applied (blacklist/grubby)
• Patched kernel NOT installed
→ "System CAN be exploited"
SOC Says "Exploited" — What Do They Check?
• auditd: AF_ALG socket by non-root (a0=26)
• auditd: splice() by Python PID (syscall=275)
• auth.log: su entry with missing username
• auditd: uid≠0 → euid=0 without sudo ancestor
• Filesystem: new SSH keys, SUID bins, cron jobs
→ "System WAS exploited"
Log Source #1
/var/log/audit/audit.log
Log Source #2
/var/log/auth.log
Log Source #3
/var/log/secure (RHEL)
Log Source #4
dmesg / kernel ring buffer
IMPORTANT: If auditd was NOT running during the exploitation window (April 29 onwards), you have no syscall-level evidence. Fall back to auth.log analysis (Step 2), filesystem artifact checks (Step 6), and SIEM behavioral anomalies. Deploy auditd rules NOW to catch future attempts. Zero disk writes means traditional file integrity monitoring (AIDE, OSSEC, Tripwire) will not detect the initial exploit — only post-exploitation persistence.
⚠ BREAKING Module Blacklist DOES NOT WORK on RHEL-Family Distributions CloudLinux · 1 May 2026

CRITICAL UPDATE: CloudLinux discovered that the widely recommended modprobe blacklist workaround does NOT work on CloudLinux, AlmaLinux, Rocky Linux, or any RHEL-family distribution. The algif_aead module is compiled directly into the kernel (CONFIG_CRYPTO_USER_API_AEAD=y), not as a loadable module. The blacklist commands execute without errors but leave the system completely unprotected — creating a false sense of security.

IMPACT ON YOUR IR PLAYBOOK

Phase 1 (Preparation) and Phase 3 (Containment) mitigation steps referencing modprobe -r algif_aead and blacklist algif_aead are ineffective on RHEL/CentOS/AlmaLinux/Rocky/CloudLinux/Oracle Linux. Replace with the grubby-based kernel command line approach below.

Correct mitigation for RHEL-family (requires reboot):

# RHEL-family: algif_aead is built-in, NOT a loadable module # modprobe blacklist has NO EFFECT — use grubby instead grubby --update-kernel=ALL \ --args="initcall_blacklist=algif_aead_init" reboot # Verify after reboot: cat /proc/cmdline | grep initcall_blacklist # Must show: initcall_blacklist=algif_aead_init
ACTIVE EXPLOITATION Exploitation Attempts Observed in the Wild Multiple Sources · 1–2 May 2026

CloudLinux Imunify360 is actively detecting published IOCs for CVE-2026-31431 and using extended heuristics to identify and mitigate currently observed exploitation attempts. This confirms the vulnerability is being actively exploited in the wild — not just theoretical.

RedPacket Security's SSVC assessment has classified this as "active exploitation" — rated as an urgent, priority remediation item for all affected Linux kernel systems.

THREAT LEVEL ASSESSMENT
Exploitation Status: ACTIVE IN WILD
SSVC Decision: ACT IMMEDIATELY
Target Environments: Multi-tenant, CI/CD, hosting
PoC Availability: PUBLIC since 29 April
NEW DETECTION Wiz Discovers auth.log Post-Exploitation Detection Signal Wiz · 1 May 2026

Wiz security researchers published a detailed analysis identifying a new post-exploitation detection signal in /var/log/auth.log. When Copy Fail corrupts the /usr/bin/su binary in page-cache and the attacker executes it, the su PAM log entry is missing the invoking username — a field that is always present in legitimate su usage.

Normal su entry:

2026-05-01T09:11:16 su[1765]: (to root) alice on pts/1 ^^^^^ username present

Copy Fail exploitation su entry:

2026-05-01T09:14:19 su[1781]: (to root) on pts/1 ^ username MISSING

Hunt query for this signal:

# Search auth.log for su entries with missing username grep 'su\[.*\]: (to root) on' /var/log/auth.log # Splunk query index=linux_secure sourcetype=linux_secure | search "su" "to root" "on pts" NOT "alice" NOT "bob" | regex _raw="su\[\d+\]:\s+\(to root\)\s+on\s+pts"
ACTION REQUIRED

Add this as a new IOC to your detection rules. The missing-username su log entry is a high-confidence post-exploitation signal with very low false positive rate. Add to Phase 2 (Identification) and IOC table.

PATCHES Global Patch Rollout Status — Distro-by-Distro Multiple Sources · 1–2 May 2026
UbuntuPatched kernels available
✓ PATCHED
AlmaLinuxProduction repos — dnf clean metadata && dnf upgrade
✓ PATCHED
CloudLinuxKernel update + KernelCare livepatch (no reboot)
✓ PATCHED
DebianTracked in Debian Security Tracker
✓ TRACKED
Red Hat / RHELOfficial errata NOT yet released — AlmaLinux patched ahead of Red Hat
⏳ PENDING
Amazon LinuxTracked via ALAS — check yum update kernel
TRACKING
Mainline KernelCommit a664bf3d603d merged in 7.0-rc7
✓ FIXED
CONFIRMED Kubernetes Container Escape — Page Cache Shared Across Boundaries Wiz / Xint / Orca · 30 Apr–1 May 2026

Multiple vendors confirmed that because the Linux page cache is shared across all processes on a host — including across container boundaries — CVE-2026-31431 functions as a container escape primitive. A compromised container can corrupt setuid binaries visible to other containers and the host kernel, escalating from container-level access to full host root.

CONTAINER RISK MATRIX
Kubernetes pods without seccomp → HOST ROOT
Docker containers → HOST ESCAPE
CI/CD runners (GitHub Actions, GitLab) → CRITICAL
Malicious PR + build runner → SUPPLY CHAIN
CONFIRMED Real-World Impact — WSL2, Broker Market, Independent Verification Multiple Sources · 29 Apr–2 May 2026
Microsoft WSL2 Affected
WSL2 (kernel 6.6.87.2-microsoft-standard-WSL2) confirmed vulnerable. Issue #40365 filed on GitHub. Any Windows developer running WSL2 is exposed.
Broker Market Valuation — $500K–$7M
Bugcrowd: "Zerodium's public price list paid up to $500K for a high-end Linux zero-day. Today's gray-market acquirers like Crowdfense run programs in the $10K–$7M range." An AI tool found this in about one hour. Source
Independent Verification — Solar Designer
Alexander Peslyak (Solar Designer), founder of the Openwall Project, independently confirmed the exploit works on Rocky Linux 9.7. oss-security
AI-Discovered Vulnerability
Discovered by Taeyang Lee (Theori). Xint Code AI tool found it in ~1 hour scanning Linux crypto subsystem. Reported 23 March, patch committed 1 April, CVE assigned 22 April, disclosed 29 April 2026. Xint Research

Additional confirmation: Alexander Peslyak (Solar Designer), founder of the Openwall Project, independently verified the exploit works on Rocky Linux 9.7.

INSTITUTIONAL Carnegie Mellon University — Prioritizing Systems Without EDR CMU SCS · 30 Apr 2026

Carnegie Mellon University's SCS Computing Facilities published an advisory confirming they are actively mitigating CVE-2026-31431 across their infrastructure. Key insight from their response: systems without CrowdStrike are being prioritized due to reduced visibility into potential exploitation. Systems with CrowdStrike have additional detection capabilities but remain vulnerable and still require patching. Their HPC environments are also being mitigated.

TAKEAWAY FOR YOUR ORG

Prioritize patching systems without EDR/XDR agents first — they have zero detection capability for this exploit. Systems with EDR (CrowdStrike, SentinelOne, MDE) have behavioral detection that may catch post-exploitation, but are still vulnerable to the initial LPE.

COVERAGE Global Media & Vendor Coverage — 12+ Sources in 48 Hours Multiple · 29 Apr–2 May 2026

CVE-2026-31431 has received extensive global coverage across security media, vendor blogs, and institutional advisories:

↗ The Hacker News ↗ The Register ↗ Help Net Security ↗ Heise (Germany) ↗ CybersecurityNews ↗ Cyber Kendra ↗ Wiz Blog ↗ Orca Security ↗ ToolsLib Blog ↗ Sesame Disk ↗ NVD / NIST ↗ copy.fail (Official)
TIMELINE Coordinated Disclosure & Patch Timeline Consolidated · 2 May 2026
23 Mar 2026
Reported to Linux kernel security team by Theori/Xint
01 Apr 2026
Patch committed to mainline kernel — commit a664bf3d603d (reverts 2017 in-place optimization)
22 Apr 2026
CVE assigned — CVE-2026-31431, CVSS 7.8 HIGH
29 Apr 2026
Public disclosure — PoC published, oss-security mailing list, copy.fail website live
30 Apr 2026
Global coverage — The Register, Hacker News, Help Net Security, Heise, Wiz, Orca publish analyses
30 Apr 2026
CloudLinux discovers modprobe blacklist ineffective on RHEL-family — issues corrected advisory
01 May 2026
AlmaLinux ships patches to production repos ahead of Red Hat errata · Ubuntu patches available
01 May 2026
KernelCare livepatches validated and rolling out (no-reboot fix for subscribed systems)
01 May 2026
Active exploitation confirmed — Imunify360 detecting IOCs, SSVC rates "active exploitation"
02 May 2026
TODAY — Red Hat errata still pending · Wiz publishes auth.log detection signal · CMU prioritizing non-EDR systems
Pending
Awaiting — Red Hat official errata, SUSE advisory, Amazon Linux ALAS update, Sigma rules on SigmaHQ
OPEN SOURCE Community Detection Toolkits — Shared by Security Researchers Globally GitHub · 29 Apr–2 May 2026

Within 72 hours of disclosure, the global security community published production-ready detection toolkits across every major platform. Here is every public resource shared by researchers — no exploit code, purely defensive.

GitHub — Open Source Detection Repos
thrandomv/cve-2026-31431-detection
Sigma Falco auditd KQL EQL
Production-ready Sigma rules (including behavioral chain rule), auditd configs, Falco container rules, KQL/EQL hunt queries, and analyst triage playbook. Mapped to MITRE ATT&CK T1068/T1611. Purely defensive — no exploit code.
↗ github.com/thrandomv/cve-2026-31431-detection
kadir/copy-fail-CVE-2026-31431-IOC
auditd eBPF Sigma YARA PageCache
Layered detection with eBPF as highest-fidelity detector — correlates AF_ALG + authencesn bind + splice into chain alerts. Includes safe vulnerability checker (is_vulnerable.py), page-cache vs disk comparison for post-exploitation, and YARA for PoC file scanning.
↗ github.com/kadir/copy-fail-CVE-2026-31431-IOC
insomnisec/Detections-CVE-2026-31431
auditd Wazuh YARA
auditd rules with Wazuh XML correlation — bridges auditd events into Wazuh SIEM with level 10/14 alerts. YARA rule scans Python scripts on disk for PoC patterns. Includes safe vulnerability test and detailed notes on what auditd cannot detect (page-cache writes are invisible to file watches).
↗ github.com/insomnisec/Detections-CVE-2026-31431
Neo23x0/signature-base (Florian Roth)
YARA
YARA rule by Florian Roth — detects forensic artifacts including known ELF shell payloads, Python exploit code fragments, AF_ALG/authencesn/splice patterns, and public PoC URLs. The gold standard YARA signature for file-level detection.
↗ Neo23x0/signature-base — YARA Rule
Vendor & Enterprise Tool Coverage
Tenable
Vulnerability Watch classification. Scanner plugins released for Nessus/Tenable.io. FAQ by Research Special Operations team.
↗ Tenable FAQ & Plugins
Wiz
auth.log detection signal. Container escape analysis. Pre-built queries for Wiz Threat Intel Center. Cloud workload prioritization.
↗ Wiz Detection Blog
Orca Security
Page-cache shared across containers confirmed. Kernel 6.12–6.18 tested. Cloud workload impact assessment.
↗ Orca Analysis
SentinelOne
Tracked in vulnerability database. Behavioral AI detection for Linux endpoint syscall anomalies.
↗ SentinelOne CVE Entry
Ciphers Security
Falco rule with exclusion list. Patch verification checklist. K8s exposure assessment guide.
↗ Detection & Verification
Sysdig
Runtime detection for containers. Falco-based alerting for AF_ALG socket in containerized workloads.
↗ Sysdig Blog
Detection Coverage Matrix — Community + Vendor
Tool / Platform Available What It Detects Source
Sigma RulesAF_ALG socket + behavioral chain + LPEthrandomv, kadir, insomnisec
Falco (Containers)Container AF_ALG socket with K8s contextthrandomv, cipherssecurity
auditd Rulessocket(AF_ALG) + splice() + execve LPEAll 3 repos
Wazuh SIEMXML correlation rules (Level 10/14 alerts)insomnisec
YARA RulesPoC file artifacts, ELF payloads, code patternsNeo23x0, insomnisec, kadir
eBPF / bpftraceReal-time chain correlation (highest fidelity)kadir
Page-Cache DiffPost-exploitation: memory vs disk comparisonkadir
Tenable / NessusVulnerability scanner plugins (VAPT)Tenable
KQL (Sentinel)AF_ALG + LPE + metadata API queriesthrandomv + this playbook
EQL (Elastic)Sequence: SUID open → pipe2 → splicethrandomv + this playbook
Copy Fail IOCs
All indicators are specific to CVE-2026-31431. Syscall IOCs are primary detection signals — each one alone justifies an alert. Behavioral IOCs require UEBA/AI baseline for best fidelity.
References: ↗ copy.fail — Official Disclosure ↗ Xint — Full Research & PoC ↗ NVD — CVE-2026-31431 ↗ oss-security Mailing List ↗ Wiz — Detection Signals
Syscall Indicators — Primary Exploitation Signals
TypeIndicatorDescriptionConfidenceAction
Syscallsocket(AF_ALG=38, SOCK_SEQPACKET) by uid>0AF_ALG socket creation by non-root. Step 1 of exploit chain. Near-zero legitimate non-root AF_ALG usage in production.HIGHAlert / Hunt
Syscallsplice(setuid_binary_fd → pipe → alg_socket) by uid>0splice() chaining a setuid binary through pipe into AF_ALG socket. The exact exploit mechanism. auditd key: copy_fail_spliceHIGHAlert / Isolate
Syscallexecve() where uid!=0 but euid=0, no sudo/su ancestorSuccessful LPE — root process appeared without legitimate auth path. Hallmark of kernel LPE post-exploitation.HIGHAlert / Forensics
Syscallopen(O_RDONLY, /usr/bin/su|/usr/bin/passwd) → splice() same PID within 5sSetuid binary read immediately followed by splice() from same PID — exploit setup sequence.HIGHAlert / Hunt
Process Indicators
TypeIndicatorDescriptionConfidenceAction
Processpython3 executing from /tmp/, /dev/shm/, /run/user/Copy Fail PoC always runs from temp directories. Python interpreter + temp script path = high confidence.HIGHAlert / Block
ProcessPython script exactly 732 bytes in sizeKnown PoC file size. Minor variants may differ slightly. Hunt: find / -name '*.py' -size 732c 2>/dev/nullMEDIUMHunt / Alert
Processalgif_aead in lsmod after mitigation was deployedModule reappearing post-blacklist = attacker with root removed blacklist, or mitigation failed. Requires root to re-enable.HIGHAlert / Investigate
Processbash/sh/zsh with ppid=python3 and uid=0Post-exploitation root shell spawned from Python parent. Check: ps auxef | grep 'uid=0' with Python as parent process.HIGHAlert / Isolate
Filesystem Indicators (Post-Exploitation)
TypeIndicatorDescriptionConfidenceAction
FileNew SUID binary in /usr/bin or /usr/local/bin after T=0Attacker achieving root may add SUID shell: cp /bin/bash /tmp/.bash && chmod +s /tmp/.bash. Hunt: find / -perm -4000 -newer /var/log/dpkg.logHIGHHunt / Remove
FileNew entry in /root/.ssh/authorized_keysRoot SSH key implant for persistent backdoor access. Check mtime vs incident timeline.HIGHHunt / Remove
File/etc/passwd or /etc/shadow modified without expected system updateAttacker adding backdoor root account. auditctl -w /etc/passwd -p wa detects this.HIGHAlert / Investigate
FileNew cron entry for root with unusual timing or commandCron persistence post-root. Check /var/spool/cron/crontabs/root and /etc/cron.d/ modification timestamps.HIGHHunt / Remove
Behavioral Indicators (High AI/ML Detection Value)
TypeIndicatorDescriptionConfidenceAction
UEBAFirst-ever AF_ALG socket on this host in 90-day baselineUser/host has NEVER created AF_ALG socket in history — first occurrence is immediate high-confidence alert. AI UEBA detects this before root is achieved.HIGHAI Alert
UEBAuid=0 process with no sudo/su ancestor, first time for this userUser has never had a root process without sudo/su in baseline. Sudden phantom root = LPE. UEBA flags the behavioral anomaly.HIGHAI Alert / Isolate
NetworkHTTP GET to 169.254.169.254 (AWS/GCP/Azure metadata) within 60s of uid=0 transitionPost-LPE cloud credential theft. First-time metadata API access from this process context. AWS GuardDuty ML detects automatically.HIGHAI Alert / Block
MITRE ATT&CK v14
Primary technique: T1068 Exploitation for Privilege Escalation. All others are pre-condition or post-exploitation techniques observed in Copy Fail attack scenarios.
TacticTechnique IDNameCopy Fail ContextDetection Signal
Privilege Escalation T1068 Exploitation for Privilege Escalation ★ PRIMARY authencesn AEAD logic flaw → splice chain → 4-byte page-cache overwrite → root. The complete exploit is this single technique. auditd: socket(AF_ALG)+splice+execve sequence; uid=0 transition without sudo
Privilege EscalationT1548.001Setuid and SetgidExploit targets SUID binaries (/usr/bin/su, /usr/bin/passwd) as the overwrite target — standard setuid execution becomes root vectorMonitor read access to setuid binaries by non-root processes
ExecutionT1059.006Python732-byte Python PoC executes the full exploit chain. Python used for AF_ALG socket creation, splice orchestration, and shellcode setupausearch -m EXECVE | grep python | grep -v '/usr/bin/python3 /usr'
Defense EvasionT1027Obfuscated Files/InfoPage-cache modification leaves ZERO disk artifacts — IDS/EDR file-write alerts completely silent. inotify does not trigger on page-cache-only writeseBPF probe on page-cache dirty marking; behavioral anomaly detection only
Defense EvasionT1562.001Disable or Modify ToolsAttacker with root may remove /etc/modprobe.d/blacklist-copy-fail.conf to restore AF_ALG access for re-exploitation or leaving for othersauditctl -w /etc/modprobe.d/ -p wa; alert on deletion of blacklist file
PersistenceT1098.004SSH Authorized KeysPost-root: adding SSH key to /root/.ssh/authorized_keys for persistent no-password root access — most common first post-exploit actionauditctl -w /root/.ssh/ -p wa -k ssh_key_add
PersistenceT1543.003Systemd ServicePost-root: attacker may install systemd service for persistent code execution on bootAlert on new .service files in /etc/systemd/system/; systemctl list-units --state=failed
Credential AccessT1552.001Credentials in FilesPost-root: reading /etc/shadow for all password hashes, app config files with cleartext passwords, private keysImpossible to prevent post-root; detect via /etc/shadow access by unexpected process (auditd watch)
ImpactT1611Escape to HostIn container environments: exploit runs inside container against host kernel → root on host → escape to host filesystem and process namespaceContainer runtime security (Falco); seccomp block on AF_ALG socket; K8s admission policies
TTP-Based Use Cases
8 structured detection use cases built from hypothesis → data sources → detection logic → TP/FP criteria → triage steps → response. Each maps to a specific MITRE ATT&CK technique and stage of the Copy Fail kill chain.
UC-CF-001 AF_ALG Socket Creation by Non-Root Process
Exploitation · Step 1 of 6 CRITICAL T1068
Hypothesis
If a threat actor attempts CVE-2026-31431 exploitation, they must create an AF_ALG socket (socket family 38) as an unprivileged user. This is the first and most specific syscall in the exploit chain — near-zero benign non-root AF_ALG use exists in production Linux environments.
Required Data Sources
Linux auditd: SYSCALL records (syscall=41, a0=26)
auditd key: copy_fail_afalg deployed to all hosts
SIEM receiving real-time auditd stream (not batched)
Process context: uid, auid, exe, comm, pid fields extracted
Detection Logic (Splunk SPL)
index=linux_audit type=SYSCALL syscall=41 a0=26 a1=5 | where uid!="0" | stats count first(_time) as first_seen by host,uid,pid,exe
True Positive Criteria
Any non-root process opens socket(AF_ALG=38, SOCK_SEQPACKET) — production has effectively zero benign cases
a0=26 (hex) AND a1=5 (SOCK_SEQPACKET) — the Copy Fail PoC exact socket type
Triggered by Python process, especially from /tmp or /dev/shm
False Positive Scenarios
Custom application using AF_ALG directly for crypto (rare — verify with app owner, then allowlist by exe path)
Security research or penetration testing tools (allowlist by auid or session)
Alert Triage Checklist
  • Identify PID and examine full process tree: ps auxef | grep <pid>
  • Check if same PID has subsequent splice() event within 10s (UC-CF-002)
  • Identify the executable (exe field) — is it python3, unknown binary, or known app?
  • If exe is python3 + working dir is /tmp → escalate to P1 immediately
  • Check if algif_aead module is loaded: lsmod | grep algif_aead
  • If mitigation (blacklist) is deployed and module still loaded → investigate how it was re-enabled
UC-CF-002 AF_ALG Socket + splice() Chain from Same PID
Exploitation · Steps 3–4 of 6 CRITICAL T1068
Hypothesis
If a threat actor is actively executing Copy Fail, the same non-root PID that opened an AF_ALG socket (UC-CF-001) will call splice() within seconds — moving page-cache pages from the pipe buffer into the AF_ALG socket. The co-occurrence of these two specific syscalls from the same PID within a short window is the most specific behavioral signature of CVE-2026-31431.
Required Data Sources
Linux auditd: both socket (syscall=41) and splice (syscall=275) SYSCALL events
SIEM with correlation/transaction capability (Splunk transaction, Elastic EQL sequence)
PID preserved across multi-event correlation (within same audit session)
Detection Logic (Splunk transaction)
(syscall=41 a0=26 a1=5) OR (syscall=275) AND uid!="0" | transaction pid maxspan=10s | where mvfind(syscall,"41")>=0 AND mvfind(syscall,"275")>=0 | eval chain="COPY_FAIL_CHAIN"
True Positive Criteria
socket(AF_ALG) followed by splice() from same non-root PID within 10 seconds
The two events share the same uid (non-zero) and pid
Any occurrence is extremely high confidence — this combination has effectively no benign use case
False Positive Scenarios
Extremely unlikely in production. Only theoretical: a custom application that uses AF_ALG AND splice() in the same process context. If an app is identified, add exe-path exclusion — do NOT broadly suppress this rule.
Alert Triage Checklist
  • This alert = P1. Initiate IR immediately, notify SOC manager
  • Identify the PID and capture process memory if process still running
  • Check for subsequent execve() with uid!=0 → euid=0 (UC-CF-004) in next 30 seconds
  • Determine if algif_aead module was loaded (mitigation may have failed)
  • Isolate host if euid=0 transition is also observed
  • Preserve auditd logs to external storage immediately
UC-CF-003 SUID Binary Read → pipe2() → splice() Setup Sequence
Exploitation · Steps 1–2 of 6 CRITICAL T1068 T1548.001
Hypothesis
If a threat actor sets up the Copy Fail exploit, they will open a setuid binary read-only, create a pipe (pipe2 syscall=293 is used specifically in the PoC), and then call splice() to move the binary's page-cache pages into the pipe buffer. The openat(SUID) → pipe2() → splice() sequence within a single non-root PID window has no legitimate benign use case and is the most Copy Fail-specific pre-exploitation indicator.
Required Data Sources
auditd: openat() (syscall=257) with file path audit (-w /usr/bin/su -p rx)
auditd: pipe2() (syscall=293) and splice() (syscall=275) SYSCALL events
Elastic auditbeat EQL sequence capability, or Splunk transaction
Detection Logic (Elastic EQL / auditbeat)
sequence by process.pid with maxspan=8s [any where event.module=="auditd" and auditd.data.syscall=="257" // openat() and auditd.summary.object.primary in ("/usr/bin/su","/usr/bin/passwd", "/usr/bin/sudo") and user.id!="0"] [any where event.module=="auditd" and auditd.data.syscall in ("22","293") // pipe/pipe2 and user.id!="0"] [any where event.module=="auditd" and auditd.data.syscall=="275" // splice() and user.id!="0"]
True Positive Criteria
Non-root process opens /usr/bin/su (or similar SUID binary) read-only AND calls pipe2() AND splice() — all within 8 seconds
pipe2() specifically (syscall 293) — used in Copy Fail PoC, not common in normal workflows
Shell scripts that run su/passwd and also use pipes may trigger — inspect process lineage, suppress if parent is interactive shell with known job
Alert Triage Checklist
  • Check which SUID binary was opened — su/passwd = highest risk, sudo = also critical
  • Examine the parent process — script runner, cron, or unexpected Python? Python = P1
  • Check if AF_ALG socket creation followed (UC-CF-001) in the same session
  • Check if the exploit completed: look for uid=0 process without auth ancestor (UC-CF-004)
  • Verify algif_aead module is NOT loaded on the affected host
UC-CF-004 Privilege Escalation Confirmed: uid→euid=0 Without Auth
Exploitation · Step 6 — LPE SUCCESS CRITICAL T1068 T1548.001
Hypothesis
If Copy Fail exploitation succeeds, the attacker's process will transition from uid≠0 to euid=0 via execve() of the modified setuid binary, without any preceding sudo, su, login, or PAM event in the process ancestry. This "phantom root" — a root process with no legitimate auth parent — is the definitive post-exploitation signal. This use case detects LPE success, not just attempt.
Required Data Sources
auditd: SYSCALL execve (syscall=59) with uid + euid fields
TA-linux-auditd (Splunk) or auditbeat (Elastic) for euid field extraction
Process ancestry correlation — parent exe field must be available
Detection Logic (auditd + Splunk)
index=linux_audit type=SYSCALL syscall=59 | where uid!="0" AND euid="0" | where NOT match(exe, "(?i)(sudo|/sbin/su|/bin/su|login| sshd|pam|polkit|pkexec| systemd|crond|gdm)") | eval verdict="LPE_CONFIRMED" | table _time host uid auid pid exe comm verdict
True Positive Criteria
execve() where uid≠0 AND euid=0 AND parent exe is NOT a known auth mechanism
Root process with auid (audit login UID) set to non-zero — auid tracks the original logged-in user even through privilege changes; auid≠0 with euid=0 = LPE almost certainly
Combined with UC-CF-001 or UC-CF-002 in same session = confirmed Copy Fail
False Positive Scenarios
Custom PAM modules or auth frameworks not in the exclusion list — review and add to allowlist
Legitimate setuid binaries called in unusual contexts (e.g., ping, mount by scripts) — add specific exe paths to exclusion list after review
Alert Triage Checklist
  • This is a P1 escalation — root achieved without auth. Notify CISO immediately
  • Capture volatile memory BEFORE taking any containment action
  • Check auid field — if auid matches a known user account, you have the attacker's identity
  • Look backwards in audit log for UC-CF-001/002/003 events from same uid/pid
  • Check for post-exploitation: new SSH keys, SUID binaries, /etc/passwd changes (UC-CF-007)
  • Isolate host via EDR quarantine, preserving EDR comms channel
UC-CF-005 algif_aead Module Load / Blacklist Bypass
Defense Evasion CRITICAL T1562.001
Hypothesis
If the algif_aead module blacklist mitigation is deployed and an attacker has achieved root (or if the mitigation was not properly applied), the attacker may load or re-enable the algif_aead module to facilitate re-exploitation, leave a backdoor for other attackers, or verify the vulnerability window is still open. Any appearance of algif_aead in lsmod on a mitigated system indicates either mitigation failure or active defense evasion by a threat actor with existing root access.
Required Data Sources
auditd: -w /etc/modprobe.d/blacklist-copy-fail.conf -p wa (file watch)
Periodic lsmod check via osquery or Wazuh agent (every 5 minutes)
auditd: kmod/insmod/modprobe execution audit events
Detection Logic (Splunk + osquery)
// osquery pack — run every 5 min on all hosts SELECT name, size, used_by FROM kernel_modules WHERE name = 'algif_aead'; // Alert if rows returned on mitigated host // Splunk: blacklist file modified index=linux_audit type=SYSCALL key=copy_fail_mitigation | where syscall in ("2","257","82","87") // open/write/rename/unlink | table _time host uid exe comm
True Positive Criteria
algif_aead appears in lsmod on a system where blacklist-copy-fail.conf is deployed
blacklist-copy-fail.conf deleted, renamed, or modified (auditd file watch hit)
modprobe algif_aead executed by any process (especially non-root — which requires root anyway)
False Positive Scenarios
Mitigation was never deployed on this host — it will always show module potentially loaded. Resolve by ensuring 100% mitigation coverage before enabling this rule.
System admin intentionally reverting mitigation after patch confirmed — add change ticket correlation
Alert Triage Checklist
  • Verify whether the blacklist was deployed to this host: check /etc/modprobe.d/
  • Check who loaded the module or deleted the blacklist file (auid field)
  • Determine if this is a patched system (uname -r) — if patched AND module re-enabled = suspicious but lower risk
  • If unpatched AND module loaded: treat as active exploit risk, escalate to P1
  • Re-deploy mitigation immediately: modprobe -r algif_aead
UC-CF-006 Post-LPE Cloud Metadata API Credential Theft
Post-Exploitation · Credential Access CRITICAL T1552.005
Hypothesis
Within seconds of achieving root via Copy Fail on a cloud VM (EC2/GCE/Azure), a threat actor will query the instance metadata service (IMDS) at 169.254.169.254 to retrieve IAM credentials, cloud API tokens, or user-data secrets. This is the fastest path from Linux root to cloud account compromise and represents an attack pivot from OS-level to cloud-level. The process making this call will be the attacker's root shell or a post-exploit script — not a known cloud agent.
Required Data Sources
Network monitoring: outbound HTTP to 169.254.169.254 per process (eBPF or network logs)
AWS CloudTrail: AssumeRole / GetCallerIdentity from unexpected EC2 instance
Azure Activity Log: first-time VM managed identity token request from unexpected process
AWS GuardDuty: CredentialAccess:EC2/AnomalousBehavior finding
Detection Logic (Sentinel KQL)
DeviceNetworkEvents | where RemoteIP == "169.254.169.254" and OSPlatform == "Linux" | extend euid = tostring( parse_json(AdditionalFields).Euid) | where euid == "0" | where InitiatingProcessFileName !in~ ( "amazon-ssm-agent","aws-cfn-bootstrap", "cloud-init","waagent","google_guest_agent") | project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, euid
True Positive Criteria
HTTP GET to 169.254.169.254/latest/meta-data/iam/security-credentials from unexpected process with euid=0
First-time metadata API access by this specific process on this host in 90-day baseline (UEBA)
Curl/wget/python/bash accessing metadata API with elevated privileges — not a known cloud agent
False Positive Scenarios
Custom bootstrap scripts that run as root and query metadata at startup — allowlist by process name and schedule (e.g., first 5 minutes post-boot)
Application deployed with overly broad IAM permissions that legitimately queries IMDS — review and restrict IAM scope
Alert Triage Checklist
  • Check CloudTrail / Azure Activity Log for IAM credential use originating from this instance immediately after the event
  • Rotate IAM role credentials for the instance profile immediately (revoke STS tokens)
  • Determine what credentials were retrieved: check metadata path accessed (IAM vs user-data vs other)
  • Correlate backwards: did UC-CF-004 fire on same host within last 60 seconds?
  • Isolate instance AND disable IAM role to prevent further credential use
UC-CF-007 Post-Root Persistence: SSH Key / SUID Shell / Cron Implant
Post-Exploitation · Persistence CRITICAL T1098.004 T1548.001
Hypothesis
Within seconds to minutes of achieving root via Copy Fail, a threat actor will establish persistent access before the page-cache exploit is cleared by a reboot. The three most common persistence mechanisms are: (1) SSH authorized_key addition to /root/.ssh/, (2) SUID shell planted in /tmp or /usr/local/bin, (3) cronjob added to root's crontab. All three are detectable via auditd file integrity watches on the specific paths that matter.
Required Data Sources
auditd: -w /root/.ssh/authorized_keys -p wa (file write watch)
auditd: -w /etc/passwd -p wa and -w /etc/cron.d/ -p wa
auditd or FIM (Wazuh/OSSEC): chmod/fchmod with SUID mode (a1=2048) in /tmp, /usr/local/bin
Detection Logic (auditd rules)
// Already in copy-fail.rules: -w /root/.ssh/authorized_keys -p wa -k cf_persist -w /etc/passwd -p wa -k cf_persist -w /etc/shadow -p wa -k cf_persist // Additional: SUID bit set on new file -a always,exit -F arch=b64 -S chmod,fchmod -F a1=0x800 -F uid=0 -k cf_suid_plant // a1=0x800 = S_ISUID bit (setuid flag)
True Positive Criteria
/root/.ssh/authorized_keys written outside of configuration management (puppet/ansible/chef auid)
New file created with SUID bit (chmod +s) in /tmp, /dev/shm, or /usr/local/bin by unexpected process
/etc/passwd or /etc/shadow modified outside package manager context (not triggered by apt/yum/passwd utility running as expected)
New entry in /etc/cron.d/ written by non-cron process with uid=0
False Positive Scenarios
Configuration management tools (Ansible, Puppet, Chef) legitimately write SSH keys — allowlist by auid matching the CM service account
User password changes via passwd utility — exclude exe=/usr/bin/passwd for /etc/shadow watches
Alert Triage Checklist
  • Check auid — was this written by a CM tool account or unexpected uid?
  • For SSH key: inspect key content, check if it matches any known key in your inventory
  • For SUID binary: identify the file, hash it, check against VirusTotal
  • Correlate with UC-CF-004 — was root achieved via LPE in the same session?
  • Remove the persistence artifact AND isolate host — attacker likely has multiple persistence mechanisms
  • Scan for ALL persistence mechanisms, not just the triggered one
UC-CF-008 Container Escape: Copy Fail on Kubernetes Host Kernel
Exploitation · Container → Host Escape CRITICAL T1611 T1068
Hypothesis
Containers share the host kernel — if the host kernel is unpatched for CVE-2026-31431, any container without a seccomp profile blocking socket(AF_ALG) can exploit Copy Fail to achieve root on the host node, not just inside the container. An attacker running an arbitrary workload on a Kubernetes cluster (via supply chain, malicious image, or compromised CI/CD) can use this to escape the container runtime and gain full node access. Detection must correlate the container namespace context with the exploit syscall chain.
Required Data Sources
Falco: real-time syscall monitoring with container context (container.name, k8s.pod.name)
Kubernetes audit log: pod creation events for the workload that triggered the exploit
eBPF probe on Kubernetes nodes: AF_ALG socket creation with container.id context
auditd on host node: same rules as UC-CF-001, but container processes appear in host auditd
Detection Logic (Falco)
// Falco rule — fires with full container context - rule: Copy Fail in Container condition: > evt.type = socket and evt.arg.domain = 38 // AF_ALG decimal and user.uid != 0 and container.id != "" // running inside container and not proc.name in (openssl,gpg) output: > COPY_FAIL IN CONTAINER (pod=%k8s.pod.name ns=%k8s.ns.name uid=%user.uid image=%container.image cmd=%proc.cmdline) priority: CRITICAL
True Positive Criteria
socket(AF_ALG=38) by non-root process inside a container (container.id not empty in Falco)
The container's pod is NOT in a known trusted namespace (kube-system crypto operations might use AF_ALG)
Kubernetes pod was recently created (within last hour) and is an unexpected workload
False Positive Scenarios
Crypto-heavy workloads in containers that legitimately use AF_ALG (hardware crypto offload) — rare, but allowlist by namespace and image digest if confirmed
Alert Triage Checklist
  • Identify the pod and namespace: kubectl get pod -n <ns> -o yaml — who owns this workload?
  • Check if pod has seccomp profile: .spec.securityContext.seccompProfile — if missing, exploit path is open
  • Check host node kernel version: was node patched? kubectl debug node/<node> -- uname -r
  • Kill the pod immediately: kubectl delete pod <name> -n <ns> --force
  • Check host auditd for UC-CF-004 (uid=0 transition) on the node — did the exploit complete?
  • Cordon the node immediately: kubectl cordon <node> — prevent new pod scheduling while investigating
  • Audit all pods running on this node for similar patterns: kubectl get pods --field-selector spec.nodeName=<node>
Use Case Kill Chain Coverage Map
Use Case Kill Chain Stage MITRE Specificity Best Platform
UC-CF-001Pre-exploitation / Step 1T1068Copy Fail SPECIFIC — AF_ALG socketauditd + Splunk/Sentinel
UC-CF-002Active exploitation / Steps 3–4T1068Copy Fail SPECIFIC — syscall chainSplunk transaction / Elastic EQL
UC-CF-003Setup / Steps 1–2 (pre-AF_ALG)T1068 + T1548.001Copy Fail SPECIFIC — pipe2+spliceElastic EQL sequence / auditbeat
UC-CF-004Exploitation success / Step 6T1068 + T1548.001Generic LPE (all kernel LPE) — auid narrowsauditd + all SIEMs
UC-CF-005Defense Evasion (post-root)T1562.001Copy Fail SPECIFIC — algif_aead moduleosquery + auditd FIM
UC-CF-006Post-exploitation / Cred AccessT1552.005Generic cloud post-LPE (high value)Sentinel + AWS GuardDuty ML
UC-CF-007Post-exploitation / PersistenceT1098.004 + T1548.001Generic post-root (FIM-based)auditd FIM + Wazuh
UC-CF-008Container → Host EscapeT1611 + T1068Copy Fail + container contextFalco + K8s audit log
Threat Hunting
18 production-ready queries across Splunk, Sentinel KQL, Elastic EQL, QRadar AQL, Sigma YAML, Falco YAML, eBPF bpftrace, and auditd. Filter by platform. All specific to CVE-2026-31431 — no generic LPE rules.
Platform:
AF_ALG Socket by Non-Root
CRITICALSPLUNK
AF_ALG socket creation by non-root. a0=26 is hex (auditd logs syscall args in hex without 0x prefix): 0x26 = 38 decimal = AF_ALG. a1=5 = SOCK_SEQPACKET — the exact socket type used in the Copy Fail PoC. Adding a1=5 makes this Copy Fail-specific rather than generic AF_ALG detection. Requires TA-linux-auditd or equivalent for field extraction.
/* CVE-2026-31431: AF_ALG socket by non-root a0=26 is HEX (no 0x prefix in auditd output) 0x26 decimal = 38 = AF_ALG socket family a1=5 = SOCK_SEQPACKET (exact type in Copy Fail PoC) Requires: TA-linux-auditd or SA-CommonInfoModel */ index=linux_audit sourcetype=linux_audit type=SYSCALL syscall=41 a0=26 a1=5 | where uid!="0" | rex field=exe "(?<binary>[^/]+)$" | stats count min(_time) as first_seen max(_time) as last_seen values(exe) as executables by host uid auid pid | eval risk="COPY_FAIL_STEP1" | table host uid auid pid executables first_seen last_seen count risk | sort -count
Splice from Python (Non-Root)
CRITICALSPLUNK
splice() syscall from Python interpreter by non-root user. Combined with AF_ALG socket creation in the same session, this is the exploit chain confirmed. Step 2 of Copy Fail.
/* CVE-2026-31431: splice() from Python non-root */ index=linux_audit sourcetype=linux_audit type=SYSCALL syscall=275 | where uid!="0" | search exe="*python*" OR exe="*python3*" | stats count values(comm) as procs values(exe) as binaries min(_time) as first_seen by host uid auid pid | eval severity="CRITICAL" | eval note="Copy Fail Step 2 — splice chain" | table host uid auid pid procs binaries first_seen count severity
UID=0 Transition Without sudo/su
CRITICALSPLUNK
execve() where uid!=0 but euid=0 — successful LPE. Filter excludes known-legitimate auth mechanisms (sudo, su, login, sshd, PAM, polkit). Any remaining result = LPE confirmation.
/* CVE-2026-31431: Phantom root — LPE success */ index=linux_audit sourcetype=linux_audit type=SYSCALL syscall=59 | where uid!="0" AND euid="0" | where NOT match(exe, "(?i)(sudo|/sbin/su|/bin/su|login|sshd|pam|polkit|pkexec)") | eval copy_fail="LPE_CONFIRMED" | stats count values(exe) as binaries values(comm) as processes min(_time) as first_seen by host uid auid pid | table host uid auid processes binaries first_seen count copy_fail | sort -count
AF_ALG + Splice Transaction (Chain)
HIGHSPLUNK
Correlates AF_ALG socket creation AND splice() syscall from the same PID within 10 seconds. Detecting the 2-event chain dramatically reduces false positives vs individual syscall alerts.
/* CVE-2026-31431: Correlated exploit chain */ index=linux_audit sourcetype=linux_audit (syscall=41 a0=26) OR (syscall=275) | where uid!="0" | eval event_type=case( syscall="41" AND a0="26","AF_ALG_SOCKET", syscall="275","SPLICE", true(),"OTHER") | transaction pid maxspan=10s maxevents=10 | where mvcount(event_type)>1 | where mvfind(event_type,"AF_ALG_SOCKET")>=0 AND mvfind(event_type,"SPLICE")>=0 | eval chain="COPY_FAIL_CHAIN_DETECTED" | table _time host uid pid event_type chain
Python from Temp Directories
HIGHSPLUNK
Python3 interpreter executing a script from /tmp, /dev/shm, /run/user, or /var/tmp by a non-root user. Copy Fail PoC always runs from temp directories — low false positive in production environments.
/* CVE-2026-31431: Python PoC from temp dir */ index=linux_audit sourcetype=linux_audit type=EXECVE | search a0="*python*" OR a0="*python3*" | rex field=a1 "^(?<script_path>/.*\.py)$" | where match(script_path, "^(/tmp|/dev/shm|/run/user|/var/tmp|/run/shm)") | where uid!="0" | stats count values(script_path) as scripts min(_time) as first_seen by host uid auid comm | eval sev="HIGH - PoC path pattern" | table host uid auid comm scripts first_seen count sev
AF_ALG Socket Hunt (Sentinel)
CRITICALKQL
Microsoft Sentinel KQL — AF_ALG socket creation by non-root via Linux CEF connector (auditd → Sentinel). Requires Linux CEF data connector configured with auditd forwarding.
// CVE-2026-31431: AF_ALG socket — Sentinel CEF CommonSecurityLog | where TimeGenerated > ago(7d) | where DeviceEventClassID == "SYSCALL" | where AdditionalExtensions has "syscall=41" | extend uid = extract(@"uid=(\d+)", 1, AdditionalExtensions) | extend a0 = extract(@"a0=([0-9a-f]+)", 1, AdditionalExtensions) | where a0 == "26" // AF_ALG = 38 decimal | where uid != "0" and uid != "" | summarize Count = count(), Hosts = make_set(Computer), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by uid, a0 | extend Alert = "CVE-2026-31431 AF_ALG exploitation" | order by Count desc
UID=0 Transition on Linux (Defender MDE)
CRITICALKQL
MDE for Linux — detects uid→euid=0 transition without legitimate auth ancestor. ProcessTokenElevationType does NOT exist on Linux — it's a Windows-only column. This query uses OSPlatform == "Linux" filter and reads uid/euid from AdditionalFields JSON, which is how MDE surfaces Linux process credential data.
// CVE-2026-31431: LPE on Linux — MDE DeviceProcessEvents // ProcessTokenElevationType is Windows-only — NOT used here // On Linux, uid/euid live in AdditionalFields as JSON // Requires: MDE Linux agent (mdatp) deployed on hosts DeviceProcessEvents | where TimeGenerated > ago(7d) | where OSPlatform == "Linux" | extend uid = tostring( parse_json(AdditionalFields).Uid) | extend euid = tostring( parse_json(AdditionalFields).Euid) | where isnotempty(uid) and isnotempty(euid) | where uid != "0" and euid == "0" | where InitiatingProcessFileName !in~ ( "sudo","su","login","sshd", "pam_unix","gdm","lightdm", "systemd","crond","init") | project TimeGenerated, DeviceName, OSPlatform, AccountName, uid, euid, FileName, FolderPath, ProcessCommandLine, InitiatingProcessFileName | extend LPERisk = "CRITICAL — Copy Fail LPE" | order by TimeGenerated desc
TriFive Draft C2 — Sentinel 2026
HIGHKQL
Hunt for Linux processes making first-time cloud metadata API calls (169.254.169.254) post-privilege-escalation. Post-Copy Fail AWS/Azure IAM credential theft pattern.
// Post-LPE: Cloud metadata API access // Detect first-time 169.254.169.254 access DeviceNetworkEvents | where TimeGenerated > ago(7d) | where RemoteIP == "169.254.169.254" or RemoteIP == "fd00:ec2::254" | join kind=inner ( DeviceProcessEvents | where TimeGenerated > ago(7d) | extend EUID = tostring( parse_json(AdditionalFields).Euid) | where EUID == "0" ) on DeviceName, InitiatingProcessId | summarize Count=count(), Processes=make_set(InitiatingProcessFileName) by DeviceName, RemoteIP, RemotePort | extend Risk = "Post-LPE Metadata Exfil" | order by Count desc
AF_ALG → splice Chain (auditbeat EQL)
CRITICALELASTIC EQL
Requires: auditbeat ≥ 8.x with auditd module + copy-fail.rules deployed. Sequences socket(AF_ALG) then splice() from same PID within 10s. AF_ALG family = 38 decimal = 0x26 hex → auditd logs it as a0=26 in auditd.data.a0 field — NOT in process.args.
/* CVE-2026-31431: AF_ALG+splice chain — auditbeat EQL Fields: auditd.data.* are populated by auditbeat auditd module auditd logs syscall args in HEX: AF_ALG=38dec=0x26 → a0="26" Deploy copy-fail.rules to auditd FIRST or events won't appear */ sequence by process.pid with maxspan=10s [any where event.module == "auditd" and auditd.data.syscall == "41" // socket() and auditd.data.a0 == "26" // AF_ALG=38dec=0x26hex and auditd.data.a1 == "5" // SOCK_SEQPACKET and user.id != "0"] [any where event.module == "auditd" and auditd.data.syscall == "275" // splice() x86_64 and user.id != "0"]
SUID open → pipe2 → splice Sequence
CRITICALELASTIC EQL
Most Copy Fail-specific EQL rule: sequences openat() on a setuid binary → pipe2() → splice() from the same non-root PID. pipe2() syscall=293 is used specifically in the Copy Fail PoC — not generic splice detection. Requires auditbeat + copy-fail.rules.
/* CVE-2026-31431: SUID open → pipe2 → splice pipe2() syscall=293 is used in the Copy Fail PoC openat() syscall=257 opens the setuid target auditd.summary.object.primary = file path for file events Requires: auditbeat + auditd rules for syscalls 257,293,275 */ sequence by process.pid with maxspan=8s [any where event.module == "auditd" and auditd.data.syscall == "257" // openat() and user.id != "0" and auditd.summary.object.primary in ( "/usr/bin/su", "/usr/bin/passwd", "/usr/bin/sudo", "/usr/bin/newgrp", "/usr/bin/chsh", "/usr/bin/chfn")] [any where event.module == "auditd" and auditd.data.syscall in ( "22", "293") // pipe() or pipe2() and user.id != "0"] [any where event.module == "auditd" and auditd.data.syscall == "275" // splice() and user.id != "0"]
LPE: uid→euid=0 Without Auth (auditbeat)
CRITICALELASTIC EQL
Detects successful LPE: execve() where uid≠0 but euid=0 without a legitimate auth ancestor. Uses user.effective.id (the ECS field for euid on Linux) — NOT process.token.elevation_type which is Windows-only and does not exist in Linux auditbeat events.
/* CVE-2026-31431: LPE confirmed — execve uid→euid=0 user.effective.id = euid in Linux ECS auditbeat schema process.token.elevation_type is Windows-only — NOT used here process.code_signature does NOT exist on Linux ELF binaries */ any where event.module == "auditd" and auditd.data.syscall == "59" // execve() and user.id != "0" // real uid non-root and user.effective.id == "0" // euid = root → LPE and not process.parent.name in ( "sudo", "su", "login", "sshd", "pam_unix", "gdm", "lightdm", "systemd", "crond")
AF_ALG Socket — Raw Payload Search
CRITICALQRADAR
QRadar AQL against raw Linux OS syslog events. "Custom String1/2" are not real QRadar fields — those require pre-configured DSM custom properties that vary per deployment. This query uses UTF8(payload) to search raw auditd log content directly, which works on any QRadar without custom property setup. For production, build a Linux Audit DSM with a0/syscall custom properties.
-- CVE-2026-31431: QRadar AQL — raw payload search -- UTF8(payload) searches the raw auditd syslog line -- auditd logs socket args in hex: AF_ALG=38dec → a0=26 (no 0x) -- NOTE: UTF8(payload) is slow on large volumes. -- For prod: create custom DSM properties for a0/syscall fields SELECT LOGSOURCENAME(logsourceid) AS source, sourceip AS host, username AS uid, UTF8(payload) AS raw_event, DATEFORMAT(starttime, 'YYYY-MM-dd HH:mm:ss') AS event_time FROM events WHERE LOGSOURCETYPENAME(logsourceid) = 'Linux OS' AND LOWER(UTF8(payload)) LIKE '%type=syscall%' AND UTF8(payload) LIKE '%syscall=41%' -- socket() AND UTF8(payload) LIKE '% a0=26 %' -- AF_ALG=38dec=0x26hex AND UTF8(payload) LIKE '% a1=5 %' -- SOCK_SEQPACKET AND username NOT IN ( 'root', '0', '') AND starttime > DATEADD('day', -7, NOW()) ORDER BY starttime DESC LAST 7 DAYS
Sigma: AF_ALG by Non-Root
CRITICALSIGMA
Sigma rule detecting AF_ALG socket creation by non-root user. Deploy via sigmatools to convert to your SIEM platform. Level: high. Contribute to SigmaHQ after validation.
title: CVE-2026-31431 AF_ALG Socket Non-Root id: a7f3e821-b4c9-4d82-copy-fail-001 status: stable description: > AF_ALG socket creation (family=38) by non-root. Step 1 of Copy Fail exploit chain. Extremely rare in legitimate non-root usage. references: - https://theori.io/research/cve-2026-31431 tags: - attack.privilege_escalation - attack.t1068 - cve.2026-31431 logsource: product: linux service: auditd detection: selection: type: SYSCALL syscall: 41 a0: '26' filter_root: uid: '0' condition: selection and not filter_root level: high falsepositives: - Custom crypto apps using AF_ALG directly
Sigma: LPE Success Detection
CRITICALSIGMA
Sigma rule detecting successful LPE: execve() with euid=0 from non-root process without legitimate auth ancestry. Level: critical. Core rule for any kernel LPE — not Copy Fail specific.
title: Linux LPE — UID Transition No Auth id: b9e2f934-c5d1-copy-fail-002 status: stable description: > Non-root execve() achieving euid=0 without sudo/su/login ancestor. Post-exploitation signature for Copy Fail and any kernel LPE. tags: - attack.privilege_escalation - attack.t1068 - attack.t1548.001 - cve.2026-31431 logsource: product: linux service: auditd detection: selection: type: SYSCALL syscall: 59 uid|not: '0' euid: '0' filter_legitimate: exe|contains: - sudo - /sbin/su - login - sshd - pam - polkit - pkexec condition: selection and not filter_legitimate level: critical
Falco: AF_ALG + Splice Rules
CRITICALFALCO
Falco runtime security rules for CVE-2026-31431. Deploy as Falco DaemonSet on Kubernetes or standalone on Docker/bare-metal Linux. Real-time alerting with container context.
# Copy Fail — Falco runtime detection rules - rule: CVE-2026-31431 AF_ALG Non-Root desc: AF_ALG socket (family 38) by non-root. Step 1 of Copy Fail exploit chain. condition: > evt.type = socket and evt.arg.domain = 38 and user.uid != 0 and not proc.name in ( openssl, gpg, cryptsetup) output: > COPY_FAIL AF_ALG socket by non-root (uid=%user.uid pid=%proc.pid cmd=%proc.cmdline container=%container.name) priority: CRITICAL tags: [CVE-2026-31431, T1068] - rule: CVE-2026-31431 Splice from Script desc: splice() from Python/shell by non-root. Combined with AF_ALG = exploit chain. condition: > evt.type = splice and user.uid != 0 and proc.name in ( python, python3, perl, ruby) output: > COPY_FAIL splice from scripting engine (uid=%user.uid cmd=%proc.cmdline container=%container.name) priority: HIGH tags: [CVE-2026-31431, T1068]
eBPF bpftrace: Real-Time Monitor
CRITICALeBPF
bpftrace probe for real-time AF_ALG + splice chain detection. Run directly on suspicious systems. Tracks PIDs that open AF_ALG sockets and alerts immediately when same PID calls splice(). Zero-overhead when not triggered.
#!/usr/bin/env bpftrace // CVE-2026-31431 Copy Fail — real-time eBPF probe // Run: bpftrace copy_fail_detect.bt // Step 1: AF_ALG socket by non-root tracepoint:syscalls:sys_enter_socket /args->family == 38 && uid > 0/ { printf("[COPY_FAIL][AF_ALG] pid=%d uid=%d comm=%s\n", pid, uid, comm); @afalg_pids[pid] = nsecs; } // Step 2: splice() from tracked PID tracepoint:syscalls:sys_enter_splice /@afalg_pids[pid] && uid > 0/ { printf("[COPY_FAIL][CHAIN] EXPLOIT DETECTED" " pid=%d uid=%d comm=%s\n", pid, uid, comm); } // Cleanup stale entries every 60s interval:s:60 { clear(@afalg_pids); }
auditd: Complete Ruleset
CRITICALAUDITD
Complete auditd detection ruleset for CVE-2026-31431. Deploy to /etc/audit/rules.d/. Covers all 3 exploit chain steps, post-exploitation persistence, and mitigation file integrity monitoring.
## /etc/audit/rules.d/copy-fail.rules ## CVE-2026-31431 Copy Fail Detection ## Load: augenrules --load # Rule 1: AF_ALG socket by non-root (a0=0x26) -a always,exit -F arch=b64 -S socket \ -F a0=0x26 -F uid!=0 \ -k copy_fail_afalg -a always,exit -F arch=b32 -S socket \ -F a0=0x26 -F uid!=0 \ -k copy_fail_afalg # Rule 2: splice() by non-root -a always,exit -F arch=b64 -S splice \ -F uid!=0 -k copy_fail_splice # Rule 3: uid=0 execve from non-root -a always,exit -F arch=b64 -S execve \ -F uid!=0 -F euid=0 -k copy_fail_lpe # Rule 4: setuid binary access by non-root -a always,exit -F arch=b64 -S open,openat \ -F path=/usr/bin/su -F uid!=0 \ -k copy_fail_setuid -a always,exit -F arch=b64 -S open,openat \ -F path=/usr/bin/passwd -F uid!=0 \ -k copy_fail_setuid # Rule 5: Mitigation file integrity -w /etc/modprobe.d/blacklist-copy-fail.conf \ -p wa -k copy_fail_mitigation # Rule 6: Post-root persistence -w /etc/passwd -p wa -k copy_fail_persist -w /root/.ssh/authorized_keys \ -p wa -k copy_fail_persist
Priority deployment order: (1) auditd ruleset — zero-overhead, immediate, runs on any Linux · (2) eBPF bpftrace — real-time on suspected hosts · (3) Splunk/Sentinel/Elastic queries — fleet-wide retrospective hunt · (4) Sigma rules — convert and deploy to your SIEM · (5) Falco — Kubernetes and container environments
References: Theori.io advisory · NVD CVE-2026-31431 · kernel commit a664bf3d603d · MITRE T1068 · Sigma HQ
Reality Check — AI in SOC for Copy Fail Detection
Honest assessment: No SOC AI tool will automatically detect CVE-2026-31431 out of the box today. AI helps after you deploy the right telemetry (auditd rules, eBPF probes). Without syscall-level logs feeding your SIEM, no AI — no matter how advanced — can see this exploit. Deploy detection rules first. Then AI adds value on top.
What AI SOC Tools Can Actually Do for Copy Fail
AI Adds Real Value Here ✓
UEBA baseline anomaly: First-ever AF_ALG socket on a host — flags Step 1 of exploit chain before root is achieved. This actually works because AF_ALG has near-zero baseline usage
Risk-Based Alerting (RBA): Splunk ES can score AF_ALG socket (risk +50) + splice from same PID (risk +40) + uid=0 transition (risk +80) = notable event only when total risk exceeds threshold — eliminates alert flood
AI-assisted triage: Splunk AI Assistant / Elastic AI Assistant can summarize the auditd event chain in plain English for L1 analysts, reducing MTTR
AWS GuardDuty ML: Automatically detects first-time metadata API access (169.254.169.254) by unusual processes post-LPE — built-in, zero config needed
Automated vulnerability scanning: Tenable plugins, Wiz cloud scanning, Qualys checks can identify unpatched hosts fleet-wide without manual checks
AI Cannot Help Here ✗
No telemetry = no detection: If auditd isn't running with AF_ALG rules, AI has nothing to analyze. Most default Linux installs don't log syscall-level data
Page-cache write is invisible: No AI, EDR, or monitoring tool can observe the actual 4-byte page-cache write — it's a kernel-internal memory operation with no event emitted
File integrity tools fail: AIDE, Tripwire, OSSEC FIM — all check disk. Copy Fail modifies memory only. These tools report "no changes" even after exploitation
No pre-built detection rule exists: As of May 2026, no major SIEM/EDR vendor has shipped a pre-built Copy Fail detection rule. You must deploy the community rules from this playbook or build your own
Container runtime limitations: Falco and Sysdig can detect AF_ALG socket creation, but cannot see the page-cache corruption or the splice-to-socket chain without custom rules
SOC AI Platforms — What Each Can Do Today (Verified)
Platform Capabilities for Copy Fail Detection
Platform What It Can Do for Copy Fail Pre-Built Rule? What You Need
Splunk ES 8.5 RBA scores aggregate AF_ALG + splice + LPE events into single notable. AI Assistant summarizes findings for L1 analysts. Detection Studio maps coverage gaps against ATT&CK T1068. No — deploy SPL from this playbook auditd → Splunk via TA-linux-auditd
Microsoft Sentinel UEBA baselines privilege patterns per user. Flags uid→euid=0 without auth ancestor as behavioral anomaly. KQL hunting queries in this playbook work directly. No — deploy KQL from this playbook MDE Linux agent or CEF auditd connector
Elastic Security EQL sequences detect AF_ALG → splice → su chain with PID correlation. Elastic AI Assistant explains alert context. Auditbeat feeds syscall events directly. No — deploy EQL from this playbook auditbeat with auditd module
CrowdStrike Falcon Falcon Linux sensor captures syscall telemetry. Behavioral AI can flag unusual process chains (python → AF_ALG → root). Charlotte AI generates hunting queries from natural language. Behavioral detection possible — no CVE-specific rule Falcon Linux sensor deployed
SentinelOne Singularity agent monitors Linux process lifecycle. Purple AI generates hunting queries in natural language. CVE tracked in vulnerability database. Behavioral detection possible — no CVE-specific rule Singularity Linux agent
AWS GuardDuty ML automatically flags first-time metadata API (169.254.169.254) access by unusual processes — catches post-LPE credential theft without any custom rules. Yes — built-in ML findings GuardDuty enabled on EC2/EKS
Tenable / Nessus Scanner plugins released — identifies unpatched kernel versions across fleet. Classified as Vulnerability Watch item. Does NOT detect exploitation — only vulnerability presence. Yes — scanner plugins available Nessus/Tenable.io scan
Wiz Cloud workload scanning identifies vulnerable kernel versions. Published auth.log detection signal. Pre-built queries in Wiz Threat Intel Center for customer environments. Yes — advisory + queries available Wiz agent on cloud workloads
Falco / Sysdig Runtime syscall monitoring with container context (pod name, namespace, image). Detects AF_ALG socket creation inside containers. Best for Kubernetes environments. No — deploy Falco rule from this playbook Falco DaemonSet on K8s
Wazuh Open-source SIEM with auditd decoder. Correlation rules from this playbook (Level 10/14) bridge auditd events into Wazuh alerts. Free alternative to commercial SIEMs. No — deploy XML rules from this playbook Wazuh agent + auditd rules
How SOC AI Actually Responds to Zero-Days (Before Any Rule Exists)
When CVE-2026-31431 was disclosed on April 29, no vendor had a pre-built detection rule. But AI-powered SOC tools didn't need one. Here's what each AI layer does during the first 24–72 hours of a zero-day — the gap between disclosure and vendor rule release.
HOUR 0–1 Behavioral AI Detects the Anomaly (No Rule Needed)
When Copy Fail runs, the endpoint AI sees a process chain it has never observed before:
python3 → socket(AF_ALG) → splice() → uid=0 root shell

This chain is behaviorally anomalous — no normal workload creates AF_ALG sockets from Python and then escalates to root. Behavioral AI flags this as suspicious without knowing it's CVE-2026-31431. The AI doesn't match a signature — it detects that the behavior has never happened on this host before.
CrowdStrike Falcon AI: Process Lifecycle Model flags the python→root chain as IOA (Indicator of Attack). Charlotte AI auto-generates a threat summary for the analyst. Falcon OverWatch may hunt proactively if the pattern is seen across multiple customers.
SentinelOne Singularity: Static + Behavioral AI on the endpoint detects the anomalous privilege transition. Storyline engine reconstructs the full attack chain visually. Purple AI lets analyst ask "what happened on this host?" in plain English.
HOUR 1–4 UEBA Flags the Privilege Anomaly
UEBA engines maintain a 90-day baseline of how each user and host normally behaves. When a user who has never created an AF_ALG socket suddenly does, or when a root process appears without sudo/su in the process ancestry — UEBA risk scores spike automatically.
Splunk UBA / ES RBA: Risk-Based Alerting scores each event: AF_ALG socket (+50 risk), splice from same PID (+40), uid=0 without sudo (+80). Only generates a notable event when cumulative risk crosses threshold — eliminates alert flood.
Microsoft Sentinel UEBA: Entity behavior baseline flags "impossible privilege escalation" — user achieved root without any known auth mechanism in their behavioral history. Risk score assigned based on deviation from 90-day baseline.
HOUR 4–24 AI Assistant Accelerates Investigation
Once the SOC team knows about CVE-2026-31431, they need to hunt across the fleet fast. AI assistants help analysts write queries, summarize findings, and triage alerts — cutting investigation time from hours to minutes.
Splunk AI Assistant: Analyst asks "summarize AF_ALG socket events on prod servers this week" → AI generates SPL, runs it, summarizes results in plain English. Also auto-generates investigation report for CISO.
Elastic AI Assistant: Analyst pastes CVE description → AI generates EQL sequence query for AF_ALG + splice chain. Explains alert context and suggests investigation steps based on MITRE ATT&CK mapping.
CrowdStrike Charlotte AI: Analyst asks "are any hosts showing AF_ALG socket activity from non-root?" → Charlotte queries Falcon telemetry across the entire fleet and returns results with context.
HOUR 24–72 Cloud AI Catches Post-Exploitation Automatically
If an attacker achieves root via Copy Fail on a cloud instance, their next move is predictable: query the metadata API (169.254.169.254) for IAM credentials, then pivot to cloud resources. Cloud-native AI detects this without any custom rules.
AWS GuardDuty ML: Built-in ML finding: UnauthorizedAccess:EC2/MetadataIPSSRFAttempt and CredentialAccess:EC2/AnomalousBehavior fire automatically when an unusual process accesses IMDS. Zero configuration required.
Wiz Runtime Sensor: Detects vulnerable kernel versions + runtime exploitation signals. Publishes pre-built queries in Wiz Threat Intel Center. Auto-prioritizes workloads with internet exposure + unpatched kernel.
Key Takeaway
AI doesn't need a CVE-specific rule to detect zero-days. Behavioral AI detects the behavior (anomalous process chain, privilege anomaly, first-time event) — not the specific exploit technique. That's why organizations with behavioral AI + UEBA + auditd telemetry had detection capability for Copy Fail from hour zero, while organizations relying only on signature-based rules had zero visibility until community rules were published 24–48 hours later.

But AI only works if the telemetry is flowing. Without auditd rules or an EDR agent capturing Linux syscalls, behavioral AI has nothing to analyze. Deploy the auditd rules from this playbook as the foundation — then let AI add intelligence on top.
Bottom Line — Detection Stack for Copy Fail
Priority 1 (deploy now): auditd rules from this playbook → feeds your SIEM (Splunk/Sentinel/Elastic/QRadar/Wazuh). This is the foundation — everything else depends on it.

Priority 2 (if you run containers): Falco rules from this playbook → real-time container AF_ALG detection with K8s context.

Priority 3 (if you run cloud): Ensure AWS GuardDuty / Azure Defender is enabled — built-in ML catches post-LPE metadata API access without custom rules.

Priority 4 (vulnerability scanning): Run Tenable/Wiz/Qualys scan to identify unpatched hosts fleet-wide. This tells you WHERE to focus — not whether exploitation happened.

The gap: No vendor has shipped a pre-built "Copy Fail" detection rule as of May 2026. The rules in this playbook fill that gap. Deploy them into your SIEM today.