iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 16
0
Security

網路安全概述系列 第 16

談 Heartbeat 協定與 CVE-2014-0160 (Heartbleed)

  • 分享至 

  • xImage
  •  

今天來講約莫四年前發生的 bug,CVE-2014-0160,又稱 Heartbleed。

Heartbleed 名稱的由來

OpenSSL 在之前實作了一個 TLS 的延伸協定,名叫 Heartbeat。其主要用途是在長時間連線時使用,確認一個資源(即一台機器)是否有在線上,避免兩台電腦之間太久沒有通訊,導致斷線,需要重新開啟一次連線的狀況。
除了在 TLS 上使用,也可以在 DTLS (即 UDP 版的 TLS) 上來使用。

Heartbeat

作業原理

Heartbeat 有兩種模式:一種是 HeartbeatRequest,另一種是 HeartbeatResponse。依據連線模式的不同,會分成以下兩種:

  • 當使用可靠的傳輸協定時,一邊會向另一邊傳 HeartbeatRequest,另一邊應該要馬上用 HeartbeatResponse 回覆,所以可以做 Keep-Alive 連線 (參考 HTTP Header)。如果另一方沒有在一定時間內回覆,這條連線應該被斷開。
  • 當使用不可靠的傳輸協定 (UDP 等) 時,大致上一樣,不過在超過時間時,會試著重傳幾次,一直沒收到回覆,才會斷開連線

當一方收到 HeartbeatRequest 時,接受方應該要將其內容複製一份,包在 HeartbeatResponse 當中,傳回去。傳送方應該要檢查內容是否和一開始傳送的一樣,如果不是,則重傳。

Heartbleed

OpenSSL 有實作上述的 Heartbeat 協定,不過它是這樣實作的:

unsigned char *pl;
unsigned int payload;

...

buffer = OPENSSL.malloc(1 + 2 + payload + padding);
bp = buffer;

...
memcpy(bp, pl, payload);
...

但是,前後並沒有針對 bp 的長度 pl 做檢查,所以 pl 不一定會等於 sizeof(bp),而 memcpy 的實作是「從 bp 的開始,讀取 pl 的長度,然後複製到 payload」,所以這樣會有 leak 的問題,且最多可以 leak 65535 bytes (unsigned int 最大 65535 bytes)。

所以在這個狀況下,只要傳 HeartbeatRequest 時,不要填寫正確的長度,即可以讀取到 payload 開頭之後 64K 的資料。

實務上的影響

由於這個漏洞不能控制 payload 在記憶體實際上的位置,所以,不一定會馬上把記憶體中其他敏感資訊給洩漏出去。但因為記憶體裡面可能會有其他敏感資訊(例如:憑證私鑰,別人的 session key,別人的密碼,別人的 log),所以這個 bug 的影響頗大。

這裡有一張圖,可以解釋實際上的影響:


上一篇
談 Debian OpenSSL 的問題與亂數產生器
下一篇
番外篇: 談 CPU Bug、FDIV/F00F bug
系列文
網路安全概述31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言