SSL geri dönüşü devre dışı bırakılsın ve .NET'te giden bağlantılar için yalnızca TLS kullanılsın mı? (Kaniş azaltma)


106

Poodle SSL 3.0 Fallback saldırısına karşı güvenlik açığımızı azaltmaya çalışıyorum . Yöneticilerimiz zaten sunucularımıza gelen bağlantılar için TLS lehine SSL'yi devre dışı bırakmaya başladı. Ayrıca ekibimize web tarayıcılarında SSL'yi devre dışı bırakmalarını tavsiye ettik. Şimdi System.Net.HttpWebRequest aracılığıyla çeşitli hizmetlerle HTTPS bağlantılarını başlatan .NET kod tabanımıza bakıyorum . TLS'den SSL'ye geri dönüşe izin verirlerse bu bağlantıların bir MITM saldırısına açık olabileceğine inanıyorum. İşte şimdiye kadar belirlediklerim. Birisi haklı olduğumu doğrulamak için lütfen bunu iki kez kontrol edebilir mi? Bu güvenlik açığı tamamen yenidir, bu nedenle .NET'te bu güvenlik açığının nasıl azaltılacağına dair Microsoft'tan henüz herhangi bir rehber görmedim:

  1. NET'te güvenli iletişimi destekleyen System.Net.Security.SslStream sınıfı için izin verilen protokoller, System.Net.ServicePointManager.SecurityProtocol özelliği aracılığıyla her AppDomain için global olarak ayarlanır .

  2. .NET 4.5 Bu özelliğin varsayılan değeridir Ssl3 | Tls(O kadar geri belgelerine bulamıyorum rağmen.) O bit tabanlı yüzden SecurityProtocolType, Bayraklar özelliği olan bir enum olan YA bu iki değerden. Bu kod satırıyla ortamınızda bunu kontrol edebilirsiniz:

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

  3. Bu , uygulamanızda herhangi bir bağlantı başlatmadan önce Tlsveya belki de olarak değiştirilmelidir Tls12:

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

  4. Önemli: özellik birden bitsel bayrakları desteklediği için, öyle sanıyorum ki SslStream olacak değil otomatik geri dönüş diğer belirtilmemiş protokollere el sıkışma sırasında. Aksi takdirde, birden çok bayrağı desteklemenin anlamı ne olur?

TLS 1.0 ve 1.1 / 1.2 ile ilgili güncelleme:

Google güvenlik uzmanı Adam Langley'e göre, TLS 1.0'ın daha sonra doğru şekilde uygulanmazsa POODLE'a karşı savunmasız olduğu tespit edildi , bu nedenle yalnızca TLS 1.2'ye geçmeyi düşünmelisiniz.

.NET Framework 4.7 ve üzeri için güncelleme:

Aşağıda Prof Von Lemongargle tarafından belirtildiği gibi, .NET Framework'ün 4.7 sürümünden başlayarak, varsayılan ayar işletim sisteminin en güvenli TLS protokol sürümünü seçmesine izin vereceği için bu hack'i kullanmaya gerek yoktur. Daha fazla bilgi için .NET Framework ile Taşıma Katmanı Güvenliği (TLS) en iyi uygulamalarına bakın .


1
Yukarıdaki 2. nokta ile ilgili olarak: referans kaynağı.microsoft.com/#System/net/System/Net/… SslProtocols "Varsayılan = Ssl3 | Tls"
Dai Bok

1
@Dai Bok Varsayılan artık SystemDefault
MarwaAhmad

@MarwaAhmad durum buysa, bağlantımdaki kaynak kodu referansı varsayılanı (48 | 192) yansıtmaz. Yok (0) olarak ayarlanırsa, sistem varsayılanına dönmelidir. Bu bana kokuyor ve muhtemelen yanlış yapılandırmaya yol açabileceğinden değişiklik yapmadan önce bunu test ederim ... ve yanlış .net çerçevesindeki protokolleri kapatır ...
Dai Bok

Yanıtlar:


137

