前言
- 复现
balsn2019 ctf
中的Creativity
区块链题目 - 这道题其实早就想复现了,只不过一直没有复现成功,是有关
create2
的骚操作,基本操作可参考另外一片文章https://hitcxy.com/2020/Create2/ - 具体分析及官方
WP
如下: https://x9453.github.io/2020/01/04/Balsn-CTF-2019-Creativity/ - 原谅我菜的抠脚…都
2020
了,还在做2019
的题目 - 复现地址为:
ropsten@0x3975c105e8D582A324F6093E7471fDf9d5b9Fa67
Source
1 | pragma solidity ^0.5.10; |
Analyse
题目大概逻辑是:
- 让我们部署一个合约,合约代码大小不超过4字节
- 调用
check
,参数是我们部署的合约地址 - 调用
execute
,执行delegatecall
到我们部署的合约内
但是,有个问题,我们没法在4个字节内
emit SendFlag
- 其实题目考查知识点为
Create2
的骚操作: 在同一个地址上部署合约,合约的字节码可以不同,即在同一个地址上先后可部署不同的合约 - 通过调用下面
Deployer.deploy
函数,我们可以把不同合约先后部署在同一个地址上,deployedAddr
即为部署的合约地址
1 | pragma solidity ^0.5.10; |
- 所以题目的逻辑如下:
- 用
create2
的骚操作,部署一个合约0x33ff
,即selfdestruct(msg.sender)
- 调用
check()
,让target
为我们部署的合约地址 - 给我们部署的合约发一笔空交易,让它自毁
- 再次使用
create2
骚操作,在同一个地址部署合约,合约内容为emit SendFlag(0)
- 调用
execute()
,就会执行我们第二次部署的合约的emit SendFlag
事件,因为是delegatecall
操作,所以还是相当于在原题目合约中进行的emit SendFlag
操作,成功!
- 用
Solution
- 先将
Deployer
部署,地址为0x307FdF03B1842A501F52221e4cF02D67BfeEc399
, 然后使用Deployer.deploy
部署0x33ff
,得到部署的合约地址0x2b473f517088f6d08e82cA06dD5A5e6A68Eb4663
- 调用
check()
,target
已经变成了我们部署的合约地址
- 给我们部署的合约发一笔空交易,让它自毁,目的是为了重新在这个地址部署合约触发
SendFlag
事件,可以看到部署的合约已经自毁
1 | web3.eth.sendTransaction({ from: '0x785a8D0d84ad29c96f8e1F26BfDb3E6CB72cAe9b', to: "0x2b473f517088f6d08e82cA06dD5A5e6A68Eb4663", data: "" }, function(err,res){console.log(res)}); |
- 使用
create2
骚操作,在同一个地址部署合约,合约内容为emit SendFlag(0)
,这里我是写了一个hack
合约,然后使用Deployer.deploy
部署
1 | contract hack { |
- 这样就把内容为
emit SendFlag
的hack
合约给部署到同一个地址0x2b473f517088f6d08e82cA06dD5A5e6A68Eb4663
上了,如下图
- 调用
execute()
,就会执行我们第二次部署的合约的emit SendFlag
事件
- 完结!!!🎉🎉🎉🎉🎉🎉