OpenSSL再曝CCS注入漏洞-心伤未愈又成筛子
生活随笔
收集整理的這篇文章主要介紹了
OpenSSL再曝CCS注入漏洞-心伤未愈又成筛子
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
太戲劇了,昨晚看了佳片有約,還不錯,2012版的《完美回顧》,像我這樣的人依舊選擇用電視或者去影院看電影,在沒有中間插播廣告的時候,體驗憋尿得過程中,總是能突然有非常多的想法,這是用電腦或者手機看電影所體會不到的。看完以后已經(jīng)12點半了,突然想再看一遍《黑客帝國》,這下不用電腦不行了,因為電視上沒得播...結(jié)果正在緩沖的時候,突然看到了旁邊的小公告:“OpenSSL再爆嚴重安全漏洞--CCS注入”,完了,電影看不成了,不是說不想看了,突然感覺自己比神還無恥,怎么人家曝出漏洞會這么高興啊,關(guān)掉已經(jīng)緩沖完畢的電影,就想看一下OpenSSL的笑話,同一時候心里還極度扭曲地想,我不近期在搞基于OpenSSL的一個改動么,向OpenSSL這樣的代碼,就我這樣的垃圾coder配得上它,因為我的垃圾代碼和它非常般配...
?????? 當我看了一篇博客《How I discovered CCS Injection Vulnerability (CVE-2014-0224)》后,我認為我錯怪OpenSSL了,這次或許真的不是OpenSSL的錯,而是RFC的錯,即這次的這個漏洞不是實現(xiàn)問題,很多其它的是協(xié)議本身的設(shè)計問題。假設(shè)你還沒有讀過上面我提到的那篇博客,一定要看一下,假設(shè)看過了,我們就接著往下走,看看這個漏洞的一些細節(jié)。
?????? 我們知道,OpenSSL協(xié)議分了兩個層次,一個是記錄協(xié)議層,一個是數(shù)據(jù)協(xié)議層,后者包括了握手協(xié)議,告警協(xié)議,CCS協(xié)議等,注意這個“等”字,搞知道國密標準的應(yīng)該知道這個等字的含義,不知道國密標準的人奉勸永遠都不要知道,這次的CCS漏洞本質(zhì)上就和這個“等”字有關(guān)。言歸正傳,SSL/TLS的安全通道通過握手協(xié)議建立,安全通道上通行的數(shù)據(jù)顯然是加密的,而在握手過程中,在密鑰等安全參數(shù)沒有協(xié)商完畢之前,數(shù)據(jù)都是明文的,那么在握手狀態(tài)機中就肯定有那么一個點,在該點之前數(shù)據(jù)是明文的,而在該點之后數(shù)據(jù)是加密的,這個點就是接收到ChangeCipherSpec消息,問題是,這個消息在握手狀態(tài)機中交換,可是卻不在握手協(xié)議中定義,它被定義為一個單獨的協(xié)議,不屬于握手協(xié)議。這樣做的理由,依照漏洞發(fā)現(xiàn)者Masashi Kikuchi在RFC挖掘出的理由那就是:
Note:????????? To help avoid pipeline stalls, ChangeCipherSpec is
???????????????? an independent SSL Protocol content type, and is not
???????????????? actually an SSL handshake message.
這是一個什么理由?顯然沒有考慮安全因素。那么問題就來了,既然CCS獨立于握手狀態(tài)機,那么它便能夠在握手過程中的不論什么一點收發(fā),在協(xié)議層面并沒有強制CCS必需要在master keys在握手協(xié)議中已經(jīng)完備的情況下才干發(fā)送,假設(shè)那樣強制,就是兩個協(xié)議之間的交疊。其實,依照規(guī)范而言,SSL/TLS的握手中,CCS的位置是被嚴格規(guī)定的,即master keys準備好之后,Finish消息之前,那么安全機制就必須由實現(xiàn)者自己負責(zé)。稍有不慎,關(guān)于握手協(xié)議和CCS之間的關(guān)系就會處理不好造成能夠利用的漏洞。在一篇文章《Early ChangeCipherSpec Attack 》中,作者披露了OpenSSL1.0.1h是怎樣解決問題的,實際上加了不多的幾行代碼,當中之中的一個就是ssl3_do_change_cipher_spec函數(shù)中的一個推斷:
if (s->session == NULL || s->session->master_key_length == 0){/* might happen if dtls1_read_bytes() calls this */SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);return (0);}
在之前的漏洞影響的版本號中,并沒有確認master_key_length不為0,這就意味著即便master key還沒有準備好,也是能夠發(fā)送CCS的,而這樣的話,所謂的密鑰也沒有秘密可言了。CCS的發(fā)送時間并沒有強制要求,可是要求master keys必須準備好!以下是一個基于中間人攻擊的漏洞利用場景,中間人在作為server的時候,在ServerHelloDone完畢后即發(fā)送一個CCS,注意此時還沒有生成master keys,因此使用一個空值取代,因為OpenSSL在收到CCS的時候并沒有檢查自己的握手狀態(tài)機處于哪一步驟,因此會無條件接收,此時它也沒有master key,后面的事情就是使用不是密鑰的密鑰對數(shù)據(jù)進行加密,注意,因為OpenSSL的實現(xiàn)原因,僅僅要已經(jīng)經(jīng)過了key的計算,在一個session中以后就不會再次計算,因此以下的代碼(相同處于ssl3_do_change_cipher_spec中)其實助長了漏洞:
if (s->s3->tmp.key_block == NULL){if (s->session == NULL){/* might happen if dtls1_read_bytes() calls this */SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);return (0);}s->session->cipher=s->s3->tmp.new_cipher;if (!s->method->ssl3_enc->setup_key_block(s)) return(0);}
??? 關(guān)于SSL/TLS規(guī)范中將CCS設(shè)計成獨立的一個數(shù)據(jù)協(xié)議,我在《TCP/IP協(xié)議族》這本經(jīng)典教材中找到了更真切的理由,那就是它將發(fā)送方和接收方切割成了兩個狀態(tài),依照分權(quán)原則,這個事不能在握手協(xié)議本身完畢。
??? 漏洞發(fā)現(xiàn)者Masashi Kikuchi所述,僅僅要保證幾點就可以,非常easy:
IMHO, this sentence is the very cause of the vulnerability. According to it, the reason that CCS is assigned an independent record type is to avoid a stall. This is the point where the most complex synchronization is required in TLS/SSL handshake. First, you need to wait until the handshake proceeds to the proper phase. Then, you need to check whether the handshake receives CCS before Finish.
More precisely, when accepting CCS, you must verify the following three conditions (*):
??? the handshake proceeds to the proper phase, i.e., just before to receive Finished,
??? no fragments from the handshake remains,
??? and, the next message is Finished.
Being more careful, you should also check
??? no Alert fragment remains (they can be rejected in the first place),
??? and, no Heartbeat fragment remains
事實非常easy,保證CCS發(fā)送的時候,master keys真的已經(jīng)準備好了,這實際上就是CCS本身的意思,假設(shè)我能跟我的三歲的小小講清楚這個,她肯定會說她的口頭禪:難道不是嗎?
?????? 一個獨立的CCS協(xié)議,獨立于握手協(xié)議的CCS協(xié)議,在SSL/TLS中必定不可能是全然獨立的,協(xié)議封裝上是獨立的,語義卻不可能是獨立的,否則,我在ClientHello后發(fā)送一個CCS,可否?唉,心病還未痊愈,CCS又來搗亂,假設(shè)說心臟出血是OpenSSL的問題的話(它實際上是一個低級的代碼級錯誤),CCS漏洞則是一個協(xié)議層面的問題,這個問題可不低級!我相信不止OpenSSL的實現(xiàn)會有這個問題。
?????? 當我看了一篇博客《How I discovered CCS Injection Vulnerability (CVE-2014-0224)》后,我認為我錯怪OpenSSL了,這次或許真的不是OpenSSL的錯,而是RFC的錯,即這次的這個漏洞不是實現(xiàn)問題,很多其它的是協(xié)議本身的設(shè)計問題。假設(shè)你還沒有讀過上面我提到的那篇博客,一定要看一下,假設(shè)看過了,我們就接著往下走,看看這個漏洞的一些細節(jié)。
?????? 我們知道,OpenSSL協(xié)議分了兩個層次,一個是記錄協(xié)議層,一個是數(shù)據(jù)協(xié)議層,后者包括了握手協(xié)議,告警協(xié)議,CCS協(xié)議等,注意這個“等”字,搞知道國密標準的應(yīng)該知道這個等字的含義,不知道國密標準的人奉勸永遠都不要知道,這次的CCS漏洞本質(zhì)上就和這個“等”字有關(guān)。言歸正傳,SSL/TLS的安全通道通過握手協(xié)議建立,安全通道上通行的數(shù)據(jù)顯然是加密的,而在握手過程中,在密鑰等安全參數(shù)沒有協(xié)商完畢之前,數(shù)據(jù)都是明文的,那么在握手狀態(tài)機中就肯定有那么一個點,在該點之前數(shù)據(jù)是明文的,而在該點之后數(shù)據(jù)是加密的,這個點就是接收到ChangeCipherSpec消息,問題是,這個消息在握手狀態(tài)機中交換,可是卻不在握手協(xié)議中定義,它被定義為一個單獨的協(xié)議,不屬于握手協(xié)議。這樣做的理由,依照漏洞發(fā)現(xiàn)者Masashi Kikuchi在RFC挖掘出的理由那就是:
Note:????????? To help avoid pipeline stalls, ChangeCipherSpec is
???????????????? an independent SSL Protocol content type, and is not
???????????????? actually an SSL handshake message.
這是一個什么理由?顯然沒有考慮安全因素。那么問題就來了,既然CCS獨立于握手狀態(tài)機,那么它便能夠在握手過程中的不論什么一點收發(fā),在協(xié)議層面并沒有強制CCS必需要在master keys在握手協(xié)議中已經(jīng)完備的情況下才干發(fā)送,假設(shè)那樣強制,就是兩個協(xié)議之間的交疊。其實,依照規(guī)范而言,SSL/TLS的握手中,CCS的位置是被嚴格規(guī)定的,即master keys準備好之后,Finish消息之前,那么安全機制就必須由實現(xiàn)者自己負責(zé)。稍有不慎,關(guān)于握手協(xié)議和CCS之間的關(guān)系就會處理不好造成能夠利用的漏洞。在一篇文章《Early ChangeCipherSpec Attack 》中,作者披露了OpenSSL1.0.1h是怎樣解決問題的,實際上加了不多的幾行代碼,當中之中的一個就是ssl3_do_change_cipher_spec函數(shù)中的一個推斷:
if (s->session == NULL || s->session->master_key_length == 0){/* might happen if dtls1_read_bytes() calls this */SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);return (0);}
在之前的漏洞影響的版本號中,并沒有確認master_key_length不為0,這就意味著即便master key還沒有準備好,也是能夠發(fā)送CCS的,而這樣的話,所謂的密鑰也沒有秘密可言了。CCS的發(fā)送時間并沒有強制要求,可是要求master keys必須準備好!以下是一個基于中間人攻擊的漏洞利用場景,中間人在作為server的時候,在ServerHelloDone完畢后即發(fā)送一個CCS,注意此時還沒有生成master keys,因此使用一個空值取代,因為OpenSSL在收到CCS的時候并沒有檢查自己的握手狀態(tài)機處于哪一步驟,因此會無條件接收,此時它也沒有master key,后面的事情就是使用不是密鑰的密鑰對數(shù)據(jù)進行加密,注意,因為OpenSSL的實現(xiàn)原因,僅僅要已經(jīng)經(jīng)過了key的計算,在一個session中以后就不會再次計算,因此以下的代碼(相同處于ssl3_do_change_cipher_spec中)其實助長了漏洞:
if (s->s3->tmp.key_block == NULL){if (s->session == NULL){/* might happen if dtls1_read_bytes() calls this */SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);return (0);}s->session->cipher=s->s3->tmp.new_cipher;if (!s->method->ssl3_enc->setup_key_block(s)) return(0);}
??? 關(guān)于SSL/TLS規(guī)范中將CCS設(shè)計成獨立的一個數(shù)據(jù)協(xié)議,我在《TCP/IP協(xié)議族》這本經(jīng)典教材中找到了更真切的理由,那就是它將發(fā)送方和接收方切割成了兩個狀態(tài),依照分權(quán)原則,這個事不能在握手協(xié)議本身完畢。
??? 漏洞發(fā)現(xiàn)者Masashi Kikuchi所述,僅僅要保證幾點就可以,非常easy:
IMHO, this sentence is the very cause of the vulnerability. According to it, the reason that CCS is assigned an independent record type is to avoid a stall. This is the point where the most complex synchronization is required in TLS/SSL handshake. First, you need to wait until the handshake proceeds to the proper phase. Then, you need to check whether the handshake receives CCS before Finish.
More precisely, when accepting CCS, you must verify the following three conditions (*):
??? the handshake proceeds to the proper phase, i.e., just before to receive Finished,
??? no fragments from the handshake remains,
??? and, the next message is Finished.
Being more careful, you should also check
??? no Alert fragment remains (they can be rejected in the first place),
??? and, no Heartbeat fragment remains
事實非常easy,保證CCS發(fā)送的時候,master keys真的已經(jīng)準備好了,這實際上就是CCS本身的意思,假設(shè)我能跟我的三歲的小小講清楚這個,她肯定會說她的口頭禪:難道不是嗎?
?????? 一個獨立的CCS協(xié)議,獨立于握手協(xié)議的CCS協(xié)議,在SSL/TLS中必定不可能是全然獨立的,協(xié)議封裝上是獨立的,語義卻不可能是獨立的,否則,我在ClientHello后發(fā)送一個CCS,可否?唉,心病還未痊愈,CCS又來搗亂,假設(shè)說心臟出血是OpenSSL的問題的話(它實際上是一個低級的代碼級錯誤),CCS漏洞則是一個協(xié)議層面的問題,這個問題可不低級!我相信不止OpenSSL的實現(xiàn)會有這個問題。
?????? 我不再吐嘈了,可是我想澄清互聯(lián)網(wǎng)時代系統(tǒng)兩種死法的不同之處,對于安全而已,死法也僅僅有兩種,我舉一個現(xiàn)實中的樣例,一種是生病或中毒而死,一種是外力置死,比方車禍,地震,或者被砍死,這兩種本質(zhì)是不同的,第一種是你自身出了問題,另外一種則是外部原因?qū)е隆S成涞交ヂ?lián)網(wǎng),對于password被破解,CCS漏洞之類的,這就是第一類的,這類問題一般都是系統(tǒng)本身的設(shè)計問題,而對于像棧溢出,Heartbleed,堆溢出之類的,則屬于第二類,這類問題一旦碰到,非常公平,可是不屬于系統(tǒng)設(shè)計的問題,僅僅是實現(xiàn)問題。再說一下現(xiàn)實世界,即便吃再安全的食品,也怕菜刀,可是能夠請保鏢,武夫之流能擋刀,可是終于可能會因為吃了太多的不健康的油而致癌...
?????? 做個廣告,最好的篩子:OpenSSL
轉(zhuǎn)載于:https://www.cnblogs.com/hrhguanli/p/3788316.html
總結(jié)
以上是生活随笔為你收集整理的OpenSSL再曝CCS注入漏洞-心伤未愈又成筛子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 云蒙山景区如何购买门票?
- 下一篇: 一天一道算法题--6.15--卡特兰数