智能合约随机数安全问题合约整理与分类

目标

  • 本文的目标是整理50个左右的随机数安全问题。
  • 总结出随机数安全问题的一些规律。
  • 为设定诸如Predictability等评价标准寻找灵感。

手段

  • 不思考业务逻辑,单纯从代码出发,理解生成随机数的过程。
  • 思考操控这个随机数的难度如何。

如何阅读本文

  • https://etherscan.io/address/替换成下面的合约代码#code
2. 0xb8797a4ba7402d8a9ab62c4a12ef8846f1ea9a80
  • 智能合约名:GoldenKingdom
  • 智能合约类型:彩票。
  • 随机数生成方式:LuckyDraw.sol23行,使用链上变量block.difficulty, now(0.7之后强制用block.timestamp)以及players的地址。
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;使用“私有”变量(可以被观测到内部信息)。
  • 识别思路:
    • 定位产生随机数的函数。
      • 通过abi.encodePacked进行定位。
      • 通过keccak256进行定位。
      • 通过函数名random进行定位。
    • 定位随机数种子:
      • block.difficulty为链上变量。
      • now为链上变量。
      • players为私有变量。
    • 定位函数传递:
      • 调用时进行取模操作。
    • 综上:
      • 这是一个产生随机数行为的合约,风险极大。
3. 0x9c008a22d71b6182029b694b0311486e4c0e53db
  • 智能合约名:Apymon
  • 智能合约类型:NFT。
  • 随机数产生方式:Apymon.sol113行,使用链上变量blockhash(block.number)。
  • 问题:运行时blockhash(block.number)还未产生,结果为0。[1]
  • 分类:误使用blockhash(block.number)作为随机数熵源。
  • 识别思路:
    • 定位产生随机数的函数。
      • 通过abi.encodePacked进行定位。
      • 通过keccak256进行定位。
    • 定位随机数种子:
      • blockhash(block.number)
    • 定位后续操作:
      • 进行取模。
    • 结论:
      • 这是对于blockhash的误使用,风险极大。
4. 0xc1ebbce86a24b6e045fc9f46af342d8dabe14272
  • 智能合约:League
  • 智能合约类型:彩票。
  • 随机数产生方式:League.sol 221行,直接使用链上变量。
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量;依赖于调用该合约的sender。
  • 识别思路:和2的基本相同。
5. 0x8dc74D28B9821f7f9d0e95AB2D3C66f5276AC474
  • 智能合约名:EthexJackpot
  • 智能合约类型:竞猜下次的blockhash。
  • 参考网址:https://bitcointalk.org/index.php?topic=5120151.msg50562585#msg50562585
  • 随机数产生方式:??
  • 问题:有可能被操控。
  • 分类:可能被操控。
  • 识别思路:??
6. 0xd5A3A5f35e8Db7740fF644752bce389fC958d5c1
7. 0xA11E4ed59dC94e69612f3111942626Ed513cB172
  • 合约名:EtherLotto
  • 智能合约类型:彩票
  • 随机数产生方式:第39行 var random = uint(sha3(block.timestamp)) % 2;直接使用链上变量。
  • 问题:非常容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源。
  • 识别思路:
    • 定位变量名:
      • 找到random。
    • 定位变量来源:
      • 完全依赖于timestamp。
    • 结论:
      • 风险非常大的随机数生成过程。
8. 0xcC88937F325d1C6B97da0AFDbb4cA542EFA70870
  • 合约名:Ethraffle_v4b
  • 智能合约类型:彩票
  • 随机数产生方式:第99行 uint winningNumber = uint(randHash) % totalTickets;而randHash变量的产生依赖于coinbase, msg.sender和block.difficulty。
  • 问题:非常容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源。
  • 识别思路:和2基本相同。
