Android 將測試 DNS over TLS

從「Android getting "DNS over TLS" to prevent ISPs from knowing what websites you visit」這邊看到的報導,原
文在「Android getting “DNS over TLS” support to stop ISPs from knowing what websites you visit」這邊可以看到。

It appears that “DNS over TLS” support is being added to Android, according to several commits added to the Android Open Source Project (AOSP). The addition in the Android repository shows that a new setting will be added under Developer Options allowing users to turn on or off DNS over TLS. Presumably, if such an option is being added to Developer Options, then that means it is in testing and may arrive in a future version of Android such as version 8.1.

這邊用的應該是 RFC 7858 的「Specification for DNS over Transport Layer Security (TLS)」,已經是 Standards Track 了。預設使用 TCP port 853:

By default, a DNS client desiring privacy from DNS over TLS from a particular server MUST establish a TCP connection to port 853 on the server, unless it has mutual agreement with its server to use a port other than port 853 for DNS over TLS.

而且建議如果另外定義的話,不要用 port 53:

This recommendation against use of port 53 for DNS over TLS is to avoid complication in selecting use or non-use of TLS and to reduce risk of downgrade attacks.

另外也說明了在 port 853 上禁用明文傳輸:

DNS clients and servers MUST NOT use port 853 to transport cleartext DNS messages.

另外一個還在發展的標準是 Cisco 的人推出的「DNS over Datagram Transport Layer Security (DTLS)」,走的是 UDP port 853,不過看起來因為 stateless 的特性,需要考慮比較多問題... (尤其這類服務常配合 anycast)

不過即使將 DNS query 保護起來,TLS 本身還是會透漏 hostname 的部份 (因為 SNI 的關係),所以就 privacy 面向考量的話,沒有實質的意義... 主要還是考慮被竄改的問題?但如果是這樣的話,目前 TLS 連線本身就已經有這樣的保護了?暫時沒想到可以解什麼實際的問題...

OpenSSL 安全通報連發...

熱騰騰的「OpenSSL Security Advisory [05 Jun 2014]」:

  • SSL/TLS MITM vulnerability (CVE-2014-0224)
  • DTLS recursion flaw (CVE-2014-0221)
  • DTLS invalid fragment vulnerability (CVE-2014-0195)
  • SSL_MODE_RELEASE_BUFFERS NULL pointer dereference (CVE-2014-0198)
  • SSL_MODE_RELEASE_BUFFERS session injection or denial of service (CVE-2010-5298)
  • Anonymous ECDH denial of service (CVE-2014-3470)

這太熱鬧了,第一個 security issue 可以在 MITM 的情況下,強迫選用比較差的 cipher:

An attacker using a carefully crafted handshake can force the use of weak keying material in OpenSSL SSL/TLS clients and servers.

第三個則有可能直接爆破執行程式碼:

A buffer overrun attack can be triggered by sending invalid DTLS fragments to an OpenSSL DTLS client or server. This is potentially exploitable to run arbitrary code on a vulnerable client or server.

接下來幾天對 SA 來說又是無止盡的升級地獄...

OpenSSL 安全漏洞 (CVE-2014-0160)

CVE-2014-0160,又稱 Heartbleed Bug,是 OpenSSL 在 TLS 與 DTLS 協定裡的 Heartbeat Extension (RFC 6520) 的錯誤實作。

OpenSSL 官方的 security advisory 在這:「OpenSSL Security Advisory [07 Apr 2014]」,影響的範圍是:

Only 1.0.1 and 1.0.2-beta releases of OpenSSL are affected including 1.0.1f and 1.0.2-beta1.

實務上爆炸的程度則是:

A missing bounds check in the handling of the TLS heartbeat extension can be used to reveal up to 64k of memory to a connected client or server.

比較有描述性的說明可以參考「The Heartbleed Bug」這個站的敘述:

We have tested some of our own services from attacker's perspective. We attacked ourselves from outside, without leaving a trace. Without using any privileged information or credentials we were able steal from ourselves the secret keys used for our X.509 certificates, user names and passwords, instant messages, emails and business critical documents and communication.

