安全鷺:Wintermute遭駭客攻擊損失1.6億美金背後的密碼技術詳解
BlockBeats 律動財經 2022-09-24 23:00
從最近的駭客攻擊說起
9 月 20 日,數字資產做市商 Wintermute 首席執行官 Evgeny Gaevoy 宣布其 DeFi 相關業務遭到駭客攻擊,損失約 1.622 億美元,疑因其合約地址「私鑰」遭到暴力破解,引發強烈的市場反響。無獨有偶,9 月 19 日,據 The Block 報導,一名駭客利用 Profanity 漏洞從多個通過 Profanity 建立的以太坊地址中盜取 330 萬美元資產。
Safeheron 密碼學安全團隊跟進分析發現,Wintermute 合約地址採用 Profanity 開源庫生成,而該類 0x000000 開頭的靚號地址,存在被暴力破解的可能性。此前 1inch 曾發文披露該漏洞潛在的安全威脅,那麼,這一系列攻擊究竟是怎麼發生的呢?靚號地址生成開源庫 Profanity 在其中又起到什麼作用呢?接下來,Safeheron 團隊將從以下幾個方面,硬核還原靚號地址被攻擊的全技術過程。
· 什麼是靚號地址?
· Profanity 的靚號地址生成原理
· Profanity 的理想安全性
· 直覺上 Profanity 存在的問題
· Profanity 算法的形式化描述
· 靚號地址的私鑰攻擊原理
· 靚號地址的私鑰攻擊示例
· 攻擊效率分析
· 安全改進建議
· 進一步思考
什麼是靚號地址?
所謂靚號地址,是加密貨幣生態中的很多參與者用以凸顯個性的一種方式。具體來說,它是指這樣的一些地址:
· 開頭 8 個 8:
· 開頭 7 個 0:
· 開頭指定單詞:
· 鏡像地址:
這些靚號地址不僅彰顯個性,也帶來一些其它的好處,比如方便記憶,讓人印象深刻,不容易錯判等等。
為生成這些靚號地址,開發者們提供各式各樣的開源生成工具,而 Profanity 就是以太坊生態中最著名的開源生成工具之一。下面我們將介紹 Profanity 的具體原理。
Profanity 靚號地址生成原理
Profanity 到底是如何生成靚號地址的呢?通過分析 Profanity 開源庫,可以整理出原理圖:
生成步驟如下:
1. 獲取安全隨機數(從硬體或者熵池),作為偽隨機數算法 mt19937 的種子。
2. 利用偽隨機數算法 mt19937 生成種子私鑰(Seed Private Key),然後計算出種子公鑰(Seed Public Key)。
3. 調用 OpenCL 並行計算平台,調用基於種子公鑰(Seed Public Key)的多輪迭代算法,計算大量的候選公鑰(Candidate Public Key)和 eth 地址(Address)。
4. 調用指定靚號篩選器,篩出靚號,並輸出靚號私鑰(Vanity Private Key)和靚號地址(Vanity Address)。
Profanity 庫支持並行計算架構,不僅靚號模式選擇多樣,而且生成效率極高,受到社區廣泛歡迎。然而這也為後面的攻擊埋下伏筆。
Profanity 的理想安全性
理想中的 Profanity 安全性有多高呢?我們一起來看看,如果需要暴力破解這樣一個靚號地址的私鑰,到底需要多長時間。
我們可以大概評估一下總的計算次數。原始種子範圍是(0,2^32),開頭是 8 個 8,假設用戶選擇使用首次匹配地址,則需要計算次數為 2^32 * 2^32 = 2^64 次,而這已經是個不小的量級。
接着評估一下破解時間。以我本地電腦為例,計算首次靚號地址耗時平均大概是 10 秒(簡單三次評估),那麼暴力破解靚號地址私鑰需要耗時(以月計) 2^32 * 10 / (3600 * 24 * 30) = 16570 個月。
如果使用並發加速,同時使用 1000 台跟我個人 PC 同配置的機器,則需要日夜不斷的跑 16 個月。
看起來,要暴力破解似乎也是非常困難的事情。那麼,是否真的安全麼?
直覺上 Profanity 所存在的安全風險點
乍一看來,調用安全隨機數,也進行大量計算,似乎沒有明顯的問題。可是駭客畢竟成功開展攻擊,那麼,問題究竟在哪裡呢?
直覺上看,Profanity 至少有兩大風險點:
· 從硬體或者熵池獲取隨機數時,僅僅獲取 32 bit,這是非常短的。要知道,常見私鑰的長度是 256 bit,遠遠超出 32 bit。
· 在後續的並行多輪計算時,其迭代算法並非使用單向函數(比如 hash 函數)。單向函數會帶來更高的安全性,而不使用單向函數則意味著逆向追溯的可能。
單獨一個風險點未必會立刻致命,但是當兩個一起出現,則可能地覆天翻。
Profanity 算法的形式化描述
在描述攻擊原理之前,我們首先將整個 Profanity 原理抽象一下。
Step 1: 計算種子公鑰(Seed Public Key)
從隨機設備(Random Device)到種子公鑰,中間有兩步:
· 獲取 32 bit 安全隨機數(從硬體或者熵池),作為偽隨機數算法 mt19937 的種子。
· 利用偽隨機數算法 mt19937 生成種子私鑰(Seed Private Key),然後計算出種子公鑰。
對應 32 bit 安全隨機數,我們定義隨機種子空間,R = [0,2^32) ;由於偽隨機數算法 mt19937 本質上是個確定性算法,因此種子私鑰的計算就是確定性的,種子公鑰 的計算也是確定性的。如下所示:
顯然,種子公鑰的數量是 2^32。
Step 2: 計算候選公鑰(Candidate Public Key)
Profanity 從種子公鑰開始進行並發多輪迭代(Iteration)操作,生成一系列的候選公鑰。整個迭代操作本質上是一個以指定種子公鑰為中心的公鑰搜尋和遍歷算法。具體的,迭代是基於輪序號(round,記為 r)和輪內序號(foundID,記為 fid ) 兩個維度下的線性搜尋操作。
迭代算法如下:
Step 3: 過濾靚號
靚號地址的私鑰攻擊原理
現在我們考慮如何對上圖中的私鑰機制進行攻擊。
Step 1: 窮舉種子公鑰集合
Step 2: 計算真實靚號公鑰
具體算法參見 此處 。
Step 3: 計算候選公鑰集合的一個平移集(Shift Set)
為了更好的說明,不妨假設有一個 3 輪、輪內迭代次數也是 3 的例子,以下是基於種子公鑰 f(2) 的一個候選公鑰集合:
候選公鑰集合中的某個公鑰將被篩選出來為靚號公鑰,不妨設被選出來的靚號公鑰為:
如圖所示,我們求出平移集合:
Tips:
· 為什麼命名為「平移集合」?這是因為平移集合和候選公鑰集合在二維空間中就是兩個矩陣,這兩個矩陣大小相等,可能相鄰,也可能有一部分元素重合。看起來,基於靚號公鑰,對候選公鑰集合做平移,即可得到平移集合。如下圖所示:
· 為什麼求平移集合?因為平移集合中包括種子公鑰。比如上圖中的 f(2) 就是種子公鑰。
Step 4: 集合求交
該命題保證一定能夠找到與靚號公鑰關聯的種子公鑰。
注意:集合求交很多不同的實現方法,比如數據量不大是可以直接通過查數據庫,如果數據量太大,可以結合一些成熟算法解決。
Step 5: 計算靚號私鑰
靚號地址攻擊示例
現在我們通過一個具體的例子,來展示如何獲取靚號地址的私鑰。待破解的靚號地址如下,這是一個以「dead」單詞開頭的地址:
Step 1: 窮舉種子公鑰集合
Step 2: 計算真實靚號公鑰
找到該地址的鏈上交易,從簽名中恢復公鑰,如下所示:
0x0488dff9528cc2fc582e11688abce90cd84d8c805424fa3c761f50ad96b877a8cf3c3b0796ec099a05403562a4e0f8ecec9c511265e12ae45793bad11111e11e4d
Step 3: 計算候選公鑰集合的一個平移集(Shift Set)
Tips:
1. 計算平移集合的過程中,平移集合中所有元素(即公鑰點)相對於靚號公鑰的偏移也被記錄下來。
2. 關於平移集合的,參數的選擇,可以根據"靚號地址」的難度來設計平移集的大小。
Step 4: 集合求交
Step 5: 計算靚號私鑰
從靚號私鑰計算靚號公鑰,用於復驗,復驗正確,至此攻擊成功結束。
攻擊效率分析
詳細分析
攻擊步驟一共 5 步,Step 2 和 Step 5 基本不耗時,Step 1 可以預先計算,所以也可以省去 Step 1 的耗時。最終,主要耗時都在 Step 3 和 Step 4。
着重說一下 Step 3,Step 3 是需要計算候選集合的一個平移,理想狀態下其規模跟候選公鑰集合一樣,因此計算次數為。這是個什麼概念呢?它意味著,如果不考慮集合求交的耗時,私鑰破解耗時跟靚號地址生成耗時大致是一樣的。
Tips:
· 平移集合的設計和計算方式直接影響到攻擊的效率。
· 在實際攻擊操作時,由於候選公鑰集合是未知,我們可以根據靚號難度來估算候選公鑰集合的大小,從而設計平移集合。
· 平移集合基數可能會略大於候選公鑰集合。
實例分析
我們給一些具體的例子,讓大家有個直觀的印象:
還有不少的情況,平移集甚至只有百萬量級大小,更是反手可破。
效率總評
基本結論是攻擊效率極高,不用付出太高的代價,就能破解幾乎所有的 Profanity 靚號地址私鑰。
· 如果不考慮集合求交的耗時,私鑰的破解速度可以逼近靚號地址的生成速度,這是非常可怕的,完全摧毀 Profanity。
· 用戶的不好的使用習慣會大大提升私鑰破解的風險,一般來說,Profanity 越早生成出來的地址,搜尋空間越小,風險越大,越容易破解。由於大部分用戶都喜歡用最早生成出來的幾個靚號地址,導致大部分 Profanity 用戶的靚號地址私鑰隨時可能被破解。
Profanity 的安全改進建議
主要是兩點建議:
· 從硬體或者熵池獲取隨機數作為種子時,直接取出 256 bit。
· 並行多輪迭代計算時,使用單向函數(比如 hash 函數)。
進一步思考
如果 Profanity 算法中生成候選公鑰時使用單向函數,算法是否安全?
如果隨機種子的長度提高到 64 bit,我們是不是就能用呢?
答案是否定的。64 bit 並不是足夠長的隨機數,同樣存在生日攻擊的問題,只不過 50% 碰撞機率的人數提高到大約 50 億而已,這依然不夠安全。
我們還能使用靚號麼?
首先,Profanity 生成的靚號地址都存在致命的風險,因此我們強烈建議,所有的 Profanity 用戶都應該將資產轉移到其它安全的地址上。其次,我們還是可以使用靚號地址的。並不是所有的靚號地址都有問題,如果不一味強調效率,選擇用更安全的算法來計算,那麼就能生成安全的靚號地址。
關於私鑰的安全生成有什麼更好的建議?
私鑰就是隨機數,要想讓私鑰足夠安全,就要足夠隨機。獲取安全隨機私鑰的方法多種多樣。
· 如果有經過認證的安全硬體,可以使用安全硬體提供的安全隨機數。
· 對於足夠複雜的運算平台,包括常見的各類 PC 和行動端,環境噪聲足夠複雜,使用平台自帶的熵池和偽隨機數發生器便已足夠隨機。
· 如果是簡單平台,比某些硬體錢包,則需要從外部導入隨機種子。方式包括不限於導入隨機文件、環境照片、語音、影音等等。
· 還有一種更安全的方式,通過 MPC 聚合多平台的隨機性。基於 MPC 從多平台生成私鑰分片,即便單平台私鑰不夠隨機或者遭遇駭客攻擊,整個 MPC 錢包私鑰依然是安全的。
暢行幣圈交易全攻略,專家駐群實戰交流
▌立即加入鉅亨買幣實戰交流 LINE 社群(點此入群)
不管是新手發問,還是老手交流,只要你想參與虛擬貨幣現貨交易、合約跟單、合約網格、量化交易、理財產品的投資,都歡迎入群討論學習!
- 從零開始學合約系列講座熱烈報名中
- 掌握全球財經資訊點我下載APP
文章標籤
上一篇
下一篇