9. 0xA65D59708838581520511d98fB8b5d1F76A96cad
  • 合约名:BlackJack
  • 智能合约类型:彩票。
  • 随机数产生方式:15行 return uint8(uint256(keccak256(block.blockhash(b), player, cardNumber, timestamp)) % 52)
  • 问题:b为当前区块block,结果恒为0。
  • 分类:误使用blockhash(block.number)作为随机数熵源。
  • 识别思路:基本和3相同。
10. 0xF767fCA8e65d03fE16D4e38810f5E5376c3372A8
  • 合约名:LuckyDoubler
  • 智能合约类型:彩票
  • 随机数产生方式:122行,使用blockhash(block.number-1)
  • 问题:容易被镜像攻击,产生相同结果的随机数。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源。
  • 识别思路:基本和3相同。
11. 0x5acE17f87c7391E5792a7683069A8025B83bbd85
  • 合约名:SmartBillions
  • 智能合约类型:彩票
  • 随机数产生方式:第561行 hash = getHash(player.blockNum); 获取超过256个区块长度的开奖信息;但需要admin来调用putHash往数据库打入hash,举办hackathon的时候admin开小差导致问题。
  • 问题:blockhash只保存256个block,需要依赖admin。
  • 分类:blockhash的误用。
  • 识别思路:??
12. 0x2983eedfbd560b6d65ffa47de6a0f6d6fee6e136
  • 合约名:Slotthereum
  • 智能合约类型:彩票
  • 随机数产生方式:使用私有变量(已自毁,未公开源码)。
  • 问题:使用私有变量的时候,可以被他人看见。
  • 分类:使用“私有”变量(可以被观测到内部信息)。
  • 识别思路:?
14. 0x99b9791d1580bf504a1709d310923a46237c8f2c
  • 合约名:MillionDollarRat
  • 智能合约类型:彩票?
  • 随机产生方式:commit & reveal方式?产生goldenRat并奖励赢家。
  • 问题:?
15. 0xd1ceeeeee83f8bcf3bedad437202b6154e9f5405
  • 合约名:Dice2Win
  • 智能合约类型:彩票
  • 随机产生方式:Commit & Reveal方式。
  • 问题:有串谋风险。
  • 分类:Commit&Reveal。
16. 0xEdB61f74B0d09B2558F1eeb79B247c1F363Ae452
  • 合约名: GutterCats
  • 智能合约类型:虚拟资产
  • 随机产生方式:76行 156行,使用coinbase,timestamp, gaslimit, msg.sender和timestamp和block.number作为随机数种子
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似
17. 0x1681bcb589b3cfcf0c0616b0ce9b19b240643dc1
  • 合约名:IslandToken
  • 智能合约类型:代币
  • 随机产生方式:1086行 使用timestamp和sender以及seed=69作为随机数种子.
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似。
18. 0x4a013d18330880167a2507bc7b2a90bd2c912ec7
  • 合约名:MansionCashToken
  • 智能合约类型:代币
  • 随机产生方式:1097行 使用timestamp和sender以及seed作为随机数种子
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似。
19. 0x9b811024635626bc37e5d294b384077ab25dcf62
  • 合约名:AsteroidScans
  • 智能合约类型:?
  • 随机产生方式:140行 使用blockhash作为随机数种子,并在144行获得seed。
  • 问题:观察发现不是使用未来哈希作为变量,所以它同样会有使用blockhash的一系列问题。
  • 分类:blockhash的不安全使用。
  • 识别方式:和3类似。
20. 0x5283fc3a1aac4dac6b9581d3ab65f4ee2f3de7dc
  • 合约名:AsciiPunks。
  • 智能合约类型:NFT。
  • 随机产生方式: AsciiPunks.sol
    115行使用_seed, timestamp, sender和numToken作为随机数种子。
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似。
21. 0x1a22188b5f6faf7253a3defcc576884c0ff50a91
  • 合约名:LotteryLikePool
  • 智能合约类型:彩票
  • 随机产生方式:LotteryLikePool.sol 536行 uint256 random = uint256(keccak256(abi.encodePacked(round_.calculation.seed, passedIterationsCount)));
  • 问题:感觉是使用链上变量直接做的随机数种子,尽管做了很多封装,容易被预测。
  • 分类:使用不安全的链上变量作为随机数熵源。
  • 识别方式:和2类似。