由於 untraceable,這代表我們必須假設所有受影響機器上的 SSL private key 都已經被洩漏出去了,所有的 key 都必須 revoke 並且重新產生 (& 重新簽)。這兩天讓所有 SA 爆炸的超大新聞...

SSL/TLS 的問題...

這篇與「對稱式加密系統的爆炸歷史 (Authenticated encryption 的問題)」這篇相關,建議可以一起看一看。

TLS (Transport Layer Security),前身是 SSL (Secure Sockets Layer),是目前 HTTPS 所使用的加密協議。發展的順序上是 SSLv2、SSLv3、TLSv1、TLSv1.1、TLSv1.2。

然後有兩篇文章可以看:

第一篇文章講 Padding oracle attack,第二篇文章是酸 SSL/TLS 的修正愈修愈歪... XD

AES 這類的 block cipher 在加密或解密時會要求切齊 block size,以 AES 的要求就是 128bits (16 bytes)。

而對於不齊的資料要怎麼加密呢?其中一個方法是 PKCS#7:(圖片取自第二篇文章)

Padding

要想辦法補齊 128bits (16bytes),如果像上圖需要補 7bytes 進去,就都補上 \x07 (剛好就是補上長度),另外在最後面會補上 padding 的長度,而問題出就出在這個設計先天就有缺陷:在 SSL/TLS 所使用的 MAC-then-Encrypt 中,MAC 只計算原文的值,沒有保護到 padding 的部份,於是就可以針對 padding 的部份想辦法找到洞鑽。

pseudo code 可能是這樣:

// Decrypt to plaintext + mac + padding
$plaintext_mac_padding = decrypt($ciphertext);
if (NULL != $plaintext_mac_padding) {

    // Now decode padding part
    $plaintext_mac = decode_padding($plaintext_mac_padding, $padding_length);
    if (NULL != $plaintext_mac) {

        // Now check MAC part
        $plaintext = check_mac(plaintext_mac);
        if (NULL != $plaintext) {

            // Now it's okay
        }
    }
}

攻擊者亂改 $ciphertext 會導致解出來的 padding 也亂掉,但早期的 SSL 會回傳「padding error」這種對攻擊者有利的資訊,而導致攻擊者可以利用這個資訊想辦法得知更多內容。

而 TLS 並沒有從根本改善,而是試著加上機制補西牆:當遇到錯誤時就跳過,不要傳回錯誤資訊。

但因為攻擊者亂改封包造成 decode_padding() 會失敗,而沒有呼叫到 check_mac()。這導致了大量的計算時間差與能量差,而使得攻擊者可以藉由這些資訊而得知是否成功。而官方在 TLSv1.2 的建議是再補上機制來補洞:

In general, the best way to do this is to compute the MAC even if the padding is incorrect, and only then reject the packet. For instance, if the pad appears to be incorrect, the implementation might assume a zero-length pad and then compute the MAC.

而官方認為雖然這樣還是有 timing channel,但已經小到會被雜訊覆蓋,所以「應該」可以解決問題:

This leaves a small timing channel, since MAC performance depends to some extent on the size of the data fragment, but it is not believed to be large enough to be exploitable, due to the large block size of existing MACs and the small size of the timing signal.

於是,只要覺得「應該安全吧」,就會「應該會被破」:「Lucky Thirteen: Breaking the TLS and DTLS Record Protocols」:

The attacks apply to all TLS and DTLS implementations that are compliant with TLS 1.1 or 1.2, or with DTLS 1.0 or 1.2. They also apply to implementations of SSL 3.0 and TLS 1.0 that incorporate countermeasures to previous padding oracle attacks. Variant attacks may also apply to non-compliant implementations.

這 SSL/TLS 的設計讓人補到快起笑了... XD

資安的東西通常是愈複雜就愈容易被抓問題出來,在 SSL/TLS 的歷史包袱下,不知道什麼時候才想換 Encrypt-then-MAC 來改善底層問題...