.net - tls中间人攻击




如何在.NET中禁用SSL回退并仅使用TLS进行出站连接?(贵宾犬缓解) (4)

我正试图减轻我们对Poodle SSL 3.0 Fallback攻击的脆弱性。 我们的管理员已经开始禁用SSL,转而使用TLS来连接到我们的服务器。 我们还建议我们的团队在其Web浏览器中禁用SSL。 我现在正在查看我们的.NET代码库,它通过System.Net.HttpWebRequest启动与各种服务的HTTPS连接。 如果他们允许从TLS到SSL的回退,我相信这些连接可能容易受到MITM攻击。 这是我迄今为止确定的。 有人可以仔细检查一下,以证实我是对的吗? 这个漏洞是全新的,所以我还没有看到任何关于如何在.NET中缓解它的指导。

  1. System.Net.Security.SslStream类的支持协议(支持.NET中的安全通信)通过System.Net.ServicePointManager.SecurityProtocol属性为每个AppDomain全局设置。

  2. 这个属性在.NET 4.5中的默认值是Ssl3 | Tls Ssl3 | Tls (虽然我找不到文档来支持它)。SecurityProtocolType是一个带Flags属性的枚举,所以它是这两个值的OR值。 您可以使用以下这行代码在您的环境中检查:

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

  3. 在您的应用程序中启动任何连接之前,应将此更改为TlsTls12

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

  4. 重要提示:由于该属性支持多个按位标志,因此我认为SslStream在握手期间不会自动回退到其他未指定的协议。 否则,支持多个标志的意义何在?

TLS 1.0 vs 1.1 / 1.2更新:

根据谷歌安全专家亚当兰利的说法, 后来发现TLS 1.0如果执行不正确很容易受到POODLE的攻击 ,所以你应该考虑专门转向TLS 1.2。


@埃迪洛芬的答案似乎是这个问题最受欢迎的答案,但它有一些不好的长期影响。 如果您在here查看System.Net.ServicePointManager.SecurityProtocol的文档页面,则注释部分意味着谈判阶段应该只是解决这个问题(并且强制该协议是不好的做法,因为将来TLS 1.2也会受到影响)。 但是,如果确实如此,我们不会寻找这个答案。

研究表明,协商阶段需要ALPN协商协议才能达到TLS1.2。 我们以此为出发点,尝试使用.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();

与强制使用TLS 1.2相比,这具有优势,如果.Net框架已升级,以便Enum中有更多条目,则代码将按原样支持它们。 它比使用.Net 4.6有一个缺点,那就是4.6使用ALPN,如果没有指定限制,应该支持新的协议。


@沃森

在窗体上它是可用的,在类的顶部放

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

因为windows是单线程的,所有你需要的,如果你需要把它放在服务调用的上面(因为没有告诉你将会在哪个线程上)。

using System.Security.Principal 

也是需要的。


我不得不投入相当于整数的整数来解决我仍在使用.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,
   } 
*/

我们也在做同样的事情。 要仅支持TLS 1.2并且不支持SSL协议,您可以这样做:

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

SecurityProtocolType.Tls只是TLS 1.0,不是所有的TLS版本。

作为一个方面:如果你想检查你的网站不允许SSL连接,你可以在这里做(我认为这不会受到上述设置的影响,我们必须编辑注册表来强制IIS使用TLS对于传入连接): https://www.ssllabs.com/ssltest/index.htmlhttps://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.htmlhttps://www.sslshopper.com/article-how-to-disable-ssl-2.0-in-iis-7.html





ssl