0x00 前言
区块链的安全需求越来越多,下面就将这些需求一一拆分,看看区块链安全需求到底是个什么样子。
0x01 拆分
目前针对安全服务行业的区块链安全需求,更多的是基于其上层应用(红色箭头指向)比如数字货币交易平台、移动数字货币钱包、DAPP等
在实际测试中也是按照这几类进行的划分,下面我会针对这几类常见的区块链应用说明其使用过程中存在的风险,如何避免风险,以及一些实际操作过程中的案例。
0x02 金融新战场-数字货币交易所
数字货币交易所,常见火币,OKcoin,币安,都是我们这些韭菜挣(pei)钱(guang)的好去处。对于这类平台就按照平时对Web站点的渗透思路进行挖掘就行,但是有一点千万记住,别上来就扫描器,Sqlmap,御剑什么的,否则今天的活也就别干了。根据测试经验,这种费力不讨好的活就放在最后,上来可以先选择逻辑进行测试,因为数字货币平台的逻辑来来回回就那么几样:注册、登录、地址管理(充币、提币、交易)、委托交易查询、买入卖出(法币、币币、杠杆和期货)、账号安全(密码修改、谷歌验证、手机和邮箱验证)、买家身份实名认证、场外交易时使用的支付宝、微信和银行卡的地址和二维码等、以及多平台快速交易使用的API接口管理等。
从功能上其实并不复杂,功能与功能之间的业务关联性也是显而易见:
注册->实名认证->手机/邮箱/谷歌验证码->法币交易获取代币->币币交易/杠杆交易->提币到其他地址
这里给出两个案例
案例一:收款账户处的存储型XSS
在微信账号,支付宝账号处可插入恶意脚本,恶意脚本随交易广告下发
当用户与恶意广告用户进行交易时,需要显示账户信息,此时触发该XSS
此处的XSS影响比较大,可以get到其他与攻击者进行交易的身份认证信息。
案例二:无密买入卖出功能的CSRF漏洞
进入某币交易模块,设置交易措施为每次交易不输入密码
构造CSRF表单并生成伪造交易请求的表单,因挂单交易是自动确认,所以存在极大风险,易被恶意攻击进行交易操作。
当用户访问并点击时,表单内容提交给交易网站,买入卖出操作成功
0x03 放在兜里的记账本-移动数字货币钱包
钱包从早期的PC端全节点钱包(体积大又不能携带)到现在到小而轻的移动钱包(就是APP了),将个人数字资产的管理做到更快截和方便。如图,移动钱包可以用于资产的查看,转账,地址管理等不需要全节点参于的功能。
重点关注以下四个方面:
私钥生成与存储的安全
助记词生成与存储的安全
Keystore生成与存储的安全
和钱包口令生成与存储的安全
针对四个方面,可以总结出多个渗透维度
密钥保存维度:私钥是否明文存储本地,keystore是否明文存储本地、助记词是否明文存储本地
钱包备份:私钥导出过程安全(检查私钥导出过程是否阻止屏幕劫持,是否保存在日志当中或临时文件当中)
keystore 导出过程安全:检查keystore导出过程是否阻止屏幕劫持,是否保存在日志当中或临时文件当中)
转账过程:转账数据的机密性和完整性
0x04 区块链应用新宠-DAPP
DAPP-分布式应用:基于不同的底层区块链开发平台和共识机制。现在绝大多数都是在以太坊(Ethereum),比如各种加密游戏,分布式宠物 ,百度的莱茨狗,网易 的网易星球,360的区块猫 ,小米的区块链游戏加密兔等等。
这里给出一个区块链养猫例子。
案例一:
全美最火的区块链宠物,价格也不贵,0.0019 ETH 大概6块左右
这个DAPP与传统的Web或者页游最大的区别就是其去中心化的结构,除了浏览器和服务器外,所有的交换操作都写入到了以太坊中的多个智能合约当中,对操作过程和结果进行安全的记录。
对这类DAPP进行渗透的时候需要考虑到整个DAPP的身份认证机制是基于密码学中的 公钥认证机制(私钥签名,公钥验签),那么后端服务器是否能够正确的安全的验证签名后的信息就是很关键的点,比如下图中的请求(这是一个DAPP和以太坊地址绑定的过程),sign是对以太坊地址的签名,服务器处理请求时如果未对请求中的sign进行安全校验,那么M ITM手段可以伪造以太坊地址进行恶意绑定,同时如果未对溢出进行防御,比如 AAAA*10000… 也会发生拒绝服务的问题。
另一个问题是,以太坊modifiers(修改器)特性导致的特权函数的恶意调用。在以太坊应用中modifiers会被用作定义某些只能被特定地址(特权地址)调用的函数。在调用函数之前需要对请求的私钥进行验签,此处就会存在一个风险,服务器如果能保证这些私钥不丢失,一旦特定地址的私钥丢失,那么特权函数就会被恶意调用造成无法估计的后果。
0x05 区块链中坚力量-智能合约
智能合约(Smart contract):以信息化方式传播、验证或执行合同的计算机协议。在没有第三方的情况下进行可信交易,这些交易可追踪且不可逆转
现在做智能合约审计的公司有,慢雾科技,降维科技和知道创宇等。但从审计方向上讲大方向上是对合约中危险函数的使用,加密的生成和数据传递等方面进行安全审计。
下面给出一些智能合约审计过程常关注的问题
1. 重入问题-关键函数被恶意多次调用
图:
当使用call.value()()处理转币时,会将剩余的 Gas 全部给予外部调用(fallback 函数)智能合约的fallback函数内递归withdrawBalance()便可以转走更多的币。攻击者可以部署一个包含恶意递归调用的合约将公共钱包合约里的 Ether 全部提出。
修复:使用send() 和 transfer() 转币,只会传递2300Gas供调用,防止重入攻击。
2. 访问控制-初始化函数可被任何人调用
风险:
合约 A 以 call 方式调用外部合约 B 的 func() 函数,在外部合约 B 上下文执行完 func() 后继续返回 A 合约上下文继续执行;A 以 delegatecall 方式调用时,相当于将外部合约 B 的 func()代码复制过来(其函数中涉及的变量或函数都需要存在)在 A 上下文空间中执行。当合约币中存在恶意代码,直接对合约A的运行逻辑造成危害。
修复:
每一个外部调用都会有潜在的安全威胁,尽可能的从你的智能合约内移除外部调用。如果你没法完全移除外部调用,另一个简单的方法来阻止这个攻击是确保你在完成你所有内部工作之前不要进行外部调。
3. 不安全的函数返回值-函数返回值未进行检查和判断
风险:
使用send() 函数进行转账时,因为没有验证 send() 返回值,如果msg.sender 为调用失败,则send() 返回 false。未验证false并进行回滚,最终导致账户余额减少了,钱却没有拿到。
修复:
使用transfer() 进行安全的转币操作,当发送失败时会自动回滚状态,该函数调用没有返回值。
4. 跨函数竞争-在余额清零前调用转币
风险:
使用withrawBalance函数时调用transfer(),此时,withdrawBalance没有执行到userBalances[msg.sender] = 0;(余额清0)那么余额就没有被清零,能够继续调transfer()重复转走代币。攻击者利用该漏洞进行恶意提币和转账。
修复:
先减少发送人的余额再进行价值转移;另外一个解决方法就是用互斥锁,从而一起缓解各种竞争条件。
5. 溢出-数值未进行校验造成的溢出攻击
向上溢出:
如果任何用户都有权利更改uint的值,让其大于最大值(2^256),因为溢出而被设置为0
向下溢出:
如果一个uint别改变后小于0,那么将会导致它下溢并且被设置成为最大值(2^256)
修复:
使用SafeMath的安全方法,进行数值的安全处理。
6. 伪随机性-随机数的生成过程可预测
风险:
合约中的存储数据都能在链上查询分析得到。如果合约代码没有严格考虑到链上数据公开的问题去使用随机数,可能会被攻击者恶意利用来进行“作弊” 。如果seed的使用不够随机,那么产生的随机数值就可预测。
修复:
所提币、钱包转账,所以除了在编写合约的时候需要严格验证输入数据的正确性,而且在 Off-Chain 的业务功能上也要对用户所输入的地址格式进行验证,防止短地址攻击的发生。
7. 短地址攻击-利用EVM解析补0操作恶意提币
风险:
EVM将会为不满足ERC20的代币交易地址补上尾部的零,导致转账扣除的地址处理时发生变化。攻击者通过这种方式从其他地址进行恶意扣币。
修复:
所提币、钱包转账,所以除了在编写合约的时候需要严格验证输入数据的正确性,而且在 Off-Chain 的业务功能上也要对用户所输入的地址格式进行验证,防止短地址攻击的发生。
8. 智能合约审计工具
https://github.com/melonproject/oyente
9. 审计步骤
面谈开发者->评审.sol文件->编译->分析代码流->运行oyente->运行Manticore->运行MAIAN->手工复审
0x06 区块链源头-密码学与密钥安全
区块链为什么有那么大的魔力,在于它的底层原理,在于它的源头,那个技术背书-密码学
区块链中的哪些地方用到了密码学:
1.哈希算法 比特币系统中使用的两个哈希函数分别是:SHA-256,主要用于完成PoW(工作量证明)计算;RIPEMD160,主要用于生成比特币地址;
2.Merkle哈希树基于哈希值的二叉树或多叉树,在计算机领域,Merkle树大多用来进行完整性验证处理,在分布式环境下,其进行完整性验证能大量减少数据传输和计算的复杂程度;
3.椭圆曲线算法 比特币中使用基于secp256k1椭圆曲线数学的公钥密码学算法进行签名与验证签名,一方面可以保证用户的账户不被冒名顶替,另一方面保证用户不能否认其所签名的交易。用私钥对交易信息签名,矿工用用户的公钥验证签名,验证通过,则交易信息记账,完成交易;
4.对称加密算法比特币官方客户端使用AES(对称分组密码算法)加密钱包文件,用户设置密码后,采用用户设置饿密码通过AES对钱包私钥进行加密,确保客户端私钥的安全。
最终的原则还是:保护好私钥。从私钥的整个生命周期来看,可以从以下几个方面进行安全分析
1.硬件模块抗拆毁、抗功耗分析、错误注入攻击等侧信道分析能力;
2. 随机数生成算法强度,随机数发生器产生随机数的随机性;
3. 密钥与密钥参与运算过程都在硬件当中;
4. 密钥导入导出过程全在硬件中实现;
5. 密钥恢复与备份; 主要关注加密货币,私钥通过助记符来协助恢复, 助记符的安全是关键。
现有的安全措施—算法白盒
静态白盒:算法+密钥+白盒密码技术->算法密码库(白盒库) 静态白盒更新密钥,需要重新生成白盒库。
动态白盒:白盒库无需更新,密钥+白盒密码技术->白盒密钥 白盒密钥传入相匹配的白盒库可以进行正常的加密或解密功能。
实现过程如下图:
现有的安全措施—密钥随机化:
椭圆曲线算法实现生成密钥 再配合代码加固,代码混淆方法
现有的安全措施—协同签名/解密:
需要一个可信的后台服务器,解密/签名密钥由客户端和服务器端协同产生,且子密钥由各自保管。这种方法安全性和效率相对较高。