Een handshake die op een fout eindigt voelt als een aanval tot je naar het bericht kijkt, en meestal is het rekenwerk: geen gedeeld aanbod, een verlopen certificaat of een pakket dat nooit aankwam. Een downgrade-aanval is iets specifieks: een tegenstander die beide kanten naar zwakker gedrag duwt dan ze gekozen zouden hebben, en hij laat ander bewijs achter. Elke fout als kwaadwilligheid behandelen stuurt je op zoek naar een slachtoffer dat er misschien niet is, terwijl een echte downgrade als configuratiefout behandelen het zwakkere resultaat laat staan. De twee fouten kosten verschillend, en slechts één ervan is goedkoop te herstellen.

Wat een downgrade-aanval werkelijk verandert

Het doel is niet het cijfer breken en niet een sleutel raden. Het is de onderhandeling beïnvloeden zodat beide kanten op een oudere versie of een zwakker algoritme uitkomen dat de aanvaller aankan, of één kant laten geloven dat de ander alleen dat ondersteunt.

Wat verandert is de overeenkomst, niet de authenticatie. Als de aanvaller het aanbod ongemerkt kan wijzigen, kunnen de peers nog steeds een handshake voltooien en elkaar nog steeds authenticeren, met parameters die de aanvaller verkiest. Daarom is de interessante vraag of de onderhandeling zelf door integriteitsbescherming wordt gedekt.

Waarom de onderhandeling zelf geauthenticeerd moet worden

TLS 1.3 maakt die bescherming expliciet. Een client die de nieuwere versie aanbood, kan een server detecteren die stil terugviel, omdat de willekeurige waarde van de server een vast patroon draagt wanneer hij 1.2 of lager onderhandelt, en de client moet afbreken wanneer hij dat ziet. Het volledige transcript wordt ook gedekt door de eindberichten, dus een wijziging ergens in de onderhandeling mislukt later in plaats van stil door te gaan.

Oudere protocolversies hadden zwakkere verhalen, en dat is precies waarom de fallback-regels ertoe doen. Een TLS 1.0-eindpunt in dezelfde configuratie is geen downgrade-aanval; het is een toegestaan resultaat dat je zelf hebt gekozen toe te staan. Het onderscheid is of het zwakkere resultaat uit een beschermde beslissing kwam of uit een onbeschermd pad dat een tussenpartij kon beïnvloeden. Formuleer je het zo, dan lossen de meeste incidenten op in een configuratievraag.

IKEv2 gedraagt zich anders maar rust op hetzelfde idee. Het aanbod wordt gedragen in een uitwisseling die later beide peers authenticeert, dus een middlebox die de algoritmes herschrijft breekt de authenticatie in plaats van haar te sturen. Het besturingskanaal van OpenVPN beschermt zijn onderhandeling met TLS en gebruikt dat kanaal vervolgens om de cijfers van het datakanaal af te spreken, en daarom is de logregel van het besturingskanaal de interessante.

Geconfigureerde compatibiliteit is geen aanval

Een beheerder kan bewust oudere keuzes toestaan om een gedocumenteerde client te ondersteunen, en die beslissing is zichtbaar in de configuratie. Een aanvaller kan die configuratie niet maken; hij kan alleen een pad misbruiken dat hem het aanbod laat beïnvloeden.

De gevaarlijke reparatie is degene die het bewijs van het verschil wegneemt. Elke oude optie inschakelen, certificaatverificatie uitschakelen of elk cijfer accepteren om een fout te laten verdwijnen verbreedt wat het eindpunt zal accepteren, en haalt de controles weg die het zwakkere resultaat zouden hebben gemeld.

Moet je één oude optie houden, noem dan de reden en de client in het configuratiecommentaar en beperk de optie daarna tot het profiel dat hem nodig heeft. Een compatibiliteitsuitzondering beperkt tot één listener is controleerbaar; een die globaal wordt toegepast is gewoon een zwakkere standaard waarvan niemand zich herinnert die gekozen te hebben.

Lees de fout voordat je een oorzaak noemt

Bewaar de exacte foutstring, de client- en serverversies en het tijdstip vóór elke wijziging. Classificeer dan: waren de peers het oneens over een aanbod, faalde het pakketpad, of wees één kant een parameter af die het ooit accepteerde?

Een mismatch in het aanbod noemt meestal de boosdoener-versies of algoritmes en faalt elke keer op hetzelfde punt. Een routing- of MTU-probleem stokt of loopt in een timeout, en het varieert vaak met het netwerk. Een verlopen certificaat geeft een verificatiefout in plaats van een onderhandelingsfout.

Niets daarvan is bewijs van een aanvaller. Bij de eerste fout een kwaadwillige oorzaak toekennen is de fout, omdat het de deterministische bug verbergt die morgen weer faalt.

Bevestig wat er werkelijk is gekozen

Lees na elke correctie het onderhandelde resultaat in plaats van te vertrouwen op dat de verbinding opkwam. Een verbinding die slaagt omdat verificatie is verwijderd, is de uitkomst die je wilde vermijden. De twee opdrachten hieronder tonen de gekozen versie en het cijfer voor een TLS-eindpunt, plus de regel van het besturingskanaal uit een OpenVPN serverlog.

openssl s_client -connect 198.51.100.30:443 -servername vpn.example.net -brief </dev/null
grep -iE 'Control Channel|Data Channel' /var/log/openvpn.log | tail -5

Vergelijk het resultaat met de configuratie die je bedoelde, niet met wat nu verbindt. Is de gekozen versie ouder dan het toegestane minimum, dan zijn het profiel of de fallback-lijst de plek om te kijken, en het antwoord is die lijst te repareren in plaats van een aanval uit te roepen en alles eromheen opnieuw te bouwen.

Gerelateerde artikelen