SSL-terugval uitschakelen en alleen TLS gebruiken voor uitgaande verbindingen in .NET? (Poedelbeperking)

Ik probeer onze kwetsbaarheid voor de Poodle SSL 3.0 Fallbackte verkleinen aanval. Onze beheerders zijn al begonnen met het uitschakelen van SSL ten gunste van TLS voor inkomende verbindingen met onze servers. En we hebben ons team ook geadviseerd om SSL in hun webbrowsers uit te schakelen. Ik kijk nu naar onze .NET-codebase, die HTTPS-verbindingen initieert met verschillende services via System.Net.HttpWebRequest. Ik geloof dat deze verbindingen kwetsbaar kunnen zijn voor een MITM-aanval als ze terugval van TLS naar SSL toestaan. Dit is wat ik tot nu toe heb vastgesteld. Zou iemand dit kunnen controleren om te controleren of ik gelijk heb? Deze kwetsbaarheid is gloednieuw, dus ik heb nog geen richtlijnen van Microsoft gezien over hoe deze in .NET te verminderen:

  1. De toegestane protocollen voor de klasse System.Net.Security.SslStream, die veilige communicatie in .NET ondersteunt, worden globaal ingesteld voor elk AppDomain via het System.Net.ServicePointManager.SecurityProtocoleigendom.

  2. De standaardwaarde van deze eigenschap in .NET 4.5 is Ssl3 | Tls(hoewel ik geen documentatie kan vinden om dat te staven.) SecurityProtocolType is een opsomming met het kenmerk Flags, dus het is een bitsgewijze OFvan die twee waarden. U kunt dit in uw omgeving controleren met deze regel code:

    Console.WriteLine(System.Net.ServicePointManager.SecurityProtocol.ToString());

  3. Dit moet worden gewijzigd in alleen Tls, of misschien Tls12, voordat u verbindingen in uw app start:

    System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls;

  4. Belangrijk:aangezien de eigenschap meerdere bitsgewijze vlaggen ondersteunt, neem ik aan dat de SslStream nietautomatisch terugvalt naar andere niet-gespecificeerde protocollen tijdens handshake. Wat heeft het anders voor zin om meerdere vlaggen te ondersteunen?

Update op TLS 1.0 versus 1.1/1.2:

Volgens Google-beveiligingsexpert Adam Langley werd TLS 1.0 later kwetsbaar bevonden naar POODLE als het niet correct is geïmplementeerd, dus u kunt overwegen om uitsluitend naar TLS 1.2 te gaan.

Update voor .NET Framework 4.7 en hoger:

Zoals vermeld door Prof Von Lemongarglehieronder, is het vanaf versie 4.7 van het .NET Framework niet nodig om deze hack als standaardinstelling stelt het besturingssysteem in staat om de veiligste TLS-protocolversie te kiezen. Bekijk Best practices voor Transport Layer Security (TLS) met het .NET Frameworkvoor meer informatie.


Antwoord 1, autoriteit 100%

Wij doen hetzelfde. Om alleen TLS 1.2 en geen SSL-protocollen te ondersteunen, kunt u dit doen:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

SecurityProtocolType.Tls is alleen TLS 1.0, niet alle TLS-versies.

Tevens: als u wilt controleren of uw site geen SSL-verbindingen toestaat, kunt u dit hier doen (ik denk niet dat dit wordt beïnvloed door de bovenstaande instelling, we moesten het register bewerken om IIS te forceren om TLS te gebruiken voor inkomende verbindingen):
https://www.ssllabs.com/ssltest/index.html

Als u SSL 2.0 en 3.0 in IIS wilt uitschakelen, gaat u naar deze pagina: https://www.sslshopper.com/article-how-to-disable-ssl-2.0-in-iis-7.html


Antwoord 2, autoriteit 18%

