ADVERTISEMENT
不是陰謀,只是亡羊補牢
眾所期待的iOS 7.1版具有許多改變,包括使用者介面的改變、攝影時依光源狀況自動開啟HDR,甚至是適用於行車時的車用模式等新功能功能。相較之下7.0.6與6.1.6版的更新履歷只有1個項目,「此安全性更新提供了SSL連線驗證的修復」。
對於使用者而言,無論從版本號的推進,或是更新內容的豐富度來看,這個更新的重要性似乎比不上7.1版,但事實上這個更新檔影響至關重大。由於Apple在SSL連線驗證過程的程式碼上犯下了嚴重的錯誤,導致SSL驗證形同虛設,讓使用者無從得知SSL加密連線是否真的經過驗證,以致於讓通信安全暴露於極大的風險之下,使用者甚至可能在看似安全的SSL加密連線過程中,無意將信用卡資訊等機密資料外洩。
此外,Apple的電腦端作業系統也受同樣的問題影響,所幸Apple也在事發幾天後釋出OSX 10.9.2版更新檔來修正此問題。由於這個安全性問題不容小覷,因此筆者建議所有OSX與iOS的使用者,務必檢查作業系統版本並進行更新。
ADVERTISEMENT
▲iOS 7.0.6版的更新內容只有1項,雖然看似單薄,不過卻可以稱得上是iOS最重要的更新之一。
7.0.6補強安全性,但不封鎖越獄
由於Apple在iOS 7.0.6版更新中只針對SSL連線驗證問題進行修正,並沒有修補越獄所使用的漏洞,因此在iOS 7.0.6版更新檔釋出的1天之內,知名越獄團隊evad3rs馬上就更新越獄工具evasi0n7,能夠替安裝7.0.6版韌體的iDevice進行越獄。
ADVERTISEMENT
由於Apple已在於2月初釋出的iOS 7.1 Beta5版更新中修補越獄所使用的漏洞,因此沒有修補7.0.6版的原因,不可能是不知道漏洞在哪裡。筆者推測除了因為要在第一時間修正SSL連線驗證問題,可能受限於時間因素放棄修補漏洞之外,另一個可能的原因是Apple長久以來對越獄抱持著「不戰、不合」的態度,與其逼迫越獄使用者放棄7.0.6版韌體,不如採取較為寬鬆的政策讓使用者有機會修正漏洞。
▲evad3rs的成員包括pimskeks、planetbeing、pod2g、MuscleNerd等駭客,旗下evasi0n7為目前唯一公開且支援iOS 7的越獄工具。
ADVERTISEMENT
Apple出包Google補刀
由於Apple自行公開部分程式原始碼,所以我們都可以看到這段出錯的程式碼,在問題爆發後,任職於Google負擔SSL相關工作的Adam Langley很快地分析了Apple的程式碼的問題所在,並於其部落格刊載說明。筆者於下方節錄部分程式碼進行解說,詳細的完整程式碼可參考延伸閱讀中的連結。
為了讓讀者瞭解該程式的錯誤,筆者先簡單地說明一下C語言的語法,以這行程式碼為例
if ((err = SSLFreeBuffer(&hashCtx)) != 0)
ADVERTISEMENT
goto fail;
它是條if判斷式,如果if後方括號中的條件成立,則執行下一行的指令,而函式SSLFreeBuffer(&hashCtx)則是SSL驗證過程中的其中1項,該驗證程式碼寫在其他位置,當程式執行至此就會調用該函式進行運算。
多一行程式導致失效
該判斷式中的變數err記錄著驗證狀態。而err會存入函式的運算結果,當err等於0時,由於條件不成立,所以程式會跳過下一行的指令,若當err不等於0時,條件成立,程式就執行goto fail;指令,並跳往fail:,執行fail:下方的指令。
依照一般人對於數字代表意義的直覺來看,很容易先入為主地認為應該以0代表驗證失敗,並以1代表驗證成功,但是在上述程式碼中,可以看到以0代表驗證成功,或許會讓讀者產生疑惑。
其實這個問題很簡單,由於驗證成功的情況只有1種,而驗證失敗的情況可能有百百種,所以當驗證失敗時,函式可能回傳各種不等於0的錯誤代碼,以利進行診斷,所以才會以0代表驗證成功,非0代表驗證失敗。
驗證一半就算通過
接下來讀者可以看到下方節錄程式碼中的第五個if判斷式,其後方有2行goto fail;,這將造成嚴重的安全性漏洞。當程式運算完SSLHashSHA1.update的結果時,若err值不等於0,則程式會跳到fail:後方,並執行SSLFreeBuffer(&signedHashes)與SSLFreeBuffer(&hashCtx)等2個函式(其功能應該是清空2組變數的緩衝區),接下來回傳err,由於這時候err值不等於0,所以驗證過不會通過,不會發生安全性問題。
但是若在第五個if判斷式中通過驗證,此時err值等於0,因此下一行指令將被跳過(第一行goto fail;),並執行第二行goto fail;,在清空緩衝區後,將等於0的err回傳給程式。此時即使夾在第五個if判斷式與fail:之間的驗證程序沒有被執行,程式也會認為SSL驗證無誤,造成安全漏洞。
▲讀者可以透過https://gotofail.com網站,檢測自己的電腦是否曝露於上述資安風險之下。
對於不想升級到iOS 7.0.6版且已越獄的使用者,可以在Cydia中安中裝SSLPatch來修正這個問題。
▲筆者以iOS 6.1.2版並安裝SSLPatch進行測試,結果顯示對於gotofail攻擊為安全狀態。
延伸閱讀網址
Adam Langley部落格
https://www.imperialviolet.org
Apple問題專文
https://www.imperialviolet.org/2014/02/22/applebug.html
Apple公開的相關程式碼
出問題的程式碼(節錄)
hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
hashOut.length = SSL_SHA1_DIGEST_LEN;
if ((err = SSLFreeBuffer(&hashCtx)) != 0)
goto fail;
if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
err = sslRawVerify(ctx,
ctx->peerPubKey,
dataToSign, /* plaintext */
dataToSignLen, /* plaintext length */
signature,
signatureLen);
if(err) {
sslErrorLog("SSLDecodeSignedServerKeyExchange: sslRawVerify "
"returned %d\n", (int)err);
goto fail;
}
fail:
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
SSL原理:透過驗證、加密確保安全
既然從前段文章中可以看到這次SSL出包的問題,在於Apple撰寫的程式碼存在bug,並不是SSL機制有問題,但讀者不免會對SSL的運作原理及安全性有所疑問,筆者在此就講述SSL的運作原理,讓讀者對這個行之有年的安全機制有更深一層的認識。
SSL、TLS同根生
SSL的全名是Secure Sockets Layer,由曾風光一時的瀏覽器公司Netscape開發,其1.0版並未公開釋出,第一個公開版本為1995年問市的2.0版,不過由於2.0版有些許安全性缺陷,因此隔年Netscape就推出SSL 3.0。
IETF(Internet Engineering Task Force,網際網路工程任務組)在1999年制定RFC2246,並將其稱為TLS(Transport Layer Security),將其視為SSL的升級版,並於2006與2008年推出TLS 1.1與1.2版。
根據Trustworthy Internet Movement於2014年3月4日提供的數據,在他們統計的網站中,最普遍被支援的規範為SSL 3.0,其比例高達99.4%,次高比例為TLS 1.0的97.7%,支援TLS 1.2的網站只有30.2%。
ADVERTISEMENT