
Prüft, ob ein Host IPv4-TCP-SYNs mit IP-Optionen verwirft (Mitigation von CVE-2026-98432)
Prüft, ob ein Host TCP-IPv4-SYNs mit IP-Optionen verwirft, die empfohlene Netzwerk-Mitigation für CVE-2026-98432 (Use-after-free im TCP-IPv4-Handshake des Linux-Kernels, CVSS 9.8, bis der gepatchte Kernel erscheint).
Für jeden Port sendet es ein normales SYN und ein SYN mit IPv4 Record Route und vergleicht die Antworten. Es ist harmlos: Es wird nichts ausgenutzt, nur ein Handshake geöffnet (und nicht abgeschlossen).
Was der Test misst: ob das SYN mit IP-Optionen ankommt und vom Ziel akzeptiert wird. Er liest nicht die Kernel-Version. Ein bereits gepatchter Kernel akzeptiert weiterhin IP-Optionen und gibt
EXPOSTOaus — in diesem Fall bedeutetEXPOSTOnur „kein IP-Optionen-Filter“, und die Korrektur lässt sich mituname -rüberprüfen.
./verifica-cve-2026-98432.sh <host-ou-ip> [porta ...] # porta padrão: 443
./verifica-cve-2026-98432.sh exemplo.com 443 80 22
Ohne Skript, direkt über das Image (das Ziel muss IPv4 sein):
docker run --rm --network host --cap-add NET_RAW \
ghcr.io/marcelofmatos/cve-2026-98432-check:latest 203.0.113.10 443 22
| Ausgabe | Exit | Bedeutung |
|---|---|---|
MITIGADO | 0 | Normales SYN akzeptiert, SYN mit IP-Optionen verworfen — und kein Hop auf dem Pfad filtert IP-Optionen |
EXPOSTO | 1 | Das SYN mit IP-Optionen wurde ebenfalls akzeptiert: weder auf dem Pfad noch am Ziel wird gefiltert |
INCONCLUSIVO | 2 | Port geschlossen (RST) oder gefiltert — verwenden Sie einen offenen Port |
SEM HOST | 2 | Ziel im lokalen Netz und niemand antwortet per ARP darauf: IP frei oder Rechner ausgeschaltet. Es wird keine TCP-Sonde gesendet |
NÃO CONFIÁVEL | 3 | Ein Hop auf dem Pfad (VPN, Provider) verwirft bereits IP-Optionen. Das „verworfen" beweist nichts über das Ziel: Testen Sie von einem anderen Punkt im Netz aus |
| — | 64 | Falsche Verwendung oder Name ohne IPv4 |
Bei mehreren Ports ist der Exit der Worst Case: jedes EXPOSTO → 1.
Details:
getent), daher funktionieren VPN-/interne DNS-Namen.prerouting eintritt, als käme es von außen.CHECK_IMAGE (Standard ghcr.io/marcelofmatos/cve-2026-98432-check:latest). Die 1. Zeile
des Logs ist die Version: cve-2026-98432-check <versão> iniciando.Viele VPNs und Provider verwerfen Pakete mit IP-Optionen. Testet man hinter einem solchen, wirkt jedes Ziel als mitigiert. Deshalb durchläuft der Prüfer den Pfad Hop für Hop (steigende TTL), bevor er testet, und gibt NÃO CONFIÁVEL zurück, wenn ein Hop IP-Optionen verwirft.
Einschränkung: Ein Filter an einem Hop, der nicht auf ICMP antwortet, bleibt unbemerkt. Validieren Sie den Testpunkt an einem bekanntermaßen nicht mitigierten Ziel: Es muss EXPOSTO ergeben.
Ein verwundbares Linux gibt die IP-Optionen im SYN-ACK zurück (das SYN mit Record Route kommt mit
ihl=6 und der RR-Option zurück). An einem Testpunkt mit der Regel aus mitigacao/ wird dieses SYN-ACK
im prerouting verworfen. Trotzdem ist das Ergebnis korrekt: scapy fängt die Antwort am Paket-Socket ab, vor
dem Netfilter. Gemessen: Beim Testen von einem Host mit der Regel gegen ein Ziel ohne die
Regel war das Ergebnis EXPOSTO und der Zähler der Regel stieg um 1 (das SYN-ACK wurde nach dem
Abfangen verworfen). Der Test alvo sem a regra (container) -> EXPOSTO deckt diesen Fall in der CI ab, die die
Tests mit dem Runner ohne und mit der Regel ausführt.
Ausnahme: Ziele hinter einer Bridge des Testpunkts selbst mit br_netfilter. Mit geladenem Modul
(net.bridge.bridge-nf-call-iptables = 1, Standard bei Docker-Swarm-Hosts und vielen
Proxmox) läuft das IPv4-prerouting noch innerhalb der Bridge, vor dem Abfangen. In diesem Fall verwirft die Regel
des Testpunkts das SYN-ACK eines Containers oder einer VM dieser Bridge, und das Ergebnis ist ein
falsches MITIGADO. Ziele, die über eine normale Netzwerkkarte erreicht werden (ein anderer Rechner im Netz), sind nicht betroffen.
Um Container oder VMs eines Hosts mit br_netfilter zu testen, verwenden Sie einen Testpunkt außerhalb davon oder einen
ohne die Regel. Die Tests überspringen diesen Fall (SKIP), wenn sie diese Kombination erkennen.
Wenn der Port des Ziels von Docker veröffentlicht wird (DNAT zu einem Container), antwortet das Ziel selbst mit ICMP
„TTL exceeded" auf die Sonden mit niedriger TTL, weil es das Paket weiterleitet. Der Prüfer erkennt dieses ICMP
an der Quell-IP (es ist die IP des Ziels) und behandelt es nicht als Hop auf dem Pfad. Bis Version 1.1.0 gab er
ein falsches NÃO CONFIÁVEL bei einem mitigierten Ziel aus, wenn der 1. Port der Liste weitergeleitet wurde. Der
Test porta encaminhada no alvo mitigado -> MITIGADO deckt diesen Fall ab.
In mitigacao/:
cve-2026-98432.nft: Tabelle ip cve_2026_98432, die TCP IPv4 mit ip hdrlength > 5
im prerouting (Priorität -300) verwirft. Idempotent.cve-2026-98432-mitigation.service: systemd-Unit, die die Regel lädt, bevor das Netzwerk hochkommt.sudo install -m 644 mitigacao/cve-2026-98432.nft /etc/cve-2026-98432.nft
sudo install -m 644 mitigacao/cve-2026-98432-mitigation.service /etc/systemd/system/
echo 'net.mptcp.enabled = 0' | sudo tee /etc/sysctl.d/90-cve-2026-98432-mptcp.conf
sudo sysctl -w net.mptcp.enabled=0
sudo systemctl daemon-reload && sudo systemctl enable --now cve-2026-98432-mitigation
Die Mitigation ersetzt nicht den gepatchten Kernel: Installieren Sie ihn und starten Sie neu, sobald Ihre Distribution ihn veröffentlicht.
flowchart LR
U["Operador"] --> L["verifica-cve-2026-98432.sh<br/>resolve o nome com getent<br/>escolhe a rede do container"]
L -->|"docker run --cap-add NET_RAW"| C["Container cve-2026-98432-check<br/>Alpine + Python + scapy"]
C -->|"rede host: alvo remoto"| N["Caminho de rede<br/>VPN, operadora, internet"]
C -->|"bridge: alvo é a própria máquina"| H["prerouting do host"]
N --> A["Alvo IPv4<br/>porta TCP"]
REG["GHCR<br/>ghcr.io/marcelofmatos/cve-2026-98432-check"] -.->|"docker pull"| C
flowchart TD
S["Início: alvo e portas"] --> AQ{"Alvo na rede local<br/>e sem resposta ARP?"}
AQ -->|"sim"| SH["SEM HOST — exit 2"]
AQ -->|"não"| H["TTL = 1, 2, 3 ... até o alvo<br/>SYN normal e SYN com RR"]
H --> HQ{"Algum salto responde ICMP ao normal<br/>e some com o RR?"}
HQ -->|"sim"| FL["caminho FILTRA no salto N"]
HQ -->|"não, chegou ao alvo, ICMP veio do próprio alvo<br/>ou 4 saltos mudos seguidos"| OK["nenhum filtro visto"]
FL --> P
OK --> P
P["Por porta: SYN normal"] --> PQ{"SYN-ACK?"}
PQ -->|"não"| INC["INCONCLUSIVO — exit 2"]
PQ -->|"sim"| R["SYN com RR"]
R --> RQ{"Alguma resposta?"}
RQ -->|"sim"| EXP["EXPOSTO — exit 1"]
RQ -->|"não, caminho filtra"| NC["NÃO CONFIÁVEL — exit 3"]
RQ -->|"não, caminho limpo"| MIT["MITIGADO — exit 0"]
docker build --build-arg APP_VERSION=dev -t cve-2026-98432-check:dev .
# ESPERADO_LOCAL=1 num host sem a regra nft; 0 num host com a regra aplicada
CHECK_IMAGE=cve-2026-98432-check:dev ESPERADO_LOCAL=1 VERSAO_ESPERADA=dev ./tests/testes.sh