Biz de aynı şeyi yapıyoruz. Yalnızca TLS 1.2'yi desteklemek ve hiçbir SSL protokolünü desteklemek için, bunu yapabilirsiniz:

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

SecurityProtocolType.Tls yalnızca TLS 1.0'dır, tüm TLS sürümleri değildir.

Taraf olarak: Sitenizin SSL bağlantılarına izin vermediğini kontrol etmek istiyorsanız, buradan yapabilirsiniz (Bunun yukarıdaki ayardan etkileneceğini sanmıyorum, IIS'yi TLS kullanmaya zorlamak için kayıt defterini düzenlememiz gerekti. gelen bağlantılar için): https://www.ssllabs.com/ssltest/index.html

IIS'de SSL 2.0 ve 3.0'ı devre dışı bırakmak için şu sayfaya bakın: https://www.sslshopper.com/article-how-to-disable-ssl-2.0-in-iis-7.html


Sağ. Yeni TLS sürümlerini de desteklemek için iyi bir fikir: geleceğe dönük.
Ürdün Rieger

1
Başkalarının yararına, bahsettiğiniz kayıt defteri düzenlemesi şu adımlarla da yapılabilir: serverfault.com/a/637263/98656 . Windows Server 2003 ila 2012 R2'de protokoller, HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ SecurityProviders \ Schannel \ Protocols konumundaki bayraklarla kontrol edilir. SSLv3'ü devre dışı bırakmak için, yukarıdaki konumda 'SSL 3.0' adlı bir alt anahtar ve bunun altında 'Sunucu' adlı bir alt anahtar ve bunun altında, 0 olarak ayarlanmış 'Etkin' adlı bir DWORD değeri oluşturun. SSL 2.0'ı da devre dışı bırakmalısınız. aynı şekilde.
Jordan Rieger

4
@ScotterMonkey Yalnızca .NET kodundan giden bağlantılar başlatıyorsanız , örneğin sunucunuzda çalışan özel koddan bir web hizmetine veya API'ye bağlanıyorsanız System.Net.ServicePointManager.SecurityProtocol'u ayarlamanız gerekir . Yalnızca basit bir web sitesi çalıştırıyorsanız ve yalnızca tarayıcılardan gelen bağlantıları kabul ediyorsanız , kayıt defteri düzeltmesi yeterlidir.
Jordan Rieger

7
Not: Görünür SecurityProtocolType.Tls11ve SecurityProtocolType.Tls12enum değerleri yalnızca ASP.net 4.5 ve üzeri sürümlerde mevcuttur. TLS 1.0 yol kenarında giderse 2.0'da çalışan eski kod tabanları için ne yapmamız gerektiğinden emin değilim.
Sam

1
@AnishV Bu kod satırını, giden SSL / TLS bağlantısını başlatan herhangi bir kodun önüne, uygulamanızın başlatılmasına koyarsınız.
Jordan Rieger

23

@Eddie Loeffen'in cevabı bu sorunun en popüler cevabı gibi görünüyor, ancak bazı kötü uzun vadeli etkileri var. System.Net.ServicePointManager.SecurityProtocol için dokümantasyon sayfasını gözden geçirirseniz buradaki açıklamalar bölümü, müzakere aşamasının yalnızca bunu ele alması gerektiğini ima eder (ve protokolü zorlamak kötü bir uygulamadır çünkü gelecekte TLS 1.2 de tehlikeye atılacaktır). Ancak, olsaydı bu yanıtı aramazdık.

Araştırma, ALPN görüşme protokolünün müzakere aşamasında TLS1.2'ye ulaşmak için gerekli olduğu anlaşılıyor. Bunu başlangıç ​​noktamız olarak aldık ve desteğin nerede başladığını görmek için .Net çerçevesinin daha yeni sürümlerini denedik. .Net 4.5.2'nin TLS 1.2'ye pazarlığı desteklemediğini, ancak .Net 4.6'nın desteklediğini gördük.

Dolayısıyla, TLS1.2'yi zorlamak işi şimdi halledecek olsa da, bunun yerine .Net 4.6'ya yükseltmenizi tavsiye ederim. Bu, Haziran 2016 için bir PCI DSS sorunu olduğundan, zaman aralığı kısadır, ancak yeni çerçeve daha iyi bir yanıttır.

GÜNCELLEME: Yorumlardan çalışarak şunu oluşturdum:

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;
        }
    }

