[.net] SSL 폴백을 비활성화하고 .NET의 아웃 바운드 연결에 TLS 만 사용 하시겠습니까? (푸들 완화)

Poodle SSL 3.0 Fallback 공격에 대한 취약성을 완화하려고합니다 . 관리자는 이미 서버에 대한 인바운드 연결을 위해 TLS를 위해 SSL을 비활성화하기 시작했습니다. 그리고 우리 팀은 웹 브라우저에서 SSL을 비활성화하도록 조언했습니다. 이제 System.Net.HttpWebRequest를 통해 다양한 서비스와 HTTPS 연결을 시작하는 .NET 코드베이스를 살펴보고 있습니다. 이러한 연결이 TLS에서 SSL 로의 대체를 허용하는 경우 MITM 공격에 취약 할 수 있다고 생각합니다. 지금까지 제가 결정한 내용입니다. 누군가 내가 옳다는 것을 확인하기 위해 이것을 다시 확인해 주시겠습니까? 이 취약점은 완전히 새로운 것이므로 .NET에서 취약점을 완화하는 방법에 대한 Microsoft의 지침을 아직 보지 못했습니다.

  1. .NET의 보안 통신을 뒷받침하는 System.Net.Security.SslStream 클래스에 대해 허용되는 프로토콜은 System.Net.ServicePointManager.SecurityProtocol 속성을 통해 각 AppDomain에 대해 전역 적으로 설정 됩니다.

  2. .NET 4.5에서이 속성의 기본값은 Ssl3 | Tls(백업 할 문서를 찾을 수는 없지만)입니다. SecurityProtocolType은 Flags 속성이있는 열거 형이므로이 두 값 의 비트 단위 OR 입니다. 다음 코드 줄을 사용하여 환경에서이를 확인할 수 있습니다.

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

  3. 이것은 단지로 변경해야합니다 Tls아마, 또는 Tls12앱의 모든 연결을 시작하기 전에 :

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

  4. 중요 : 이 속성은 여러 비트 플래그를 지원하기 때문에 SslStream이 핸드 셰이크 중에 지정되지 않은 다른 프로토콜로 자동으로 폴백 되지 않는다고 가정합니다 . 그렇지 않으면 여러 플래그를 지원하는 요점이 무엇입니까?

TLS 1.0 대 1.1 / 1.2 업데이트 :

Google 보안 전문가 Adam Langley에 따르면 TLS 1.0은 올바르게 구현되지 않으면 나중에 POODLE에 취약한 것으로 밝혀 졌으므로 TLS 1.2로만 전환하는 것을 고려해야합니다.

.NET Framework 4.7 이상용 업데이트 :

아래 Prof Von Lemongargle이 언급했듯이 .NET Framework 4.7 버전부터는 기본 설정으로 OS가 가장 안전한 TLS 프로토콜 버전을 선택할 수 있으므로이 해킹을 사용할 필요가 없습니다. 자세한 내용 은 .NET Framework사용한 TLS (전송 계층 보안) 모범 사례 를 참조하세요.



답변

우리는 같은 일을하고 있습니다. TLS 1.2 만 지원하고 SSL 프로토콜은 지원하지 않으려면 다음을 수행하십시오.

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

SecurityProtocolType.Tls는 모든 TLS 버전이 아닌 TLS 1.0입니다.

측면 : 사이트에서 SSL 연결을 허용하지 않는지 확인하려면 여기에서 할 수 있습니다 (위 설정의 영향을받지 않는다고 생각하므로 IIS에서 TLS를 사용하도록 레지스트리를 편집해야했습니다. 들어오는 연결의 경우) :
https://www.ssllabs.com/ssltest/index.html

IIS에서 SSL 2.0 및 3.0을 비활성화하려면 다음 페이지를 참조하십시오. https://www.sslshopper.com/article-how-to-disable-ssl-2.0-in-iis-7.html


답변

@Eddie Loeffen의 답변이이 질문에 대한 가장 인기있는 답변 인 것 같지만 장기적으로 나쁜 영향을 미칩니다. 여기서 System.Net.ServicePointManager.SecurityProtocol에 대한 설명서 페이지를 검토하는 경우 비고 섹션은 협상 단계에서이 문제를 해결해야 함을 의미합니다 (향후 TLS 1.2도 손상 될 것이기 때문에 프로토콜을 강제하는 것은 좋지 않습니다). 그러나 만약 그렇다면 우리는이 대답을 찾지 않을 것입니다.

조사 결과 협상 단계에서 TLS1.2에 도달하려면 ALPN 협상 프로토콜이 필요한 것으로 보입니다. 이를 시작점으로 삼아 지원이 시작되는 위치를 확인하기 위해 .Net 프레임 워크의 최신 버전을 시도했습니다. .Net 4.5.2는 TLS 1.2에 대한 협상을 지원하지 않지만 .Net 4.6은 지원합니다.

따라서 TLS1.2를 강제 적용하면 이제 작업이 완료되지만 대신 .Net 4.6으로 업그레이드하는 것이 좋습니다. 이것은 2016 년 6 월 PCI DSS 문제이므로 기간은 짧지 만 새로운 프레임 워크가 더 나은 답입니다.

