自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關于OpenSSL“心臟出血”漏洞的分析

安全 漏洞
OpenSSL“心臟出血”漏洞是一個非常嚴重的問題。這個漏洞使攻擊者能夠從內(nèi)存中讀取最多64 KB的數(shù)據(jù)。

當我分析GnuTLS的漏洞的時候,我曾經(jīng)說過,那不會是我們看到的最后一個TLS棧上的嚴重bug。然而我沒想到這次OpenSSL的bug會如此嚴重。

[[111228]]

OpenSSL“心臟出血”漏洞是一個非常嚴重的問題。這個漏洞使攻擊者能夠從內(nèi)存中讀取最多64 KB的數(shù)據(jù)。一些安全研究員表示:

無需任何特權信息或身份驗證,我們就可以從我們自己的(測試機上)偷來X.509證書的私鑰、用戶名與密碼、聊天工具的消息、電子郵件以及重要的商業(yè)文檔和通信等數(shù)據(jù)。

這一切是如何發(fā)生的呢?讓我們一起從代碼中一探究竟吧。

0x01 Bug

請看ssl/dl_both.c,漏洞的補丁從這行語句開始:

  1. int              
  2. dtls1_process_heartbeat(SSL *s)  
  3.     {            
  4.     unsigned char *p = &s->s3->rrec.data[0], *pl;  
  5.     unsigned short hbtype;  
  6.     unsigned int payload;  
  7.     unsigned int padding = 16; /* Use minimum padding */ 

一上來我們就拿到了一個指向一條SSLv3記錄中數(shù)據(jù)的指針。結構體SSL3_RECORD的定義如下(譯者注:結構體SSL3_RECORD不是SSLv3記錄的實際存儲格式。一條SSLv3記錄所遵循的存儲格式請參見下文分析):

  1. typedef struct ssl3_record_st  
  2.     {  
  3.         int type;               /* type of record */ 
  4.         unsigned int length;    /* How many bytes available */ 
  5.         unsigned int off;       /* read/write offset into 'buf' */ 
  6.         unsigned char *data;    /* pointer to the record data */ 
  7.         unsigned char *input;   /* where the decode bytes are */ 
  8.         unsigned char *comp;    /* only used with decompression - malloc()ed */ 
  9.         unsigned long epoch;    /* epoch number, needed by DTLS1 */ 
  10.         unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */ 
  11.     } SSL3_RECORD; 

每條SSLv3記錄中包含一個類型域(type)、一個長度域(length)和一個指向記錄數(shù)據(jù)的指針(data)。我們回頭去看dtls1_process_heartbeat:

  1. /* Read type and payload length first */ 
  2. hbtype = *p++;  
  3. n2s(p, payload);  
  4. pl = p; 

SSLv3記錄的第一個字節(jié)標明了心跳包的類型。宏n2s從指針p指向的數(shù)組中取出前兩個字節(jié),并把它們存入變量payload中——這實際上是心跳包載荷的長度域(length)。注意程序并沒有檢查這條SSLv3記錄的實際長度。變量pl則指向由訪問者提供的心跳包數(shù)據(jù)。

這個函數(shù)的后面進行了以下工作:

  1. unsigned char *buffer, *bp;  
  2. int r;  
  3.    
  4. /* Allocate memory for the response, size is 1 byte  
  5.  * message type, plus 2 bytes payload length, plus  
  6.  * payload, plus padding  
  7.  */ 
  8. buffer = OPENSSL_malloc(1 + 2 + payload + padding);  
  9. bp = buffer; 

所以程序將分配一段由訪問者指定大小的內(nèi)存區(qū)域,這段內(nèi)存區(qū)域最大為 (65535 + 1 + 2 + 16) 個字節(jié)。變量bp是用來訪問這段內(nèi)存區(qū)域的指針。

  1. /* Enter response type, length and copy payload */ 
  2. *bp++ = TLS1_HB_RESPONSE;  
  3. s2n(payload, bp);  
  4. memcpy(bp, pl, payload); 

宏s2n與宏n2s干的事情正好相反:s2n讀入一個16 bit長的值,然后將它存成雙字節(jié)值,所以s2n會將與請求的心跳包載荷長度相同的長度值存入變量payload。然后程序從pl處開始復制payload個字節(jié)到新分配的bp數(shù)組中——pl指向了用戶提供的心跳包數(shù)據(jù)。最后,程序將所有數(shù)據(jù)發(fā)回給用戶。那么Bug在哪里呢?

0x01a 用戶可以控制變量payload和pl

如果用戶并沒有在心跳包中提供足夠多的數(shù)據(jù),會導致什么問題?比如pl指向的數(shù)據(jù)實際上只有一個字節(jié),那么memcpy會把這條SSLv3記錄之后的數(shù)據(jù)——無論那些數(shù)據(jù)是什么——都復制出來。

很明顯,SSLv3記錄附近有不少東西。

說實話,我對發(fā)現(xiàn)了OpenSSL“心臟出血”漏洞的那些人的聲明感到吃驚。當我聽到他們的聲明時,我認為64 KB數(shù)據(jù)根本不足以推算出像私鑰一類的數(shù)據(jù)。至少在x86上,堆是向高地址增長的,所以我認為對指針pl的讀取只能讀到新分配的內(nèi)存區(qū)域,例如指針bp指向的區(qū)域。存儲私鑰和其它信息的內(nèi)存區(qū)域的分配早于對指針pl指向的內(nèi)存區(qū)域的分配,所以攻擊者是無法讀到那些敏感數(shù)據(jù)的。當然,考慮到現(xiàn)代malloc的各種神奇實現(xiàn),我的推斷并不總是成立的。

當然,你也沒辦法讀取其它進程的數(shù)據(jù),所以“重要的商業(yè)文檔”必須位于當前進程的內(nèi)存區(qū)域中、小于64 KB,并且剛好位于指針pl指向的內(nèi)存塊附近。

研究者聲稱他們成功恢復了密鑰,我希望能看到PoC。如果你找到了PoC,請聯(lián)系我。

0x01b 漏洞修補

修復代碼中最重要的一部分如下:

  1. /* Read type and payload length first */ 
  2. if (1 + 2 + 16 > s->s3->rrec.length)  
  3.     return 0; /* silently discard */ 
  4. hbtype = *p++;  
  5. n2s(p, payload);  
  6. if (1 + 2 + payload + 16 > s->s3->rrec.length)  
  7.     return 0; /* silently discard per RFC 6520 sec. 4 */ 
  8. pl = p; 

這段代碼干了兩件事情:首先第一行語句拋棄了長度為0的心跳包,然后第二步檢查確保了心跳包足夠長。就這么簡單。

0x02 前車之鑒

我們能從這個漏洞中學到什么呢?

我是C的粉絲。這是我最早接觸的編程語言,也是我在工作中使用的第一門得心應手的語言。但是和之前相比,現(xiàn)在我更清楚地看到了C語言的局限性。

從GnuTLS漏洞和這個漏洞出發(fā),我認為我們應當做到下面三條:

花錢請人對像OpenSSL這樣的關鍵安全基礎設施進行安全審計;

為這些庫寫大量的單元測試和綜合測試;

開始在更安全的語言中編寫替代品。

考慮到使用C語言進行安全編程的困難性,我不認為還有什么其他的解決方案。我會試著做這些,你呢?

作者簡介:Sean是一位關于如何把事兒干好的軟件工程師。現(xiàn)在他在Squadron工作。Squadron是一個專為SaaS應用程序準備的配置與發(fā)布管理工具。

測試版本的結果以及檢測工具:

OpenSSL 1.0.1 through 1.0.1f (inclusive) are vulnerable

OpenSSL 1.0.1g is NOT vulnerable

OpenSSL 1.0.0 branch is NOT vulnerable

OpenSSL 0.9.8 branch is NOT vulnerable

http://filippo.io/Heartbleed/

原文地址:http://blog.existentialize.com/diagnosis-of-the-openssl-heartbleed-bug.html

責任編輯:藍雨淚 來源: 烏云知識庫
相關推薦

2015-07-09 13:46:15

漏洞OpenSSL

2014-04-16 11:38:41

網(wǎng)絡·安全技術周刊

2014-04-16 14:32:13

2014-04-28 09:37:52

2014-09-26 08:55:03

漏洞bash破殼安全漏洞

2014-10-08 10:15:17

2014-07-17 15:31:48

2014-09-26 10:15:45

2014-09-26 15:29:13

2017-09-27 16:38:51

2014-04-09 09:37:29

2014-04-15 10:55:17

2014-09-26 09:22:35

2014-09-26 15:41:51

2014-04-14 12:26:30

IT技術周刊

2015-05-05 11:32:11

2014-11-13 10:03:19

2014-04-09 09:56:53

2014-05-14 10:44:02

2014-04-10 18:12:04

點贊
收藏

51CTO技術棧公眾號