【译】 Stealing the funds of all HTC EXODUS 1 users (HTC 区块链钱包安全漏洞分析)
HTC EXODUS 1手機帶有集成的硬件錢包。該錢包允許通過拆分并將其發送給“受信任的聯系人”?來備份其主種子。通常需要三個受信任的聯系人來重建整個種子。我們表明,任何受信任的聯系人或破壞了該受信任聯系人的電話的攻擊者都可以收回全部種子并竊取EXODUS 1所有者的所有資金。如果在2019年4月之前使用社交密鑰恢復功能,我們強烈建議HTC EXODUS 1用戶將其資金轉移到另一種子。
介紹
在2018年,HTC推出了其首款面向區塊鏈的智能手機EXODUS 1。與其他智能手機相比,它具有硬件錢包功能,可將主種子存儲在安全的區域中。這樣可以確保即使具有root特權的攻擊者也無法訪問主種子-它在安全區域內被加密。
圖1:HTC EXODUS 1設備?
我們對此款(硬件)錢包特別感興趣,因為它提供了一個不錯的功能:Social Key Recovery。在此博客文章中,我們將重點介紹EXODUS 1的特定功能。
它包含一個原始機制,可以強制執行種子的備份。種子被分成五份,每份被發送到受信任的聯系人。如果用戶丟失了手機,他們將可以通過請求其五個受信任聯系人中的三個來傳播種子來重建種子。份額數(5)和閾值(3)是固定的。
我們將首先提供有關實施社交密鑰恢復的更多詳細信息。然后,我們將介紹兩種攻擊方法:
- 第一個演示了如何將閾值從三個可信聯系人降低到兩個。
- 第二個示例演示了如何將閾值從三個受信任的聯系人降低到一個,這意味著您的任何一個受信任的聯系人都可以檢索主種子并訪問您的資金。
社交密鑰恢復
主種子備份是硬件錢包用戶的常見問題。僅從該種子生成每個用戶機密。必須備份該種子,以確保您的錢包丟失并不意味著您的秘密丟失:可以從備份的種子將其恢復到新的錢包中。
如何備份種子?大多數硬件錢包都會提出一份紙質回收表(圖3),用戶必須在紙上寫下其BIP39助記符(助記符是將您的種子表示為人類可讀的單詞的一種方式)。但是,要保證此紙張的安全性并非易事,因此為此設計了一些專用設備(圖2)。例如,可以使用加密鋼來防止助記符種子惡化。
圖2:Cryptosteel-備份種子的設備?
另一種解決方案是擁有一個備份硬件錢包,并用相同的種子初始化。但是,沒有完美的解決方案可以解決所有問題。
圖3:總帳回收表?
圖4:實踐中的恢復表存儲?
HTC EXODUS 1帶有自己的備份機制:社交密鑰恢復。用戶的種子被分成共享,并發送給受信任的聯系人。1或2?股的知識不會帶來有關種子的任何信息。3?股的唯一知識可以重建完整的種子。在該方案中,主種子永遠不會在單個位置完全備份。
HTC硬件錢包采用名為Zion的Android應用程序的形式,以及存儲種子并執行敏感操作的trustlet(在智能手機安全OS中執行的安全應用程序)的形式(圖5)。秘密共享也在trustlet中計算:在下面,研究的機制在安全OS中實現。
圖5:Zion-體系結構概述
?
Shamir’s Secret Sharing
?
此問題可以通過以下方法解決:
- 安全地存儲多項式系數,以便以后可以恢復它們以生成其他份額,
- 或僅在拆分前保持PRNG狀態。
HTC使用的SSS實現受一個開源項目的啟發,可在此處獲得。此開源實現一次生成所有共享。一個人不能要求一個份額。為了允許隨意添加受信任的聯系人,HTC修改了實現,但犧牲了安全性。
HTC選擇保留PRNG種子。但是該實現還使用了DRBG:這可確保輸出是可預測的,并且生成的系數將始終相同。DRBG使用的種子(即PRNG狀態)存儲在加密分區內,僅可用于安全OS。
隨機數生成器:
原始實現的RNG(不確定的)已由以下功能代替:
#define RANDOM_POOL_SIZE 128static uint8_t random_pool[RANDOM_POOL_SIZE];size_t sss_rand(uint8_t *data, size_t len) {if (len == 0) {return 0;}while (len > RANDOM_POOL_SIZE) {memcpy(data, random_pool, RANDOM_POOL_SIZE);data += RANDOM_POOL_SIZE;len -= RANDOM_POOL_SIZE;}memcpy(data, random_pool, len);return len; }PRNG僅返回隨機緩沖區的內容。此128字節的緩沖區由函數手動更新sss_update_secure_random_buffer:
void sss_update_secure_random_buffer(const uint8_t *entropy, size_t size) {SHA256_CTX ctx;uint8_t digest[SHA256_DIGEST_LENGTH];uint8_t *p = random_pool;sha256_Init(&ctx);sha256_Update(&ctx, entropy, size);sha256_Final(digest, &ctx);for (int i = 0; i < 4; i++) {memcpy(p, digest, SHA256_DIGEST_LENGTH);sha256_Init(&ctx);sha256_Update(&ctx, p, SHA256_DIGEST_LENGTH);sha256_Final(digest, &ctx);p += SHA256_DIGEST_LENGTH;} }我們可以看到,作為輸入參數傳遞給此函數的熵完全確定了PRNG的內部狀態,因此也確定了PRNG的輸出。正如我們之前所解釋的,此行為是HTC想要的。該熵來自智能手機TRNG,其值由返回qsee_prng_getdata。使用128位熵并將其存儲在加密分區中。
知道PRNG的輸出足以完全確定整個隨機輸出序列。例如,如果我們知道返回的前32個字節,那么我們知道接下來的字節將對應于這些字節的SHA-256,然后對應于該值的SHA-256,依此類推……此外,PRNG的周期非常短128個字節。
但是,PRNG缺乏魯棒性對我們的攻擊無濟于事:將使用PRNG的狀態在兩次調用之間固定的事實。如果兩次之間的未調用,sss_rand則兩次調用將始終返回相同的值sss_update_secure_random_buffer。
HTC Social Key Recovery Shares計算
共享秘密是錢包的種子,用于導出每種加密貨幣的所有密鑰。但是該實現增加了一個加密層來保護秘密。選擇的密碼是基于Salsa20和Poly1305(與TweetNaCl相同)的經過身份驗證的流密碼。
Fig. 6: The bitslice function
?
/** Create `n` shares with theshold `k` and write them to `out`*/ void sss_create_shares(sss_Share *out, const unsigned char *data,uint8_t n, uint8_t k) {unsigned char key[32];unsigned char m[crypto_secretbox_ZEROBYTES + sss_MLEN] = { 0 };unsigned long long mlen = sizeof(m); /* length includes zero-bytes */unsigned char c[mlen];int tmp;sss_Keyshare keyshares[n];size_t idx;/* Generate a random encryption key */sss_rand(key, sizeof(key)); .../* Generate KeyShares */sss_create_keyshares(keyshares, key, n, k); ...Here is the?sss_create_keyshares?code :
/** Create `k` key shares of the key given in `key`. The caller has to ensure* that the array `out` has enough space to hold at least `n` sss_Keyshare* structs.*/ void sss_create_keyshares(sss_Keyshare *out,const uint8_t key[32],uint8_t n,uint8_t k) { ...uint8_t share_idx, coeff_idx, unbitsliced_x;uint32_t poly0[8], poly[k-1][8], x[8], y[8], xpow[8], tmp[8];/* Put the secret in the bottom part of the polynomial */bitslice(poly0, key);/* Generate the other terms of the polynomial */sss_rand((void *)poly, sizeof(poly)); ... sage: load("rebuild_secret.py") 0102030405060708090a0b0c0d0e0f100102030405060708090a0b0c0d0e0f100a2b7065ad61a3ca403d62f61b21fabbab4de9811b3d2ce55c847488f231bf4e Recovered 1 secret in 0.111693s我們剛剛展示了如何降低到22重建機密所需的份額數(而不是33)。除了五分之三的閾值不再有效這一事實外,我們仍然認為安全威脅是不可忽略的。理想情況下,用戶應將種子分成5個5彼此不認識的可信任聯系人。實際上,使用55?受信任的聯系人,即使其中一些彼此認識。
借助這種攻擊,惡意聯系人只需說服(或折衷)其他信任的聯系人即可完全收回種子并訪問資金。
打破機制
受先前攻擊影響的固件如下(使用了歐洲ID):
- 固件1.47.2401.2,它似乎是初始固件;
- 固件1.53.2401.2,于2019-12-18。
2019年2月19日,發布了第三個固件。
通過研究這一點,我們非常驚訝地注意到sss_update_secure_random_bufferPRNG初始化函數從未被調用過。PRNG始終返回相同的值:其熵緩沖區,以固定值初始化(可能通過測試向量驗證)。我們認為,trustlet已使用測試選項進行編譯,而該選項應永遠不會在生產中使用。結果,用于加密種子的密鑰是固定的。由于此密鑰已發送給每個聯系人,因此任何人都可以解密種子并訪問資金。
<span style="color:#514134"><span style="color:#2e2925"><code>secret_key <span style="color:#000000"><strong>=</strong></span> b<span style="color:#dd1144">"</span><span style="color:#dd1144">\x0e\x74\xcd\x69</span><span style="color:#dd1144">..."</span> box <span style="color:#000000"><strong>=</strong></span> nacl<span style="color:#000000"><strong>.</strong></span>secret<span style="color:#000000"><strong>.</strong></span>SecretBox(secret_key) nonce <span style="color:#000000"><strong>=</strong></span> b<span style="color:#dd1144">"</span><span style="color:#dd1144">\x00</span><span style="color:#dd1144">"</span> <span style="color:#000000"><strong>*</strong></span> <span style="color:#009999">24</span> encrypted_seed <span style="color:#000000"><strong>=</strong></span> share1[<span style="color:#009999">1</span> <span style="color:#000000"><strong>+</strong></span> <span style="color:#009999">32</span>:] seed <span style="color:#000000"><strong>=</strong></span> box<span style="color:#000000"><strong>.</strong></span>decrypt(nonce <span style="color:#000000"><strong>+</strong></span> encrypted_seed)[:<span style="color:#009999">16</span>] <span style="color:#000000"><strong>print</strong></span>(mnemonic<span style="color:#000000"><strong>.</strong></span>Mnemonic(<span style="color:#dd1144">'english'</span>)<span style="color:#000000"><strong>.</strong></span>to_mnemonic(seed)) </code></span></span>結論
負責任的披露
我們于2019.02.15向HTC Exodus披露了所有上述缺陷。
兩個月后,還披露了其他漏洞(觸摸屏驅動程序內部,受信任的UI內部以及ETH / BTC事務解析中的內存損壞)。HTC安全團隊已經找到并修復了它們。
2019年3月5日,HTC Exodus團隊在巴黎并借此機會訪問了我們。他們甚至有機會進入Donjon。
HTC?在2019.03.25發行了新固件(1.62.2401.7)解決了所有這些問題。SSS修補程序包括使用可靠的PRNG,并將每個生成的共享保存在安全存儲中。每當添加新的受信任聯系人時,都會使用這些共享。
HTC Exodus于2019.04.05開始為Zion Hardware Wallet設立賞金計劃。
在這些討論之后,HTC向我們表明,此漏洞的披露觸發了他們自己賞金計劃的創建。當我們在建立賞金計劃之前報告了這些錯誤時,我們沒有得到任何賞金,但是當他們訪問我們時,我們得到了出埃及記襯衫和貼紙。:) 非常感謝!
帶走
我們研究了HTC Exodus 1手機的硬件錢包,并發現了社交密鑰恢復機制上的兩個關鍵漏洞。在攻擊者能夠在任何Zion信任聯系人的Android手機上執行代碼(Android漏洞,常規Android應用)的情況下,他可能會竊取相應EXODUS 1所有者的資金?;蛘?#xff0c;受信任的聯系人可以直接訪問種子。這些漏洞已得到正確修補。
不過,我們強烈鼓勵所有使用社交密鑰恢復來更改種子(并轉移其資金)的EXODUS 1用戶。確實,他們的種子可能早些受到破壞,或者仍然可以通過不會更新Zion的受信任聯系人而受到破壞。
?
?
總結
以上是生活随笔為你收集整理的【译】 Stealing the funds of all HTC EXODUS 1 users (HTC 区块链钱包安全漏洞分析)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTML常用标签、特殊字符、路径
- 下一篇: 深度优化LNMP之MySQL