@Eddie Loeffen’s antwoord lijkt het meest populaire antwoord op deze vraag, maar het heeft een aantal slechte langetermijneffecten. Als u de documentatiepagina voor System.Net.ServicePointManager.SecurityProtocol hierimpliceert de sectie Opmerkingen dat de onderhandelingsfase dit alleen moet aanpakken (en het forceren van het protocol is een slechte gewoonte omdat in de toekomst ook TLS 1.2 in gevaar zal komen). We zouden echter niet naar dit antwoord zoeken als dat zo was.

Uit onderzoek blijkt dat het ALPN-onderhandelingsprotocol nodig is om in de onderhandelingsfase naar TLS1.2 te gaan. We namen dat als uitgangspunt en probeerden nieuwere versies van het .Net-framework om te zien waar de ondersteuning begint. We hebben geconstateerd dat .Net 4.5.2 onderhandeling naar TLS 1.2 niet ondersteunt, maar .Net 4.6 wel.

Dus hoewel het forceren van TLS1.2 de klus nu zal klaren, raad ik u aan in plaats daarvan te upgraden naar .Net 4.6. Aangezien dit een PCI DSS-probleem is voor juni 2016, is het venster kort, maar het nieuwe raamwerk is een beter antwoord.

UPDATE:
Op basis van de opmerkingen heb ik dit gebouwd:

ServicePointManager.SecurityProtocol = 0;    
foreach (SecurityProtocolType protocol in SecurityProtocolType.GetValues(typeof(SecurityProtocolType)))
    {
        switch (protocol)
        {
            case SecurityProtocolType.Ssl3:
            case SecurityProtocolType.Tls:
            case SecurityProtocolType.Tls11:
                break;
            default:
                ServicePointManager.SecurityProtocol |= protocol;
            break;
        }
    }

Om het concept te valideren, heb ik SSL3 en TLS1.2 samengevoegd en de code uitgevoerd die gericht was op een server die alleen TLS 1.0 en TLS 1.2 ondersteunt (1.1 is uitgeschakeld). Met de or’d-protocollen lijkt het goed te verbinden. Als ik overstap naar SSL3 en TLS 1.1, kon ik geen verbinding maken. Mijn validatie gebruikt HttpWebRequest van System.Net en roept gewoon GetResponse() aan. Ik heb dit bijvoorbeeld geprobeerd en faalde:

       HttpWebRequest request = WebRequest.Create("https://www.contoso.com/my/web/resource") as HttpWebRequest;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11;
        request.GetResponse();

terwijl dit werkte:

       HttpWebRequest request = WebRequest.Create("https://www.contoso.com/my/web/resource") as HttpWebRequest;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12;
        request.GetResponse();

Dit heeft een voordeel ten opzichte van het forceren van TLS 1.2 doordat, als het .Net-framework wordt geüpgraded, zodat er meer items in de Enum zijn, deze worden ondersteund door de code zoals deze is. Het heeft een nadeel ten opzichte van het gebruik van .Net 4.6 in die zin dat 4.6 ALPN gebruikt en nieuwe protocollen zou moeten ondersteunen als er geen beperking is gespecificeerd.

Bewerk 29-4-2019 – Microsoft heeft dit artikel gepubliceerd afgelopen oktober. Het heeft een redelijk goede samenvatting van hun aanbeveling over hoe dit moet worden gedaan in de verschillende versies van het .net-framework.


Antwoord 3, autoriteit 5%

Ik moest het integer-equivalent casten om het feit te omzeilen dat ik nog steeds .NET 4.0 gebruik

System.Net.ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
/* Note the property type  
   [System.Flags]
   public enum SecurityProtocolType
   {
     Ssl3 = 48,
     Tls = 192,
     Tls11 = 768,
     Tls12 = 3072,
   } 
*/

Antwoord 4, autoriteit 4%

@watson

Op Windows-formulieren is het beschikbaar, zet bovenaan de klas

 static void Main(string[] args)
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
       //other stuff here
    }

