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所有者的资金。或者,受信任的联系人可以直接访问种子。这些漏洞已得到正确修补。

不过,我们强烈鼓励所有使用社交密钥恢复来更改种子(并转移其资金)的EXODUS 1用户。确实,他们的种子可能早些受到破坏,或者仍然可以通过不会更新Zion的受信任联系人而受到破坏。

【译】 Stealing the funds of all HTC EXODUS 1 users (HTC 区块链钱包安全漏洞分析)相关推荐

  1. HTC公布第二款区块链手机Exodus 1s:或将于9月前发售

    [TechWeb]5月12日消息,今年4月,HTC 首席运营官陈信生在公开活动上表示,公司将于今年下半年推出第二款区块链手机.如今,Exodus 1s官方海报曝光,但从外形看与上一代没什么区别. 20 ...

  2. HTC推区块链手机;微软终于更新Windows Notepad;Python之父退出决策层 | 极客头条...

    「CSDN 极客头条」,是从CSDN网站延伸至官方微信公众号的特别栏目,专注于一天业界事报道.风里雨里,我们将每天为朋友们,播报最新鲜有料的新闻资讯,让所有技术人,时刻紧跟业界潮流. 快讯速知 HTC ...

  3. 【译】用Java创建你的第一个区块链-part2:可交易

    转自:http://www.spring4all.com/article/814 区块链是分布式数据存储.点对点传输.共识机制.加密算法等计算机技术的新型应用模式.所谓共识机制是区块链系统中实现不同节 ...

  4. 区块链日记——【译】用Java创建你的第一个区块链-part2:可交易

    本文转自http://www.spring4all.com/article/814 [译]用Java创建你的第一个区块链-part2:可交易 区块链是分布式数据存储.点对点传输.共识机制.加密算法等计 ...

  5. HTC Vive会是HTC的下一个增长引擎吗?

    2014年初,Facebook以20亿美元收购虚拟现实技术公司Oculus的大手笔点燃了世界对虚拟现实的热情.时至今日,虚拟现实玩家已经不仅仅是Facebook.Facebook之外,微软.谷歌.HT ...

  6. 【译】用JavaScript写一个区块链

    原文:Writing a tiny blockchain in JavaScript 作者:Savjee.be 译者:JeLewine 几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数 ...

  7. htc+one+m8+联通+android+5,HTC One M9和HTC M8哪个好

    HTC One M9和HTC M8哪个好 屏幕方面,HTC One M9屏幕尺寸维持在了5英寸,这也是目前安卓旗舰手机最常见的屏幕尺寸,可以很好地保证单手操作体验和视觉效果.屏幕分辨率为1920×10 ...

  8. htc g1 android4.0,HTC解锁其旧款android手机HTC G1的BL

    来源: IT168 作者: 梁子 2012-03-08/17:23 HTC终于发布了其旧版Dream手机的解锁引导程序,该手机是HTC第一款Android智能机,也是全球首款android手机,于三年 ...

  9. HTC新渴望VC HTC T328d移动上网补丁设置

    HTC新渴望VC HTC T328d移动上网补丁设置: 1.不论你的手机有没有进行解锁或者ROOT,都可以使用这款HTC T328d补丁: 2.首先安装HTC T328d移动上网补丁,安装好后手机千万 ...

最新文章

  1. MySQL高可用架构InnoDB Cluster (和NDB Cluster是两码事)
  2. (转载)项目实战工具类(一):PhoneUtil(手机信息相关)
  3. 非常酷!10个基于 HTML5 的字体应用演示网站
  4. 【linux 开发】定时器使用setitimer
  5. 【转】VS工具:实时可视化树
  6. javascript canvas生成分形图练习
  7. 小强的HTML5移动开发之路(51)——jquerymobile中改善页面访问速度
  8. Silverlight中Shape,Geometry
  9. 迭代器修改元素_设计模式-迭代器模式
  10. 访问samba服务器提示无权限使用网络资源
  11. 大物 磁场对载流导线的作用 中dl转化为dx
  12. 计算机专业保研面试备考:高等数学
  13. 阿里云对象存储OSS中上传的资源在生成URL链接时直接在浏览器中打开而不是下载的问题解决方法
  14. tf.app.flags
  15. 普通路由器改4g路由器_4G工业路由器物联卡批发价格是多少?良心厂家推荐
  16. Qt错误:LNK1181:无法打开输入文件“debug\main.obj”
  17. 原来路由器的USB接口这么强大!这样设置,路由器秒变私有云盘
  18. 时序预测 | MATLAB实现ARIMA时间序列预测(GDP预测)
  19. FANUC机器人IO通信板卡(CRMA15和CRMA16)详解
  20. 什么笔记本适合python_python什么样的笔记本

热门文章

  1. IE报vuex requires a Promise polyfill in this browser问题解决
  2. HttpContext.Cache属性
  3. [转]matlab 函数三种定义方式
  4. BlogEngine(4)---Widget小部件
  5. 子窗体与父窗体之间相互调用其方法的实现
  6. 你为何要带着我的爱远走
  7. $$和$BASHPID区别
  8. 人生苦短,Let's Go!
  9. Python学习笔记:常用内建模块2:collections
  10. Matlab函数解释:colormap