關於燒毀漏洞的事後檢討

這篇文章要來談一個被稱為燒毀(burning)的漏洞。這篇文章的目標是對上述的漏洞提供完整的細節,解釋這是如何被用來攻擊線上服務、商家與交易所,並且 Monero (開發)社群是如何處理這個漏洞。

這個漏洞基本上來自於錢包在接收到被燒毀的交易時不會發出警告。因此,有心的攻擊者可以利用這點,僅是支付網路交易就能燒毀一個服務機構的錢包內資金。經由此漏洞,攻擊者其實沒有直接的獲益,但是仍然可能有間接的獲益。燒毀的概念上是將數筆交易送至相同的隱匿性地址,而這地址是在先前就已經存在的,這概念的例子可以在先前的討論中看到。不幸的是,這問題被利用來攻擊服務機構的可能性並沒有被察覺,直到 Monero 的一位 reddit 社群成員提出了這個攻擊假設。

目前,Monero的隱匿性地址可以用這樣的公式來表示:

P = Hs(rA||i)*G + B

其中

Hs 是一個雜湊至純量的函式(注意這存量的輸出為 reduced modulo l);

r 是交易私鑰,由發送者隨機產生;

A 是查看公鑰,是收款者的錢包地址字串的其中一部分;

i 是交易輸出索引 (每筆交易輸出都有其索引編號,譬如第一筆交易輸出就是索引0);

G 是標準 Ed25519 的基點;

B 是花費公鑰,是收款者的錢包地址字串的其中一部分;

而 Monero 的金鑰映像可由以下公式表示:

I = xHp(P)

其中

x 是一個私鑰/純量(由收款者的花費私鑰與 ECDH 共享金鑰雜湊純量輸出相加而得);

Hp 是雜湊至點函式;

P 是隱匿性地址;

可以從上面的公式看到,將 Monero 發送至相同的隱匿性地址時將會輸出多個重複的金鑰映像,當區塊鏈網路中出現重複的金鑰映像時,網路將會將之捨棄,因為這相當於重複花費的攻擊。因此每一個隱匿性地址都只能有一個交易輸出被花費一次(錢包會自動挑選面額最大的來使用),而其餘的交易輸出將會無法被花費/被燒毀。此外,發送到同一個隱匿性地址的交易之間關係將可以被連結起來。

實際上來說這個漏洞可以被如下實施,攻擊者首先產生隨機的交易私鑰,接著修改程式碼使錢包只使用這份金鑰並將數筆交易都送到對方地址(如某交易所的熱錢包地址)的相同隱匿性地址,最後如果攻擊者發送了 1000 次 1 XMR 的交易到交易所,因為交易所的錢包沒有對這種異常狀況發出警告,因此交易所將會歸戶給該攻擊者 1000 XMR 的額度,接著攻擊者就可將之交易為 BTC 並提領出 BTC,最後交易所就會留下 999 筆 無法花費/被燒毀的 1 XMR 交易輸出。

這個漏洞是經由一位社群成員在 Monero reddit 社群上描述了一個可能的攻擊假設後所發現。一個祕密更新檔迅速的被製作出來並隨後在這個 pull request 中提交到原始碼中。

我與一些成員私下地盡可能通知了所有的交易所、線上服務、與商家,請他們將這更新檔應用在 v0.12.3.0 發行版上。在此重申一次,(從上一篇漏洞檢討的文章中提過)顯然這不是個最好的方法: (i)這不可避免地排除了與我們沒有聯絡管道但又是 Monero 生態中重要的對象。(ii) 這可能導致差別待遇的觀感。但是,在這段期間尚未有足夠的時間改善漏洞通報處理流程,雖然這份消息有在公開郵件列表中發送可以視為一個進步。最後我想在這邊強調,任何在 Monero 生態中的服務機構或組織都非常強烈希望可以訂閱公開的郵件列表。 總而言之,這在錢包中的一個漏洞可以讓攻擊者以最少的成本造成服務機構或組織巨大的損失。

幸好,這個漏洞沒有造成交易協定和貨幣發行量上的影響。不過我們的 Monero 是一個社群,非常需要大家關注程式碼,尤其是新提交的 pull request。如果你熟悉C或C++語言,若時間允許,即使僅是是個幫忙一小部分的審查都會對 Monero 的開發產生助益。此外,這個事件也是再一次的重要提醒,加密貨幣與其軟體都還是在發展中階段,容易出現(重大)漏洞。  

本篇消息譯自核心開發團隊網站: https://getmonero.org/2018/09/25/a-post-mortum-of-the-burning-bug.html