Kavramı doğrulamak için, SSL3 ve TLS1.2'yi birlikte kullandım veya kullandım ve kodu yalnızca TLS 1.0 ve TLS 1.2'yi destekleyen bir sunucuyu hedefleyen çalıştırdım (1.1 devre dışı bırakıldı). Or'd protokolleriyle, iyi bağlanıyor gibi görünüyor. SSL3 ve TLS 1.1'e geçersem, bu bağlantı başarısız oldu. Doğrulam, System.Net'ten HttpWebRequest'i kullanıyor ve sadece GetResponse () 'yi çağırıyor. Örneğin, bunu denedim ve başarısız oldum:

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

bu işe yararken:

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

Bu, TLS 1.2'yi zorlamaktan daha avantajlıdır, çünkü .Net çerçevesi Enum'da daha fazla giriş olacak şekilde yükseltilirse, kod tarafından olduğu gibi desteklenecektir. Sadece .Net 4.6 kullanmaya göre bir dezavantajı vardır, 4.6 ALPN kullanır ve herhangi bir kısıtlama belirtilmemişse yeni protokolleri desteklemelidir.

Edit 4/29/2019 - Microsoft bu makaleyi geçen Ekim ayında yayınladı . .Net çerçevesinin çeşitli sürümlerinde bunun nasıl yapılması gerektiğine dair tavsiyelerinin oldukça iyi bir özeti var.


3
İlginç. Görünüşe göre dokümantasyon sayfası MSDN'nin ".NET Framework'e (mevcut sürüm) " taşınmasıyla birlikte güncellendi ve şimdi "bu özellik için kasıtlı olarak hiçbir varsayılan değerin listelenmediğini" açıklıyor. Belki de kabul edilen cevabın daha ileriye dönük bir versiyonu, yalnızca izin verilen protokollerin listesini almak için özelliği sorgulamak ve ardından, yalnızca açık bir şekilde eklemek yerine uygulamanızın güvenli olmadığını düşündüklerini (yani TLS 1.2'den daha azı) kaldırmak olacaktır. güvenli olduğunu düşündükleriniz. Bu, gelecekte yeni sürümleri hariç tutmaz.
Jordan Rieger

Programın, sistemin oluşturduğu bir listeden protokolleri kaldırmasını sağlamak iyi olurdu, ancak mevcut API'de bunu yapmanın bir yolunu göremiyorum. Tek seçenek belirli bir protokolü zorlamak gibi görünüyor, ki kimsenin neden yapmak istediğini anlamıyorum. Ne yazık ki, ALPN desteği olmadan, çalışmak için bir TLS1.2 bağlantısı elde etmenin tek yolu bu gibi görünüyor.
Prof Von Lemongargle