업데이트 : 주석에서 일하면서 이것을 만들었습니다.

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

개념의 유효성을 검사하기 위해 SSL3과 TLS1.2를 함께 사용하고 TLS 1.0 및 TLS 1.2 만 지원하는 서버를 대상으로 코드를 실행했습니다 (1.1은 비활성화 됨). or’d 프로토콜을 사용하면 제대로 연결되는 것 같습니다. SSL3 및 TLS 1.1로 변경하면 연결에 실패했습니다. 내 유효성 검사는 System.Net의 HttpWebRequest를 사용하고 GetResponse ()를 호출합니다. 예를 들어, 나는 이것을 시도했지만 실패했습니다.

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

이것이 작동하는 동안 :

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

이것은 Enum에 더 많은 항목이 있도록 .Net 프레임 워크가 업그레이드되면 코드에서 그대로 지원된다는 점에서 TLS 1.2를 강제하는 것보다 이점이 있습니다. 4.6은 ALPN을 사용하고 제한이 지정되지 않은 경우 새 프로토콜을 지원해야한다는 점에서 .Net 4.6을 사용하는 것보다 단점이 있습니다.

2019 년 4 월 29 일 편집-Microsoft는 지난 10 월 이 기사를 게시 했습니다 . 다양한 버전의 .net 프레임 워크에서이 작업을 수행하는 방법에 대한 권장 사항에 대한 꽤 좋은 개요가 있습니다.


답변

왓슨

Windows 양식에서 사용할 수 있습니다.

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

창은 단일 스레드이기 때문에 서비스가있는 경우 서비스에 대한 호출 바로 위에 배치해야합니다 (어떤 스레드에 있을지 알 수 없기 때문에).

using System.Security.Principal 

또한 필요합니다.


답변

.NET이 지원하는 프로토콜이 궁금하다면 https://www.howsmyssl.com/에서 HttpClient를 사용해 볼 수 있습니다.

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

그 결과는 다음과 같습니다.

클라이언트가 TLS 1.0을 사용하고 있습니다. TLS 1.0은 매우 오래되어 BEAST 공격에 취약 할 수 있으며 사용할 수있는 최상의 암호 그룹이 없습니다. MD5-SHA-1을 대체하기위한 AES-GCM 및 SHA256과 같은 추가 기능은 TLS 1.0 클라이언트와 더 많은 최신 암호 제품군에서 사용할 수 없습니다.

Eddie가 위에서 설명했듯이 더 나은 프로토콜을 수동으로 활성화 할 수 있습니다.

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

왜 그것이 바로 잘못된 프로토콜을 사용하는지 모르겠습니다. 그것은 잘못된 설정 선택으로 보이며 주요 보안 버그에 해당합니다 (많은 응용 프로그램이 기본값을 변경하지 않을 것입니다). 어떻게 신고 할 수 있습니까?


답변

여전히 .NET 4.0을 사용하고 있다는 사실을 피하기 위해 정수를 캐스팅해야했습니다.

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


답변

가장 간단한 해결책은 다음과 같이 두 개의 레지스트리 항목을 추가하는 것입니다 (관리자 권한으로 명령 프롬프트에서 실행).

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

이러한 항목은 클라이언트로 보안 연결을 만들 때 .NET CLR이 프로토콜을 선택하는 방법에 영향을 미치는 것 같습니다.

이 레지스트리 항목에 대한 자세한 정보는 다음과 같습니다.

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

이것은 더 간단 할뿐만 아니라 귀하의 경우에 작동한다고 가정하면 개발자가 프로토콜 및 개발을 추적하고 모든 관련 코드를 업데이트해야하는 코드 기반 솔루션보다 훨씬 강력합니다. .NET이 사용 가능한 가장 높은 프로토콜을 자동으로 선택하지 않을만큼 멍청한 상태로 유지되는 한 TLS 1.3 이상에 대해 유사한 환경 변경이 이루어질 수 있기를 바랍니다.

참고 : 위의 기사에 따르면 이것은 RC4를 비활성화하는 것으로 간주되며 .NET 클라이언트가 TLS1.2 +를 사용할 수 있는지 여부를 변경하지 않을 것이라고 생각할 수 있습니다. 효과.

참고 : 주석에서 @Jordan Rieger가 언급했듯이 이것은 이전 프로토콜을 비활성화 하지 않기 때문에 POODLE에 대한 해결책이 아닙니다. 예를 들어 패치 된 서버가 이전 프로토콜을 비활성화 한 경우 클라이언트가 최신 프로토콜로 작업 할 수 있습니다. 프로토콜. 그러나 MITM 공격의 경우 분명히 손상된 서버는 클라이언트에게 이전 프로토콜을 제공하고 클라이언트가 즐겁게 사용할 것입니다.

TODO : 이러한 레지스트리 항목으로 TLS1.0 및 TLS1.1의 클라이언트 측 사용을 비활성화하십시오. 그러나 .NET http 클라이언트 라이브러리가 이러한 설정을 준수하는지 여부는 알 수 없습니다.

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


답변