MRCTF2021 BlockChain Writeup
Retr_0师傅为MRCTF2021出的两道区块链题,我来捧个场。
Check_IN
0xE27eAb49f660451df7157cA812fcF1c719Cf504e@Ropsten
题目没有给源代码,需要先逆向。
Decompiled
1 | // Decompiled at www.contract-library.com |
可以看到想要getflag的话必须先让_addAuth为真、或者在去调用target.model函数来检查。在这个合约里一眼看不到能够从外部对_addAuth进行修改的地方,所以把目光转向target.model这里的校验。
在0xf2889ac4
中创建了一个新的合约并且赋值给了target。所以去逆向这个新的合约。发现只要在创建的时刻这个合约自己有2.333ether就可以通过验证。
还需要有一定的钱,可以直接调相应的函数拿钱。
Expliot
1 | // SPDX-License-Identifier: GPL-3.0 |
学到的东西
- revert会连带合约自己的nonce一同revert会去,也就是说如果创建合约失败,下一次创建合约还是在这个失败的地址上创建。以及,合约的nonce和用户不同,从1开始。
- 用encodePacked而不是encode
- remix的gas estimate准到离谱,要相信他的报错,他的报错是我们部署之前检查的机会。
uncertainty
0x47b9bdCFFCC6bb1851442E5e9dacCBE6F84C1841@Ropsten
Source
1 | pragma solidity ^0.4.17; |
看了很久,才理清三个合约之间的关系,发现unlock(target1).winned没有地方能够修改,才发现是变量覆盖。
Exploit
1 | // SPDX-License-Identifier: GPL-3.0 |
赛后师傅说可以用revise实现任意storage写。