1
Tüm SecurityProtocolType numaralandırmalarında döngü yapmak, ServicePointManager.SecurityProtocol bayrak numaralarında hangilerinin bulunduğunu görmek mümkün olmalıdır (bu, tüm işaretlerin mantıksal VEYA'sıdır, böylece her birini bir AND ile test edebilirsiniz) ve ardından yeni bir kaldırılmasını istemediklerinizin listesi. Ardından bunları tek bir numaralandırmada birleştirin ve özelliği bununla ayarlayın.
Jordan Rieger

Numaralandırma / döngü kodunu yeniden okuyordum ve bunun yanlış olduğunu düşünüyorum. | = Mantıksal operatörü, yalnızca Tls12 ve üstünü dahil etmek yerine özellikte başlangıçta ayarlanmış varsayılan değerleri içeren özellik ile sonuçlanır. Düzeltmek için, 0 değeriyle bir SecurityProtocolType enum değişkenini başlatmanız, bu değişkene karşı | = döngüsünü yapmanız ve ardından bunu ServicePointManager.SecurityProtocol özelliğine atamanız gerekir.
Jordan Rieger

7
.NET'in yapabildiği en yüksek protokol sürümüyle otomatik olarak pazarlık etmemesini başka biri çılgınca buluyor mu ?!
Raman

5

@yavbirah

Windows formlarında, sınıfın en üstünde bulunur

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

pencereler tek iş parçacıklı olduğundan, ihtiyacınız olan tek şey, bir hizmet olması durumunda, onu hizmet çağrısının hemen üstüne koymanız gerekir (çünkü hangi iş parçacığını kullanacağınızı bilmiyorsunuz).

using System.Security.Principal 

ayrıca gereklidir.


5

NET'in hangi protokolleri desteklediğini merak ediyorsanız, HttpClient'i https://www.howsmyssl.com/ adresinde deneyebilirsiniz.

// 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");

Sonuç kahredici:

Müşteriniz çok eski olan, muhtemelen BEAST saldırısına duyarlı olan ve üzerinde mevcut en iyi şifre paketlerine sahip olmayan TLS 1.0 kullanıyor. MD5-SHA-1'in yerini alacak AES-GCM ve SHA256 gibi eklemeler, bir TLS 1.0 istemcisinin yanı sıra daha birçok modern şifre paketi için kullanılamaz.

Eddie'nin yukarıda açıkladığı gibi, daha iyi protokolleri manuel olarak etkinleştirebilirsiniz:

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

Kutudan çıkar çıkmaz kötü protokolleri neden kullandığını bilmiyorum. Bu, kötü bir kurulum seçeneği gibi görünüyor, büyük bir güvenlik hatasıyla eşdeğer (bahse girerim pek çok uygulama varsayılanı değiştirmez). Nasıl rapor edebiliriz?


5

Hala .NET 4.0 kullandığım gerçeğini aşmak için tamsayı eşdeğerini çevirmek zorunda kaldım

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

Bu çalışır, ancak .NET 4.0 TLS 1.2'yi desteklemez, ancak .NET 4.5 ve üstü TLS 1.2'yi destekler. Bu nedenle, .NET 4.0 uygulamanıza bu kodu ekleyebilir (veya TLS 1.2 anlaşması için destek eklemek için bit düzeyinde OR ekleyebilir) ve onu oluşturabilirsiniz, ancak kodu .NET 4.5 veya daha yüksek bir sürümde dağıtmanız gerekir. blogs.perficient.com/microsoft/2016/04/tsl-1-2-and-net-support
rboy

Ayrıca buna bakın, .NET 4.0 kodu .NET 4.5 ve .NET 4.6 stackoverflow.com/questions/33378902/…
rboy

Tam sayı atama, TLS 1.2'yi göndermek için çalıştı. Tls12 enum değeri. NET 4.0'da mevcut değil
CZahrobsky

İki farklı nokta. Yorumuma bakın. Değeri girebilirsiniz, ancak çalışma zamanı Net sürümünüz 4.0 ise başarısız olur. Bu bayrakla derleyebilirsiniz, ancak .NET
4.0'daki

2
TLS 1.2 desteği eklemek için eski .NET çalışma zamanı sürümleri için birkaç düzeltme vardır. Örneğin, support.microsoft.com/en-us/help/3154518/… , CZahrobsky, düzeltmeyi de içeren Win10 sonbahar yaratıcıları güncellemesinde bunu kullanıyor olabilirdi.
sessiz ton

1

En basit çözümün aşağıdaki gibi iki kayıt defteri girişi eklemek olduğunu buldum (bunu yönetici ayrıcalıklarına sahip bir komut isteminde çalıştırın):

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

Bu girdiler, istemci olarak güvenli bir bağlantı kurarken .NET CLR'nin bir protokolü nasıl seçtiğini etkiliyor gibi görünmektedir.

Bu kayıt defteri girdisi hakkında daha fazla bilgiyi burada bulabilirsiniz:

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

Bu sadece daha basit değil, aynı zamanda sizin durumunuz için çalıştığını varsayarsak, geliştiricilerin protokolü ve geliştirmeyi izlemesini ve ilgili tüm kodlarını güncellemesini gerektiren kod tabanlı bir çözümden çok daha sağlamdır. Umarım, .NET mevcut en yüksek protokolü otomatik olarak seçmeyecek kadar aptal kaldığı sürece TLS 1.3 ve sonrası için benzer ortam değişiklikleri yapılabilir.

NOT : Yukarıdaki makaleye göre, bunun yalnızca RC4'ü devre dışı bırakması gerekse de, .NET istemcisinin TLS1.2 + kullanmasına izin verilip verilmeyeceğinin değişeceğini düşünmemekle birlikte, bazı nedenlerden dolayı buna sahiptir. etki.

NOT : @ Jordan Rieger tarafından yorumlarda belirtildiği gibi, devre dışı bırakmadığı için bu POODLE için bir çözüm değildir. eski protokolleri a - yalnızca istemcinin daha yeni protokollerle çalışmasına izin verir, örneğin yamalı bir sunucu bıraktığında protokoller. Bununla birlikte, bir MITM saldırısıyla, açık bir şekilde, güvenliği ihlal edilmiş bir sunucu istemciye, istemcinin mutlu bir şekilde kullanacağı daha eski bir protokol sunacaktır.

TODO : Bu kayıt defteri girdileriyle TLS1.0 ve TLS1.1'in istemci tarafı kullanımını devre dışı bırakmayı deneyin, ancak .NET http istemci kitaplıklarının bu ayarlara uyup uymadığını bilmiyorum:

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


Bir koda alternatif olarak kayıt defteri ayarları harika olurdu, ancak bu ayarlar aslında TLS 1.0 ve 1.1'i yalnızca TLS 1.2 ve üzeri kullanan istemci bağlantılarına izin vermek için devre dışı mı bırakıyor? Bağlantıya göre, TLS'de yalnızca RC4'ü devre dışı bırakıyor gibi görünüyor. Kaniş saldırısının bundan daha geniş olduğunu düşünüyorum.
Jordan Rieger

@JordanRieger Bu kayıt defteri girdileri, bir .NET istemcisinin POODLE'ı azaltmak için eski protokolleri devre dışı bırakılan bir sunucuya bağlanmasına izin verir. Bunlar olmadan, sunucu daha yeni bir protokol istese bile .NET istemcisi aptalca eski bir protokolü kullanmakta ısrar ettiğinden istemci bir hata atar. Sunucunuz hala eski protokolleri kullanan bağlantılara izin veriyorsa tüm bahisler kapalıdır. Teorik olarak eski protokolleri olmalıdır devre dışı. Bunların sunucuda devre dışı bırakılmasına izin veren aynı kayıt defteri girişlerinin (örn. Nartac.com/Products/IISCrypto ) istemci için de işe yarayıp yaramayacağını merak ediyorum.
Raman

Nartac'ın işlediği kayıt defteri girişlerinde, istemci ve (olarak davranırken) sunucu için (olarak hareket ederken) ayrı ayarlar vardır. Ancak arayüzlerinin ayırt edip etmediğini hatırlamıyorum. .Net'in hangi sürümlerinin bu kayıt defteri hackini desteklediğini biliyor musunuz?
Prof Von Lemongargle

@Raman sorumun amacı, istemciniz kontrol etmediğiniz bir sunucuya bağlanırken POODLE güvenlik açığını azaltmaktı. Güvenlik açığı, bir MITM saldırganının protokolü saldırıya uğrayabilecek daha eski bir TLS veya SSL sürümüne düşürmesine izin verecektir. Sadece RC4'ü devre dışı bırakmak yeterli değildir. Bu kayıt defteri ayarları belirli durumlarda yararlı olabilir, ancak sorumdaki senaryo için uygun olmayabilir.
Jordan Rieger

1
@JordanRieger Kabul edildi. Metni bazı ek gözlemler ve düşüncelerle güncelledim.
Raman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.