22. 0x9af15d7b8776fa296019979e70a5be53c714a7ec
  • 合约名:EvnToken
  • 智能合约类型:代币。
  • 随机产生方式:RewardDistributor.sol 59行uint256 rand = block.timestamp * (block.difficulty == 0 ? 1 : block.difficulty) * (uint256(addressForRandom) >> 128) * 31 % 100;
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似。
23. 0x988b3A538b618C7A603e1c11Ab82Cd16dbE28069
  • 合约名:KlerosLiquid
  • 智能合约类型:流动代币
  • 随机产生方式:239行有一个RNG类 里面获取随机数的方式很奇怪,类似使用链上变量,但是又讲不清楚。
  • 问题:使用链上变量。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似。
24. 0x3aE323c0589d32067c07B4A351b10bc900d8B50D
  • 合约名:PackFive
  • 智能合约类型:彩票。
  • 随机产生方式:189行,尽管有很多操作,但还是依赖于链上变量。
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似。
25. 0x7bd29408f11d2bfc23c34f18275bbf23bb716bc7
  • 合约名: Meebits
  • 智能合约类型:NFT?
  • 随机产生方式:326行,完全用链上变量生成的随机数uint index = uint(keccak256(abi.encodePacked(nonce, msg.sender, block.difficulty, block.timestamp))) % totalSize;
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似。
26. 0x06bca1e513603a5544e0a70256607087aba73659
  • 合约名:HUSTLERS
  • 智能合约类型:?
  • 随机产生方式:1875行,直接用block.number + block.timestamp作随机数源
  • 问题:使用链上变量和地址,容易被预测。
  • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2类似。
27. 0x678e8128138eec59801a80e1d57d0a982b8db5bb
  • 合约名:Jackpot
  • 智能合约类型:彩票。
  • 随机产生方式:1421行,几乎把所有的链上变量全部拿出来做随机数种子,而且blockhash还使用的是当前block的。
  • 问题:结合了2和3的。
    • 分类:使用“简单不安全”的链上变量作为随机数熵源;
  • 识别方式:和2,3类似。
28. 0xbc13cdbf9cc107a04be2070f068690b7e7412868
  • 合约名:Mogiets。
  • 智能合约类型:NFT?
  • 随机产生方式:80行,91行,使用blockhash获得随机。
  • 问题:主要是3的问题。
  • 分类:误使用blockhash(block.number)作为随机数熵源,或使用未来hash作为随机。
  • 识别方式:?。
29. 0xee4650cbe7a2b23701d416f58b41d8b76b617797
  • 合约名:AragonCourt
  • 智能合约类型:?
  • 随机产生方式:506行,使用未来hash作为熵源。
  • 问题:存在着只记录256个blockhash的问题。
  • 分类:属于blockhash很容易出现的误使用问题。
  • 识别方式:和3类似。
30. 0xc0fcdb4d882c28238cbcfbb023f87a7a7a1bdaa1
  • 合约名:MultipleWinners
  • 智能合约类型:彩票?
  • 随机产生方式:64行 直接使用外部调用的变量作为随机数,非常不安全。
  • 问题:
31. 0x3c22e37a198835d8a6413e3999ac7a404157c5b9
  • 合约名:ChonkFarm
  • 智能合约类型:?
  • 随机产生方式:做了专门处理的timestamp作为随机数熵源,不确定是否安全。https://swcregistry.io/docs/SWC-116
32. 0x02b5841550f699e68b32336d3f88fcf689ebfa20
  • 合约名:ERC20Token
  • 智能合约类型:Token
  • 随机产生方式:448行,uint screen = uint(keccak256(abi.encodePacked(now, msg.sender, nicetacos))) % 100;其中niceacos不断自增。
