Share
## https://sploitus.com/exploit?id=EDA6BA70-68B9-5D54-9C53-1DE0BCA51BAA
# CVE-2026-31431 โ "Copy Fail": Linux Kernel `algif_aead` Local Privilege Escalation
> **CISA KEV | CVSS 7.8 HIGH | Affects Linux kernels 4.14 โ early 2026 (~9 years)**
---
## Table of Contents
1. [Executive Summary](#1-executive-summary)
2. [Risk Assessment](#2-risk-assessment)
3. [Technical Deep Dive](#3-technical-deep-dive)
4. [Attack Methodology โ Red Team](#4-attack-methodology--red-team)
5. [Detection & Incident Response โ Blue Team](#5-detection--incident-response--blue-team)
6. [Patching & Remediation](#6-patching--remediation)
7. [Lab Environment](#7-lab-environment)
8. [References](#8-references)
---
## 1. Executive Summary
**CVE-2026-31431**, nicknamed **"Copy Fail"**, is a high-severity local privilege escalation (LPE) vulnerability in the Linux kernel's cryptographic subsystem. A low-privileged local user can escalate to **root in seconds** on any unpatched system.
| Attribute | Value |
|-----------|-------|
| CVE | CVE-2026-31431 |
| Nickname | Copy Fail |
| CVSS v3.1 | **7.8 HIGH** |
| Attack Vector | Local |
| Privileges Required | Low |
| User Interaction | None |
| Component | `crypto/algif_aead.c` โ `authencesn` template |
| Introduced | 2017 (commit `72548b093ee3`) |
| Disclosed | 2026 |
| Years Silent | ~9 years |
| CISA KEV | **Yes** |
| Public PoC | **Yes** (732-byte standalone Python script) |
### Business Impact
- **Root access** on any unpatched Linux server, VM, cloud instance, or container host
- **Container escape** from Kubernetes pods โ page cache is shared with the host kernel
- **Zero on-disk footprint** โ exploitation leaves no file changes, no dirty pages, no audit trail via standard file integrity tools (Tripwire, AIDE)
- Affects **Red Hat, Ubuntu, Debian, SUSE, Amazon Linux**, and virtually all major distributions running kernels from 2017 onward
### Recommended Immediate Action
1. **Temporary mitigation** (deploy now, no reboot required if module not loaded):
```bash
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null || true
```
2. **Permanent fix**: Update kernel packages via your distribution's package manager and reboot.
3. **Verify**: Run `detection/check_vulnerable.sh` before and after remediation.
---
## 2. Risk Assessment
### CVSS 3.1 Vector String
```
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
```
| Metric | Value | Rationale |
|--------|-------|-----------|
| Attack Vector | **Local** | Requires shell access (SSH, container exec, physical) |
| Attack Complexity | **Low** | Reliable, fully automated โ no race condition required |
| Privileges Required | **Low** | Any unprivileged user account |
| User Interaction | **None** | No victim interaction needed |
| Confidentiality | **High** | Full system compromise |
| Integrity | **High** | Full system compromise |
| Availability | **High** | Full system compromise |
### Threat Landscape
| Factor | Assessment |
|--------|-----------|
| PoC Availability | Public, weaponized, 732-byte standalone Python |
| Exploit Reliability | High โ works across tested distros without modification |
| Detection Difficulty | High โ no disk writes, no dirty pages |
| Attacker Skill Required | Low โ script kiddie with public PoC |
| CISA KEV | Added 2026 โ actively monitored |
| Microsoft Defender | Flagged as under active investigation |
### Affected Environments
| Environment | Risk |
|-------------|------|
| Bare-metal Linux servers | Critical |
| Linux VMs (cloud or on-prem) | Critical |
| Kubernetes nodes | Critical (also enables container escape) |
| Docker hosts | Critical |
| Shared hosting / multi-tenant | Critical |
| WSL2 / Linux on Windows | Assess per kernel version |
---
## 3. Technical Deep Dive
### 3.1 Background: AF_ALG and AEAD
The Linux kernel exposes cryptographic operations to userspace via **AF_ALG sockets** (`AF_ALG = 38`). This interface (`algif_aead`) allows unprivileged applications to invoke kernel crypto hardware accelerators without needing kernel-mode code.
**AEAD** (Authenticated Encryption with Associated Data) algorithms like AES-GCM and ChaCha20-Poly1305 are widely used for TLS, disk encryption, and VPN protocols. The vulnerable template is `authencesn` โ an AEAD composition using `hmac(sha256)` + `cbc(aes)` with Extended Sequence Number (ESN) support, commonly used in IPsec.
### 3.2 Root Cause
In 2017, commit `72548b093ee3` introduced **in-place AEAD operation** to `algif_aead` as a performance optimization โ allowing the crypto engine to read and write the same buffer. This was flawed:
```
The bug chain:
1. Caller binds AF_ALG socket to:
authencesn(hmac(sha256),cbc(aes))
2. Caller sends a decryption request via sendmsg() with specific flags
3. Caller uses splice() to feed PAGE CACHE PAGES from an open file
descriptor directly into the socket's scatterlist
4. The authencesn template, during ESN header processing, uses the
OUTPUT BUFFER as scratch space โ writing 4 bytes past the
expected output boundary
5. Because the scatterlist contains page cache pages (not private
copies), this scratch write lands DIRECTLY IN THE PAGE CACHE
6. Page cache is shared kernel-wide โ all processes reading the
same file now see the modified bytes
Key insight: splice() is zero-copy โ it hands page cache references
to the socket. The in-place "optimization" then writes INTO those
pages. No dirty bit is set because the write goes through the crypto
engine, not the normal write path.
```
### 3.3 The Write Primitive
The vulnerability provides a **controlled 4-byte write into the page cache** of any file the attacker can open for reading:
| Property | Value |
|----------|-------|
| Write size | 4 bytes |
| Offset control | Yes โ attacker-controlled via splice offset |
| Target | Page cache of any readable file |
| Dirty page marking | **None** |
| On-disk modification | **None** |
| Timestamp update | **None** |
| Kernel log entry | None (unless auditd configured) |
The write is repeatable โ the exploit loops the 4-byte write to patch larger code sequences.
### 3.4 Exploitation Chain
```
[1] Open /usr/bin/su (or any setuid-root binary) for reading
โ
[2] Map a copy to find target instruction bytes
(e.g., UID check, execve path, security gate)
โ
[3] Compute exact page cache offset of target bytes
โ
[4] Set up AF_ALG socket โ authencesn(hmac(sha256),cbc(aes))
โ
[5] splice() the target binary's page cache into the socket
โ
[6] Trigger decryption โ authencesn scratch write patches
the target bytes in page cache (4 bytes per iteration)
โ
[7] Repeat for each 4-byte patch needed
โ
[8] Execute /usr/bin/su โ runs root-owned setuid binary
but now with attacker-controlled code in page cache
โ
[9] Root shell
```
### 3.5 Why Standard Defenses Fail
| Defense | Bypassed? | Reason |
|---------|-----------|--------|
| File Integrity Monitoring (Tripwire/AIDE) | **Yes** | No on-disk change |
| IDS file hash checks | **Yes** | Disk bytes unchanged |
| `inotify` file watch | **Yes** | No VFS write event |
| SELinux / AppArmor | **Partial** | Controls process, not page cache write via crypto engine |
| Read-only mounts | **Yes** | Page cache modified in-memory, not via mount |
| auditd `watch` on binary | **Yes** | Audit watches VFS writes โ this bypasses VFS |
### 3.6 Affected Kernel Versions
| Branch | Vulnerable Through | Fixed From |
|--------|-------------------|------------|
| 4.14.x | All (vulnerability origin) | No upstream fix (EOL) |
| 5.4.x (LTS) | All | Distribution backport required |
| 5.10.x (LTS) | All | Distribution backport required |
| 5.15.x (LTS) | All | Distribution backport required |
| 6.1.x (LTS) | โค 6.1.129 | **6.1.130+** |
| 6.6.x (LTS) | โค 6.6.86 | **6.6.87+** |
| 6.12.x (LTS) | โค 6.12.22 | **6.12.23+** |
| 6.15-rc | Fixed in rc | **6.15-rc+** |
> Distribution kernels may have backported the fix at different version numbers. Always check your distribution's security advisory.
---
## 4. Attack Methodology โ Red Team
> **Authorization Required.** This section exists to help defenders understand attacker perspective. Only execute on systems you own or have explicit written authorization to test.
### 4.1 Prerequisites
- Low-privileged shell on target (SSH, container exec, RCE chain)
- Python 3.10+ **or** compiled C binary
- Unpatched kernel with `algif_aead` available
### 4.2 Recon
```bash
# Check if vulnerable
uname -r
cat /proc/crypto | grep -A10 "authencesn"
lsmod | grep algif_aead
# Verify setuid target exists
ls -la /usr/bin/su /usr/bin/sudo /usr/bin/passwd
```
### 4.3 Public PoC
The original researchers (Theori) released a fully working 732-byte standalone Python PoC:
- **Repository**: https://github.com/theori-io/copy-fail-CVE-2026-31431
- **Website**: https://copy.fail
- **File**: `copy_fail_exp.py`
```bash
# Default: targets /usr/bin/su
python3 copy_fail_exp.py
# Custom target
python3 copy_fail_exp.py /usr/bin/passwd
```
A local copy is available at `exploit/poc.py`. See `exploit/README.md` for technical breakdown.
### 4.4 Container Escape Scenario
Because the Linux page cache is shared between all processes on the same host (including host and containers):
```
Attacker in container โ patches /usr/bin/su in HOST page cache
Host user runs su โ executes attacker code as root on host
```
This works even from non-privileged containers, as long as the host kernel is vulnerable.
### 4.5 MITRE ATT&CK Mapping
| Technique | ID | Notes |
|-----------|-----|-------|
| Exploitation for Privilege Escalation | T1068 | Core technique |
| Abuse Elevation Control Mechanism: Setuid/Setgid | T1548.001 | Setuid binary hijack |
| Hijack Execution Flow | T1574 | In-memory binary patching |
| Indicator Removal: Timestomp | T1070.006 | No timestamps updated |
| Indirect Command Execution | T1202 | Patched binary executes shell |
---
## 5. Detection & Incident Response โ Blue Team
> **This is the primary focus of this repository.**
### 5.1 Vulnerability Detection
Run the detection script on any Linux system:
```bash
chmod +x detection/check_vulnerable.sh
sudo ./detection/check_vulnerable.sh
```
**What it checks:**
- Kernel version against known-vulnerable ranges
- `algif_aead` module load status and blacklist status
- `authencesn` availability in `/proc/crypto`
- Page cache integrity of setuid binaries (requires root)
- Distribution-specific patch status
- Running processes for active exploitation indicators
A timestamped report is saved to `/tmp/cve-2026-31431-report-*.txt`.
### 5.2 YARA Detection
Two YARA rules are provided in `detection/yara/`:
| Rule File | Purpose |
|-----------|---------|
| `cve_2026_31431_base.yar` | Matches known public PoC exactly |
| `cve_2026_31431_enhanced.yar` | Detects obfuscated, compiled, and variant exploits |
```bash
# Install YARA
apt-get install yara # Debian/Ubuntu
dnf install yara # RHEL/Fedora
apk add yara # Alpine
# Scan running process executables
sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /proc/*/exe 2>/dev/null
# Scan common dropper locations
sudo yara -r detection/yara/cve_2026_31431_enhanced.yar /home /tmp /var/tmp /dev/shm
# Scan uploaded files / quarantine
yara detection/yara/cve_2026_31431_base.yar
```
**Why enhanced rules matter**: Attackers may obfuscate the public Python PoC (base64-encode strings, XOR-encode the algorithm name, compile to a C binary, strip symbols). The enhanced rule detects these variants by targeting invariants that cannot be removed without breaking the exploit:
- The kernel MUST receive `authencesn` as the algorithm name
- The exploit MUST use `splice()` to achieve zero-copy page cache access
- The exploit MUST create an AF_ALG socket (family `38`)
### 5.3 Auditd Rules
Deploy to `/etc/audit/rules.d/cve-2026-31431.rules`:
```bash
# Detect AF_ALG socket creation (family 38 = 0x26)
-a always,exit -F arch=b64 -S socket -F a0=38 -k cve_2026_31431_afalg
# Detect splice() calls โ used to feed page cache into the socket
-a always,exit -F arch=b64 -S splice -k cve_2026_31431_splice
# Monitor algif_aead module loading
-a always,exit -F arch=b64 -S init_module -S finit_module -k cve_2026_31431_modload
# Detect setuid binary execution by non-root users
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -k cve_2026_31431_suid_exec
```
Reload:
```bash
augenrules --load && service auditd restart
```
Query for exploitation attempts:
```bash
# Look for AF_ALG socket creation
ausearch -k cve_2026_31431_afalg --start today
# Correlate: same PID doing AF_ALG socket + splice
ausearch -k cve_2026_31431_afalg -k cve_2026_31431_splice --start today
```
### 5.4 Falco / eBPF Detection
Add to `/etc/falco/rules.d/cve-2026-31431.yaml`:
```yaml
- rule: CVE-2026-31431 AF_ALG Socket Creation
desc: Detects unprivileged process creating AF_ALG socket (family 38) โ required step for Copy Fail exploit
condition: >
syscall.type = socket and
evt.arg.domain = 38 and
not user.uid = 0 and
not proc.name in (known_crypto_daemons)
output: >
CVE-2026-31431 exploitation attempt - AF_ALG socket (user=%user.name
uid=%user.uid pid=%proc.pid cmd=%proc.cmdline)
priority: CRITICAL
tags: [cve-2026-31431, lpe, kernel, crypto]
- list: known_crypto_daemons
items: [strongswan, charon, pluto, openssl]
- rule: CVE-2026-31431 Splice After AF_ALG
desc: Detects splice() syscall shortly after AF_ALG socket creation โ exploitation sequence
condition: >
syscall.type = splice and
not user.uid = 0 and
evt.elapsed
CVE-2026-31431 splice after AF_ALG socket (user=%user.name pid=%proc.pid)
priority: CRITICAL
tags: [cve-2026-31431, lpe]
```
### 5.5 Page Cache Integrity Check
Since the exploit modifies the page cache **without writing to disk**, standard FIM tools are blind. This check detects active exploitation:
```bash
#!/bin/bash
# Compare in-memory binary against on-disk binary
SETUID_BINS=("/usr/bin/su" "/usr/bin/sudo" "/usr/bin/passwd")
for binary in "${SETUID_BINS[@]}"; do
[[ -f "$binary" ]] || continue
LIVE_HASH=$(sha256sum "$binary" | awk '{print $1}')
echo 3 | sudo tee /proc/sys/vm/drop_caches > /dev/null # flush page cache
DISK_HASH=$(sha256sum "$binary" | awk '{print $1}')
if [[ "$LIVE_HASH" != "$DISK_HASH" ]]; then
echo "CRITICAL: Page cache tampering detected on $binary"
echo " Pre-flush: $LIVE_HASH"
echo " Post-flush: $DISK_HASH"
else
echo "OK: $binary page cache matches disk"
fi
done
```
> **Production note:** `drop_caches` causes a performance hit. Run during maintenance windows or on non-critical systems first.
### 5.6 Indicators of Compromise (IoCs)
| IoC Type | Indicator | Confidence |
|----------|-----------|-----------|
| String (binary/script) | `authencesn(hmac(sha256),cbc(aes))` | High |
| Hex bytes | `78 DA AB 77 F5 71 63 62 64 64` (zlib payload header) | High |
| Syscall sequence | `socket(38,5,0)` โ `bind()` โ `splice()` | High |
| Network | None โ purely local | N/A |
| File | No disk writes (stealth) | โ |
| Process | Short-lived Python/C process with AF_ALG socket | Medium |
| Page cache | Setuid binary page cache โ on-disk hash | Critical |
### 5.7 SIEM Detection Queries
**Splunk (auditd source):**
```spl
index=linux_audit sourcetype=auditd action=SYSCALL syscall=socket a0="0x26"
| join pid [
search index=linux_audit sourcetype=auditd action=SYSCALL syscall=splice
]
| where (_time - join_time) /dev/null || echo "Not loaded โ mitigation active after config"
# Verify
lsmod | grep algif_aead && echo "WARNING: still loaded โ reboot needed" || echo "OK: not loaded"
```
*If `algif_aead` is already loaded, a reboot is required for the blacklist to take full effect.
**Side effects:** Applications that use the kernel AEAD interface via AF_ALG (uncommon โ most use OpenSSL userspace) may fail. Standard TLS, disk encryption, and VPN tools are generally unaffected.
### 6.2 Permanent Fix โ Kernel Update
| Distribution | Update Command |
|---|---|
| Ubuntu / Debian | `apt-get update && apt-get upgrade linux-image-generic && reboot` |
| RHEL / CentOS / Rocky | `dnf update kernel && reboot` |
| Amazon Linux 2 | `yum update kernel && reboot` |
| Amazon Linux 2023 | `dnf update kernel && reboot` |
| SUSE / SLES | `zypper update kernel-default && reboot` |
| Arch Linux | `pacman -Syu linux && reboot` |
| Alpine Linux | `apk update && apk upgrade linux-lts && reboot` |
| Debian | `apt-get update && apt-get upgrade linux-image-amd64 && reboot` |
### 6.3 Kubernetes Clusters
```bash
# Check all node kernel versions
kubectl get nodes -o wide
# Drain โ update node kernel โ uncordon (one node at a time)
kubectl drain --ignore-daemonsets --delete-emptydir-data
# SSH into node and run kernel update
kubectl uncordon
```
Use node auto-upgraders (Karpenter, Managed Node Groups) or cluster node pool rotation where available.
### 6.4 Post-Patch Verification
```bash
# Re-run detection script
sudo ./detection/check_vulnerable.sh
# Quick manual verification
uname -r # confirm new kernel version
lsmod | grep algif_aead # should be empty
cat /proc/crypto | grep authencesn # should return nothing (or still listed but module blacklisted)
```
---
## 7. Lab Environment
A minimal Alpine Docker lab is provided for testing detection tooling safely.
```bash
cd lab/
docker compose up -d
docker exec -it cve-2026-31431-lab /bin/sh
# Inside container:
/cve-2026-31431/detection/check_vulnerable.sh
```
> **Important:** Docker containers share the host kernel. The lab tests **your host kernel's** vulnerability status. Vulnerability results reflect the actual host system โ this is intentional for realistic assessment.
For isolated testing with a specific vulnerable kernel version, use a dedicated VM with a pinned kernel. See `lab/README.md` for VM setup guidance.
---
## 8. References
| Resource | Link |
|----------|------|
| NVD Advisory | https://nvd.nist.gov/vuln/detail/CVE-2026-31431 |
| Original Research | https://copy.fail |
| Technical Write-up | https://xint.io/blog/copy-fail-linux-distributions |
| Public PoC | https://github.com/theori-io/copy-fail-CVE-2026-31431 |
| CISA KEV Catalog | https://www.cisa.gov/known-exploited-vulnerabilities-catalog |
| Kernel Fix โ Revert Commit | `a664bf3d603d` / `fafe0fa2995a` |
| Vulnerable Commit | `72548b093ee3` |
| Microsoft Defender Advisory | Microsoft Defender Threat Intelligence Blog |
---
## Repository Structure
```
cve-2026-31431/
โโโ README.md โ This document
โโโ exploit/
โ โโโ README.md โ Technical exploit breakdown
โ โโโ poc.py โ Public PoC (theori-io, for reference)
โโโ detection/
โ โโโ README.md โ Detection guide
โ โโโ check_vulnerable.sh โ Vulnerability & IoC detection script
โ โโโ yara/
โ โโโ cve_2026_31431_base.yar โ Detects known public PoC
โ โโโ cve_2026_31431_enhanced.yar โ Detects obfuscated/compiled variants
โโโ patch/
โ โโโ README.md โ Remediation guide
โ โโโ patch.sh โ Automated patch/mitigation script
โโโ lab/
โโโ README.md โ Lab setup guide
โโโ Dockerfile โ Alpine-based lab container
โโโ docker-compose.yml โ Lab orchestration
```
---
*This research is provided for educational and defensive security purposes only. All tooling is designed to help defenders detect and remediate CVE-2026-31431 on systems they are authorized to protect.*
*Repository maintained by [rippsec](https://github.com/rippsec)*