Heartbleed漏洞是怎麼來的?
(題圖來自 Heartbleed Bug)
這次驚天動地的OpenSSL漏洞,在這篇blog里有詳細的介紹:existential type crisis : Diagnosis of the OpenSSL Heartbleed Bug簡而言之,TLS協議提供了可選的心跳檢測(Heart beat)擴展(RFC: https://tools.ietf.org/html/rfc6520)。連接的一端可以發一個特定類型的heart beat請求包給對端,裡面攜帶最長64KiB的任意數據,對端收到後請求把數據原樣返回,完成心跳檢測。
」你還活著嗎?跟我念下面25個字:你是一頭大肥豬「nn」我還活著,你TMD才是肥豬呢「 (誤)nn」我還活著,你是一頭大肥豬小明的賬號是abcd密碼是12345"n
上面的對話(請認真的忽略第2行,以及不要拿UTF8來數字數)演示了heartbleed攻擊的全過程。發送heartbeat請求的客戶端故意聲明自己攜帶了很長的數據(例如最長64KiB),需要伺服器echo回來,但實際上可以只帶很短的數據甚至就不帶任何數據。OpenSSL的代碼沒有檢查heartbeat請求中聲明的數據長度和實際數據的大小,而是直接按這個長度用memcpy從請求數據進行複製。請求的數據本身很短,實際複製的是內存中緊跟在請求數據後面的這一段空間的數據。這就是這次攻擊能獲得伺服器上隨機地址的64KiB數據的由來。運氣好的話,這64KiB就能包括伺服器上最近處理過的用戶名密碼之類的東西。而且這種攻擊基本留不下日誌,反覆跑也是大丈夫的。
因為問題出在Heart beat的實現上,所以這次exploit很形象的叫做Heartbleed。
「永遠不要相信任何外部輸入的數據」——給新員工培訓的時候我都會反覆強調這一點。從scanf到SQL注入,漏洞都出在不檢查用戶輸入上。一個很小的疏忽,就可以造成天崩地裂的損失。
像這種問題,嚴格的代碼review和完整的單元測試都有助於提前發現,只是絕大多數開發者都不愛做這些麻煩的事。
推薦閱讀:
※TLS完全指南(二):OpenSSL操作指南
※酷站推薦 - ssllabs.com/ssl-pulse - SSL/TLS Security Scan Summary
※TLS完全指南(零)
※為什麼SSL證書那麼貴?
※使用了不受支持的SSL協議是怎麼回事?
TAG:SSL |