
Detection rules, YARA signatures, auditd/Wazuh rules, and MISP event templates for CVE-2026-31431 Linux kernel LPE vulnerability (Copy Fail). Includes IoCs, mitigation steps, and exploit analysis.
Published: 2026-04-30
CVSSv3: 7.8 (High)
Type: Local Privilege Escalation (LPE)
Subsystem: Linux kernel algif_aead / authencesn cryptographic template
Affected: Linux kernels 4.14 – 6.18.21 (virtually all distributions since 2017)
References:
CVE-2026-31431 is a logic flaw introduced in kernel 4.14 (2017) at the intersection of three independent changes:
authencesn template (added 2011 for IPsec ESN support) writes 4 bytes of scratch data past its output buffer boundary.AF_ALG gained AEAD support in 2015, allowing userspace to submit data via splice() from page-cached files.algif_aead.c was optimized to operate in-place (req->src == req->dst), placing live page-cache pages into a writable scatterlist.The result: an unprivileged user can write exactly 4 attacker-controlled bytes into the kernel's page-cache copy of any readable file — including setuid binaries and /etc/passwd — without touching the on-disk file. The working PoC is a 732-byte Python script. No race condition. No per-distribution offsets. Reliable across Ubuntu, RHEL, Amazon Linux, and SUSE.
Attacker opens AF_ALG socket (family 38, type 5)
└─ Binds to "authencesn(hmac(sha256),cbc(aes))"
└─ Sets SOL_ALG (279) options including key and authsize
└─ Accepts a connection socket
Attacker opens target file (e.g., /etc/passwd) read-only
└─ Uses splice() to feed page-cache pages into the AEAD socket's RX buffer
└─ Sends crafted AAD via sendmsg() — bytes 4–7 of AAD = attacker-controlled write value
authencesn performs in-place decryption:
└─ scatterwalk_map_and_copy writes seqno_lo into the chained page-cache page
└─ recvmsg() returns an error (HMAC fails — expected), but the write already happened
Page-cache now contains attacker-modified copy of the file
└─ Kernel executes from page-cache, not disk
└─ On-disk file is UNCHANGED — file integrity tools see nothing
The PoC targets /etc/passwd: it finds the offset of the running user's UID field and overwrites it with 0000, then invokes su to obtain a root shell.
Read this section before deploying any rules below.
This exploit has two properties that significantly limit detection coverage:
1. The write goes to the page cache, not the filesystem.
Any detection tool that monitors file system events — inotify, fanotify, AIDE, Tripwire, auditd path watches — will not observe the modification. The on-disk file is never written. This means the -p w (write) flags in auditd path watches for /usr/bin/su or /etc/passwd will not catch the actual exploitation write.
2. The mechanism uses legitimate kernel interfaces.
AF_ALG sockets, splice(), and authencesn all have legitimate uses (IPsec, kernel self-tests, sendfile-style I/O). Detection must focus on the combination of these primitives rather than any one in isolation, and false positives should be expected on systems running IPsec or doing kernel crypto testing.
What detection CAN catch:
socket(AF_ALG, SOCK_SEQPACKET, 0) syscallsplice() syscall correlated with the above, especially near setuid binary accessauthencesn(hmac(sha256),cbc(aes)) algorithm string in process memory or script filesWhat detection CANNOT catch:
su or passwd call)Before deploying detection rules, apply this mitigation on any unpatched host:
# Disable algif_aead kernel module — blocks the exploit primitive entirely
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null || true
Verify the mitigation is active using the official detector:
# Exit 0 = not vulnerable / mitigated
# Exit 2 = VULNERABLE
python3 test_cve_2026_31431.py
Note: The
rmmodcommand will fail if the module is not currently loaded; this is acceptable. Themodprobe.dconfig prevents future loads. This mitigation has no impact on standard TLS, SSH, or filesystem encryption workloads — it only affects IPsec with Extended Sequence Numbers using theauthencesntemplate, which is uncommon outside dedicated VPN gateways.
Save as cve_2026_31431.yar
Scanning scope: This rule is designed to scan Python script files on disk or pulled from memory dumps. It will match the known PoC and close variants. It will NOT detect the exploit activity at the syscall level — use the auditd/Wazuh rules for that.
rule CVE_2026_31431_CopyFail_PoC_HighConfidence {
meta:
description = "High-confidence match: CVE-2026-31431 Copy Fail PoC or close variant"
author = "Detection Engineering"
reference = "https://xint.io/blog/copy-fail-linux-distributions"
cve = "CVE-2026-31431"
date = "2026-04-30"
severity = "High"
cvss = "7.8"
strings:
// Algorithm string unique to this exploit path — very high fidelity
$alg_full = "authencesn(hmac(sha256),cbc(aes))" ascii
// Specific socket call signature from PoC: AF_ALG=38, SOCK_SEQPACKET=5
$socket_call = "socket(38,5,0)" ascii
// SOL_ALG socket option (decimal 279)
$solalg = "setsockopt(279" ascii
// Hex key/iv payload written via setsockopt in PoC
$key_payload = "0800010000000010" ascii
// splice() usage in context of AEAD operations
$splice = "splice(" ascii
// Target indicators from PoC (page-cache corruption targets)
$target_passwd = "/etc/passwd" ascii
$target_su = "/usr/bin/su" ascii
// AF_ALG aead bind strings
$aead_bind = "\"aead\"" ascii
condition:
// High-confidence: unique algorithm string alone is sufficient
$alg_full
or
// Medium-confidence: socket primitive + option number
($socket_call and $solalg)
or
// Medium-confidence: splice into AEAD socket targeting a setuid path
($aead_bind and $splice and ($target_passwd or $target_su))
or
// PoC hex payload present alongside splice
($key_payload and $splice)
}