
前言
- 双十一哈皮🐶
- https://blockchain-ctf.securityinnovation.com/#/
- 做了一遍,感觉这个网站上面的题目可能更贴近实际一些,新手小白刷完 https://ethernaut.openzeppelin.com/ 之后,可以选择性来做这个网站的题目
- 难度还是有的,还有很多小 trick,目前上面是13道题目
- 看了《数码宝贝:最后的进化》,爷青结,然后发现好久没做题了,熟悉一下做题,大佬勿喷,不是 WP,随便写一下
- 很多是参考了网上的 wp的内容 懒癌患者 :)
Donation
- 直接调用 withdrawDonationsFromTheSuckersWhoFellForIt函数即可
Lock Box
- 考点是 EVM中storage存储的读取
| 1 | await web3.eth.getStorageAt(ContractAddress, "1", function(x,y){console.info(y);}) | 
Piggy Bank
- 考点是继承,重写的 collectFunds函数实际上覆盖了PiggyBank中的同名函数
- 直接调用 collectFunds(piggyBalance)即可
SI Token Sale
- 溢出漏洞 balances[msg.sender] += _value – feeAmount
- 只要传入一个小于 feeAmount的_value,即可让我们的balances下溢,比如发送1 gas,然后即可调用refundTokens函数将合约的余额清空,因为这里是将_value除2得到提取的余额,所以我们将合约的etherCollection乘2作为_value即可
Secure Bank
- MembersBank合约跟- SecureBank合约的- withdraw函数的参数类型不同,一个的- _value是- uint8,另一个却是- uint256,这样这两个函数的签名就不相同了,在合约里也就是两个不同的函数,不过它们使用- super.withdraw最终都会调用- SimpleBank的- withdraw函数
- MembersBank中仅需要是注册用户即可,所以这题的流程就是先调用- register函数注册一下,然后使用- etherscan在挑战合约的创建交易里查看一下合约的创建者,因为合约的- ether都存在了它的账户上,然后我们直接使用这个地址来调用- MembersBank中的- withdraw函数即可,也就是找到参数类型为- uint256的函数
Lottery
- 随机数预测
| 1 | contract attack { | 
Heads or Tails
- 随机数漏洞
- 每次猜对可以获得赌注的 1.5倍,因为每次下注只能为0.1 ether,所以一次的收益为0.05 ether,要将合约的ether清空需要20次,那么我们直接在合约中循环调用20次即可
| 1 | contract attack { | 
Record Label
- 调用 withdrawFundsAndPayRoyalties函数时会将对应的_withdrawAmount全部发送至Royalties合约,而Royalties会将其中的80%发送给创建者,剩下的20%发回去,接着withdrawFundsAndPayRoyalties中又会将这20%发送给我们
- 所以我们直接将 _withdrawAmount设为1 ether来调用withdrawFundsAndPayRoyalties函数即可
Trust Fund
- 重入漏洞
| 1 | contract attack { | 
Slot Machine
- selfdestruct不会触发- fallback payable函数
Rainy Day Fund
- 这个题目也挺有意思,考点是 create的计算方式,提前向可预测的地址转账
- 合约账户部署合约,nonce从1开始计算
- 外部账户部署合约,nonce从0开始计算
Raffle
- blockhash这个函数,它可以获取给定的区块号的- hash值,但只支持最近的- 256个区块,不包含当前区块,对于- 256个区块之前的函数将返回- 0
- 触发 fallback函数后,若fallback函数中又调用了自身函数,那么此时,msg.sender变成了自身
- 所以先调用 buyTicket,然后ctf_challenge_add_authorized_sender认证题目合约地址(这是因为接下来会触发fallback函数修改了msg.sender),接着等待256个区块后触发fallback函数中msg.value=0这条分支调用closeRaffle函数,最后调用collectReward即可
Scratchcard
- 这道题我做的很简单,简单分析了一下题目的逻辑,大致得到必须得是第三方合约和其交互,并且只能在构造函数中完成功能逻辑,所以我就去链上找记录去了2333,成功找到一个别人做过的合约地址 0xD38308cb90F17a5aB1B4DD805f69Eb5798536Eea,完美,然后查看其内部交易(因为是第三方合约与题目进行交互,所以是内部交易),点开交易即可看到 Input Data
| 1 | 0x60806040526040516020806102c08339810180604052810190808051906020019092919050505060006402540be4006305f5e1004281151561003d57fe5b0602600081905550600190505b601981111515610113578173ffffffffffffffffffffffffffffffffffffffff1660005460405180807f706c617928290000000000000000000000000000000000000000000000000000815250600601905060405180910390207c01000000000000000000000000000000000000000000000000000000009004906040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038185885af1935050505050808060010191505061004a565b8173ffffffffffffffffffffffffffffffffffffffff1660405180807f636f6c6c6563744d6567614a61636b706f742875696e74323536290000000000815250601b01905060405180910390207c010000000000000000000000000000000000000000000000000000000090046730927f74c9de00006040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808267ffffffffffffffff1681526020019150506000604051808303816000875af19250505050505060d2806101ee6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a035b1fe14604b578063fc4333cd146073575b005b348015605657600080fd5b50605d6087565b6040518082815260200191505060405180910390f35b348015607e57600080fd5b506085608d565b005b60005481565b3373ffffffffffffffffffffffffffffffffffffffff16ff00a165627a7a72305820657390e5500a8446cf4b6fedd6a0ea0a1c3824339e44080120130ef94540ff5d0029000000000000000000000000428c0e1d593d7b85253f2dcf48bfb7626d7ce7e2 | 
- 然后我把 Input Data中换成我自己的题目合约地址就行了(在字节码的最后)
- 然后按照 create计算地址方法,计算出我自己外部账户部署此攻击合约的地址0xf297e7d46bdc54cdfa1cfda71e7ff0368f416705, 提前进行ctf_challenge_add_authorized_sender认证
| 1 | import rlp | 
- 最后将攻击合约部署即可
| 1 | from web3 import Web3, HTTPProvider | 
- 完美,偷懒不愧是我,这里就不具体分析题目了,有兴趣的自行分析


 
          