aangezien Windows single-threaded is, is het alles wat je nodig hebt, in het geval dat het een service is, moet je deze direct boven de aanroep van de service plaatsen (omdat het niet te zeggen is in welke thread je zult zijn).

using System.Security.Principal 

is ook nodig.


Antwoord 5, autoriteit 4%

Als je benieuwd bent welke protocollen .NET ondersteunt, kun je HttpClient uitproberen op https://www.howsmyssl. com/

// set proxy if you need to
// WebRequest.DefaultWebProxy = new WebProxy("http://localhost:3128");
File.WriteAllText("howsmyssl-httpclient.html", new HttpClient().GetStringAsync("https://www.howsmyssl.com").Result);
// alternative using WebClient for older framework versions
// new WebClient().DownloadFile("https://www.howsmyssl.com/", "howsmyssl-webclient.html");

Het resultaat is vernietigend:

Uw cliënt gebruikt TLS 1.0, dat erg oud is, mogelijk vatbaar voor de BEAST-aanval en niet over de beste coderingssuites beschikt. Toevoegingen zoals AES-GCM en SHA256 ter vervanging van MD5-SHA-1 zijn niet beschikbaar voor een TLS 1.0-client en voor veel modernere coderingssuites.

Zoals Eddie hierboven uitlegt, kun je betere protocollen handmatig inschakelen:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11; 

Ik weet niet waarom het standaard slechte protocollen gebruikt. Dat lijkt een slechte setup-keuze, wat neerkomt op een grote beveiligingsfout (ik wed dat veel applicaties de standaard niet veranderen). Hoe kunnen we dit melden?


Antwoord 6

Ik ontdekte dat de eenvoudigste oplossing is om als volgt twee registervermeldingen toe te voegen (voer dit uit in een opdrachtprompt met beheerdersrechten):

reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:32
reg add HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 /v SchUseStrongCrypto /t REG_DWORD /d 1 /reg:64

Deze vermeldingen lijken van invloed te zijn op hoe de .NET CLR een protocol kiest bij het maken van een beveiligde verbinding als client.

Hier vindt u meer informatie over deze registervermelding:

https://docs.microsoft .com/en-us/security-updates/SecurityAdvisories/2015/2960358#suggested-actions

Dit is niet alleen eenvoudiger, maar ervan uitgaande dat het voor uw geval werkt, veel robuuster dan een op code gebaseerde oplossing, waarbij ontwikkelaars het protocol en de ontwikkeling moeten volgen en al hun relevante code moeten bijwerken. Hopelijk kunnen soortgelijke veranderingen in de omgeving worden aangebracht voor TLS 1.3 en hoger, zolang .NET dom genoeg blijft om niet automatisch het hoogst beschikbare protocol te kiezen.

OPMERKING: hoewel, volgens het bovenstaande artikel, dit alleen bedoeld is om RC4 uit te schakelen, en je zou niet denken dat dit zou veranderen of de .NET-client TLS1.2+ mag gebruiken of niet, om de een of andere reden heeft het dit effect.

OPMERKING: Zoals opgemerkt door @Jordan Rieger in de opmerkingen, is dit geen oplossing voor POODLE, omdat het de oudere protocollen niet uitschakelt— het is alleen stelt de klant in staat om met nieuwere protocollen te werken, bijv wanneer een gepatchte server de oudere protocollen heeft uitgeschakeld. Bij een MITM-aanval zal een gecompromitteerde server de client uiteraard een ouder protocol aanbieden, dat de client dan graag zal gebruiken.

TODO: probeer het gebruik van TLS1.0 en TLS1.1 aan de clientzijde uit te schakelen met deze registervermeldingen, maar ik weet niet of de .NET http-clientbibliotheken deze instellingen respecteren of niet :

https:/ /docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-10

https:/ /docs.microsoft.com/en-us/windows-server/security/tls/tls-registry-settings#tls-11

Other episodes