33. 0x5fd335e64400eabecc9ebe80e3d2fcfb6c001adb
  • 合约名:Niftysistas
  • 智能合约类型:?
  • 随机产生方式:209行,使用skillBase, nonce, id作为随机数种子,其中skillBase来自于blockhash。
34. 0xe9a2bbc6f08f200afba25474083d8b42a89abab8
  • 合约名:Mars
  • 智能合约类型:NFT?
  • 随机数产生方式:245行 blockhash(block.number)作为随机数种子。
35. 0x082903f4e94c5e10a2b116a4284940a36afaed63
  • 合约名:Pixls
  • 智能合约类型:NFT?https://www.getpixls.com/
  • 随机数产生方式:Pixls.sol 115行和上面的合约一模一样。
36. 0x27d22a7648e955e510a40bdb058333e9190d12d4
  • 合约名:Ticket
  • 智能合约类型:?
  • 随机数产生方式:48行 引入了随机数,并且没有看到预言机或者VRF的字样,但是搞不清楚哪里调用了这个随机数函数
37. 0xe5e7DdADD563018b0E692C1524b60b754FBD7f02
  • 合约名:Vyper_contract
  • 智能合约类型:?
  • 随机数产生方式:69行 randomLevel 使用block.timestamp, msg.sender, block.number, traitNonce作为随机数种子
38. 0xac9bb427953ac7fddc562adca86cf42d988047fd
  • 合约名:SCATTER
  • 智能合约类型:代币
  • 随机数产生方式:131行 使用block.timestamp, _addr, _totolsuppluy作为随机数种子
39. 0xa05d1fea5688688db808c17d2f3d8faa9026a41f
  • 合约名:Buccaneers
  • 智能合约类型:?
  • 随机数产生方式:80行~100行,使用链上变量作为随机种子,131行进行了调用。
40. 0x1a79dd60bedd1ef00bd7d6e3ec0d98b979e5fcdc
  • 合约名:ERC20Token(?)
  • 智能合约类型:代币
  • 随机数产生方式:40行,使用now, msg.sender, nicetacos(一个自增的变量)作为熵源。
41. 0x9816c3f639f5dfdc8832ffca75499b312d1f0c54
  • 合约名:AWMain
  • 智能合约类型:彩票。
  • 随机数产生方式:147行,使用block.difficulty, now - num作为熵源。
42. 0x06a6a7af298129e3a2ab396c9c06f91d3c54aba8
  • 合约名:UniverseGalaxy
  • 智能合约类型:?
  • 随机数产生方式:251行 使用上一个block.number作为熵源
43. 0xe10a2d74e7233e4e66f361a116b2ab1f61dbffcb
  • 合约名:ELG
  • 智能合约类型:代币
  • 随机数产生方式:530行 使用block.number和now作为熵源。
44. 0xa7437c148c782d260b929140262a8e873e7f7ff4
  • 合约名:Bussiness
  • 智能合约类型:交易返利
  • 随机数产生方式:50行,52行,以msg.sender和block.timestamp作为熵源。
45. 0xde201daec04ba73166d9917fdf08e1728e270f06
  • 合约名:MEXPToken
  • 智能合约类型:代币。
  • 随机数产生方式:496行,使用blockHashValue和_userSeed作为随机数熵源
46. 0x3e370a6c8255b065bd42bc0ac9255b269cfcc172
  • 合约名:jackpot
  • 智能合约类型:彩票。
  • 随机数产生方式:134行 直接使用now, msg.sender和block.number作为随机数种子。
47. 0x028ff933bd86bd4d699b1643477f858626482d35
  • 合约名:LUCKER
  • 智能合约类型:彩票。
  • 随机数产生方式:75行 直接使用block.difficulty和_usertime和_time作为随机数种子。
48. 0x7f6f3012373b4fc7c33812402a880407eeac317c
  • 合约名:FairWin
  • 智能合约:彩票。
  • 随机数产生方式:典型的commit-reveal合约,有串谋风险。
