Signal修復(fù)了一個允許攻擊者破壞加密附件的bug
譯文【51CTO.com快譯】導(dǎo)言:Signal應(yīng)用可謂是最可信的消息傳遞應(yīng)用程序,但它并不完美的。
Signal應(yīng)用,一款由美國國家安全局(NSA)泄密者--愛德華·斯諾登和大量的安全專家推薦的移動消息傳送應(yīng)用,近期修復(fù)了一個允許攻擊者將隨機數(shù)添加到由Android用戶發(fā)送的加密消息附件里的錯誤(bug)。該更新已在Github(面向開源及私有軟件項目的托管平臺)的項目子集里可獲取到,但在谷歌的Android應(yīng)用市場—Google Play里尚無。
旁路消息驗證(message authentication-bypass)的脆弱性是由研究人員Jean-Philippe Aumasson和Markus Vervier在一次非正式的檢查Android版本的Signal所使用的Java代碼時發(fā)現(xiàn)出的多個弱點中的一個。該bug將使得那些破壞或假冒Signal服務(wù)器的攻擊者有可能通過添加隨機數(shù)據(jù)來修改“合法”的附件。第二個bug則可能是允許攻擊者遠程執(zhí)行惡意代碼;而Vervier先生告訴本刊記者,第三個bug是一個簡單的遠程導(dǎo)致系統(tǒng)崩潰手段的有限利用。
“雖然結(jié)果并非不是災(zāi)難性,但這表明,和其他的軟件一樣,Signal應(yīng)用也并非完美。”Aumasson先生在一封郵件中這么寫道,“Signal應(yīng)用吸引了許多安全研究人員的注意。在此之前,其‘無脆弱性’曾給大家留下了深刻印象。但該發(fā)現(xiàn)是有益于Signal應(yīng)用的,我們?nèi)詫⒗^續(xù)信任它。”
附件破壞的脆弱性來自整數(shù)類型數(shù)據(jù)溢出的bug,即:當有非常大的文件集(至少4 GB大小)被附加到消息里時就會被觸發(fā)。Signal應(yīng)用將會檢查一小部分,而并非驗證整體文件真實性這一特點,使得攻擊者可以添加偽隨機數(shù)據(jù)而不會被MAC(消息驗證碼)所檢測到,盡管MAC已是大多數(shù)加密方案里的一個標準部分。為了使得此攻擊更具操作性,攻擊者可以使用Signal應(yīng)用所支持的文件壓縮來將惡意附件的大小減少到可控的4MB以用于運輸。
在郵件中,Aumasson聲稱數(shù)據(jù)溢出的bug可在如下代碼行中被發(fā)現(xiàn):
- int remainingData = (int) file.length() - mac.getMacLength();
他的解釋是:此處“file.length()”的值是一個64位編碼的數(shù)值(“長整型”),而接收變量--“remainingData”卻是一個32位 (“int,整型”)。因此,當“file.length()”比適合32位的數(shù)值還要長的時候,“remainingData”(剩下用于處理的字節(jié)數(shù))的值將不正確,因為它將比實際文件的大小要小得多。因此,當Signal應(yīng)用驗證加密的真實性的時候,文件的很大部分將被忽略掉了。Signal應(yīng)用只會檢查文件的開始一小部分,而用戶卻實際上將接收的是更大的文件。
Signal應(yīng)用吸引人的原因之一就是它部署的是端到端加密,也就意味著它在發(fā)送方的設(shè)備上加密一條消息,直到安全地存儲到了接收設(shè)備上才進行解密。當然,加密的消息要經(jīng)過一個服務(wù)器。那么黑客就可以冒充該服務(wù)器,繞過消息身份驗證,進而篡改信息附件。為了繞過傳輸層的安全保護,攻擊者可能需要黑掉Android操作系統(tǒng)所信任的數(shù)以百計的權(quán)威證書簽發(fā)機構(gòu)中的某一個或誘騙其目標在設(shè)備上安裝一個假的CA證書。下面是更細節(jié)化的漏洞分析:
為了防止被第三方(也包括Signal的維護人員)所閱讀或改變,Signal應(yīng)用的附件是被加密驗證的。相對于“消息驗證再加密”(如TLS)和“加密并消息驗證”(如SSH)的做法,Signal則使用的是“加密再消息驗證”,這一最為安全的方法。
如果消息和附件被發(fā)送,其附件被單獨下載到AWS服務(wù)器上,如https://whispersystems-textsecure-attachments.s3.amazonaws.com/。附件被發(fā)送方用PKCS7的AES-128-CBC進行加密,以及HMAC-SHA-256進行認證,而且使用的是128位密鑰。
通過HTTPS方式下載的附件被保存到Android存儲空間。Signal的服務(wù)對文件的MAC使用如下代碼進行檢查。其文件路徑是:
- :libsignal-service-java/java/src/main/java/org/whispersystems/signalservice/api/crypto/AttachmentCipherInputStream.java:
- private void verifyMac(File file, Mac mac) throws FileNotFoundException, InvalidMacException {
- try {
- FileInputStream fin = new FileInputStream(file);
- int remainingData = (int) file.length() - mac.getMacLength();
- byte[] buffer = new byte[4096];
- while (remainingData > 0) {
- int read = fin.read(buffer, 0, Math.min(buffer.length, remainingData));
- mac.update(buffer, 0, read);
- remainingData -= read;
- }
- byte[] ourMac = mac.doFinal();
- byte[] theirMac = new byte[mac.getMacLength()];
- Util.readFully(fin, theirMac);
- if (!Arrays.equals(ourMac, theirMac)) {
- throw new InvalidMacException("MAC doesn't match!");
- }
- } catch (IOException e1) {
- throw new InvalidMacException(e1);
- }
- }
如上所述remainingData的類型是int(整形),由文件的長度減去MAC的長度得出。因為file.length()將返回一個長整型值而文件可能大于Integer.MAX_VALUE,所以remainingData將被略過了。
不像C(+ +)語言,Java是“記憶安全”的,也就不會導(dǎo)致任何經(jīng)典的內(nèi)存崩潰狀態(tài)。然而,我們卻可以使用此溢出來破壞程序的邏輯?,F(xiàn)在,如果文件大小是4BG + 1byte+ X,其價值將被略過,remainingData也將被設(shè)置為X。
不巧的是:Signal應(yīng)用將所有附件存儲在AWS S3上,以HTTPS的方式獲取它們,并使用系統(tǒng)證書集來檢查服務(wù)器的證書(注意:在S3服務(wù)器上的Signal用的是通配符:*.s3.amazonaws.com)。因此具有訪問Amazon S3權(quán)限或具有其他Android系統(tǒng)所信任的CA證書的實體,可以用下列步驟修改附件:
1.等待取附件的請求。
2.取出原始附件的大小X。
3.用4GB + 1byte的數(shù)據(jù)來填充附件,以得到X + 4GB + 1的總共大小。
如上所述,這將導(dǎo)致X字節(jié)通過verifyMAC()的檢查,而原始的MAC已然合法。因此,我們可以將任意數(shù)據(jù)添加到文件,而MAC的檢查是不會報錯的!
值得注意的是:攻擊者并不需要在任何網(wǎng)絡(luò)連接中真實發(fā)送超過4GB的數(shù)據(jù),如果我們使用gzip進行HTTP的流壓縮,我們就能創(chuàng)建一個4GB的文件而實際壓縮下來卻只有4.5MB。如下所示:
- [s@polo tools-markus]$ python2 sap.py --encoding gzip
- Serving HTTP on 0.0.0.0 port 8000 ...
- opening: https://whispersystems-textsecure-attachments.s3.amazonaws.com/attachments/id1/id2...
- * Compressing content...
- ** Padding content...
- ** Finished
- Compressed Content Length (Raw 49284): 4458483
- * Set Content-Length to: 4458483
- * Sent header, writing content
- * Request finished
通過查看Android的調(diào)試日志,我們現(xiàn)在看到如下異常代碼:
- W/AttachmentDownloadJob(10484): ws.com.google.android.mms.MmsException: java.io.IOException: javax.crypto.BadPaddingException: EVP_CipherFinal_ex
- W/AttachmentDownloadJob(10484): at org.thoughtcrime.securesms.database.AttachmentDatabase.setAttachmentData(AttachmentDatabase.java:427)
- W/AttachmentDownloadJob(10484): at org.thoughtcrime.securesms.database.AttachmentDatabase.setAttachmentData(AttachmentDatabase.java:412)
- W/AttachmentDownloadJob(10484): at org.thoughtcrime.securesms.database.AttachmentDatabase.insertAttachmentsForPlaceholder(AttachmentDatabase.java:255)
- W/AttachmentDownloadJob(10484): at org.thoughtcrime.securesms.jobs.AttachmentDownloadJob.retrieveAttachment(AttachmentDownloadJob.java:120)
- W/AttachmentDownloadJob(10484): at org.thoughtcrime.securesms.jobs.AttachmentDownloadJob.onRun(AttachmentDownloadJob.java:84)
- W/AttachmentDownloadJob(10484): at org.thoughtcrime.securesms.jobs.MasterSecretJob.onRun(MasterSecretJob.java:18)
- W/AttachmentDownloadJob(10484): at org.whispersystems.jobqueue.JobConsumer.runJob(JobConsumer.java:76)
- W/AttachmentDownloadJob(10484): at org.whispersystems.jobqueue.JobConsumer.run(JobConsumer.java:46)
- W/AttachmentDownloadJob(10484): Caused by: java.io.IOException: javax.crypto.BadPaddingException: EVP_CipherFinal_ex
- W/AttachmentDownloadJob(10484): at org.whispersystems.signalservice.api.crypto.AttachmentCipherInputStream.readFinal(AttachmentCipherInputStream.java:129)
- W/AttachmentDownloadJob(10484): at org.whispersystems.signalservice.api.crypto.AttachmentCipherInputStream.read(AttachmentCipherInputStream.java:100)
- W/AttachmentDownloadJob(10484): at org.whispersystems.signalservice.api.crypto.AttachmentCipherInputStream.read(AttachmentCipherInputStream.java:94)
- W/AttachmentDownloadJob(10484): at org.thoughtcrime.securesms.util.Util.copy(Util.java:220)
- W/AttachmentDownloadJob(10484): at org.thoughtcrime.securesms.database.AttachmentDatabase.setAttachmentData(AttachmentDatabase.java:425)
- W/AttachmentDownloadJob(10484): ... 7 more
- W/AttachmentDownloadJob(10484): Caused by: javax.crypto.BadPaddingException: EVP_CipherFinal_ex
- W/AttachmentDownloadJob(10484): at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
- W/AttachmentDownloadJob(10484): at com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430)
- W/AttachmentDownloadJob(10484): at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:490)
- W/AttachmentDownloadJob(10484): at javax.crypto.Cipher.doFinal(Cipher.java:1314)
- W/AttachmentDownloadJob(10484): at org.whispersystems.signalservice.api.crypto.AttachmentCipherInputStream.readFinal(AttachmentCipherInputStream.java:124)
- W/AttachmentDownloadJob(10484): ... 11 more
檢查MAC后,類構(gòu)造函數(shù)--AttachmentCipherInputStream將創(chuàng)建一個javax.crypto.Cipher類的實例:
- public AttachmentCipherInputStream(File file, byte[] combinedKeyMaterial)
- throws IOException, InvalidMessageException
- {
- ...
- verifyMac(file, mac);
- byte[] iv = new byte[BLOCK_SIZE];
- readFully(iv);
- this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- this.cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(parts[0], "AES"), new IvParameterSpec(iv));
- this.done = false;
- this.totalRead = 0;
- this.totalDataSize = file.length() - cipher.getBlockSize() - mac.getMacLength();
- } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidAlgorithmParameterException e) {
- throw new AssertionError(e);
- } catch (InvalidMacException e) {
- throw new InvalidMessageException(e);
- }
達到這種狀態(tài)時,我們便可以對自己所選取的密碼進行解密了。
研究人員已將此漏洞在9月13日“私信”了Signal應(yīng)用的開發(fā)商Open Whisper Systems公司,該司也已發(fā)布了相應(yīng)的更新。Kudelski安全公司的首席研究員Aumasson先生和X41公司的首席執(zhí)行官兼安全研究主任Vervier先生分別聲稱他們?nèi)栽谘芯窟@次bug是否也影響到了依賴于Signal代碼的WhatsApp和Facebook消息傳遞應(yīng)用。
在郵件中,Open Whisper Systems公司的創(chuàng)辦人Moxie Marlinspike寫到:這是一個重大的錯誤報告,但我們認為當前其影響程度仍較低。它并不允許攻破了服務(wù)器的黑客去讀取或修改附件,而只能添加一個最低為4GB的不可預(yù)測的隨機數(shù)據(jù)到附件尾部用于傳輸。在有效地以不可預(yù)知的方式破壞文件并使之太大,從而無法在Android設(shè)備上打開的同時,入侵了服務(wù)器的黑客就很容易通過拒絕你的附件要求的方式使服務(wù)器不再提供服務(wù)。
參考原文:
http://arstechnica.com/security/2016/09/signal-fixes-bug-that-let-attackers-tamper-with-encrypted-messages/
https://pwnaccelerator.github.io/2016/signal-part1.html
【51CTO譯稿,合作站點轉(zhuǎn)載請注明原文譯者和出處為51CTO.com】