49. 0x3a9fff453d50d4ac52a6890647b823379ba36b9e
  • 合约名:ShuffleToken
  • 智能合约:代币
  • 随机数产生方式:699行和687行 使用_from, nonce, magnitude(of the tx), 和heap.size()作为随机数种子,但仍可以被预测。
50. 0xf317a365cfef0aa4357abd057048808a1d430402
  • 合约名:Plague
  • 智能合约:彩票(一个号称解决了Fomo3D的合约)。
  • 随机数产生方式:最后一位进入游戏的玩家拿走奖池一半的资金,每次有玩家进入,就增加30秒,如果一直有人买,那么则奖池一直积累,越早入场赚得越多,超过30000基本就回本。
  • 攻击方式:
    • 传统矿主,在自己购买完之后,就拒绝打包后面的购买。
    • 购买完key后用天价GAS堵塞以太坊,使得其他人的交易都无法正常打包。
    • 参见:https://zhuanlan.zhihu.com/p/42762070
51. 0xa94753f10dae24e39f0dd88bf73718455da387f2
  • 合约名:LUCK
  • 智能合约:彩票。
  • 随机数产生方式:75行 和47基本问题一样。
52. 0x63a389435f370f8aec9ddb179483bdf16d189d1c
  • 合约名:Fusion
  • 智能合约:NFT
  • 随机数产生方式:1298行,获取随机的罕见性,data1, data2和data3由getdata3这个函数来,而getData3就直接是由链上的data数组获得; 1434行使用blockhash作为随机数种子(理得不清楚)

结论

  • 链上随机数的主要生成方式有:
    • 直接通过非blockhash的链上变量生成。
    • 通过blockhash(block.number-1)或blockhash(block.number)调用。(镜像攻击/对blockhash的错误理解)。
    • 间接地通过各种非blockhash链上变量进行调用。(增加理解难度)
    • 通过调用合约的调用者的信息生成。
    • 通过未来的blockhash(block.number)进行调用。(哈希保存问题)
    • Commit&Reveal——有串谋风险。
    • 预言机。
  • 从可预测性的角度,直觉的判断
    • blockhash错误使用>非blockhash链上变量>间接非blockhash链上变量>(调用者信息)>通过未来的blockhash(block.number)进行调用。>Commit&Reveal>预言机。
  • 从实现的角度来讲:
    • 如果面对较为复杂的情况,的确判断难度较大,需要更多的讨论和思考。

Reference

  • [1] https://www.freebuf.com/vuls/179173.html
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智能合约是由代码编写的自动执行合约,通常在区块链技术中使用。与传统的合约不同,智能合约可以自动执行、验证和执行合约条款,无需第三方干预。然而,由于智能合约是由代码编写的,因此它们可能存在一些安全漏洞,这些漏洞可能会导致合约执行不当或被黑客攻击。 以下是一些常见的智能合约安全漏洞: 1. 重入攻击:重入攻击是一种攻击,攻击者利用合约中的漏洞,使其可以重复执行一个函数,从而实现对合约的攻击。攻击者可以在合约执行期间多次调用函数,从而获取更多的资产。 2. 溢出错误:当智能合约处理某些数值时,如果没有正确的检查,可能会发生溢出错误。攻击者可以利用这种漏洞来篡改合约的状态或窃取资产。 3. 未授权的访问:如果智能合约中的某些函数未正确实现访问控制,攻击者可能会访问他们不应该访问的功能。这可能会导致资产丢失或合约被篡改。 4. 错误的随机数生成:在智能合约中,随机数很重要,因为它们可以用来确保合约安全性。如果随机数生成不正确,攻击者可能会利用这种弱点来攻击合约。 5. 不正确的代码:当智能合约中的代码有错误时,可能会引发安全漏洞。攻击者可能会利用这些漏洞来对合约进行攻击或篡改。 这些是智能合约中常见的安全漏洞,因此在编写智能合约时,必须严格遵循安全最佳实践,以确保合约安全性。同时,定期进行安全审核和测试也是非常重要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值