前言
- 第五空间
creativityplus
题目 creativityplus
题目有个非预期,直接部署一个字节stop
指令也可以,0x600a600c60003960016000f3
+00
- 文章介绍预期解
CreativityPlus
- 题目很简单,改编自
Creativity
题目,简称CreativityPlus
升级版 - 考点
create2
与bytecode
题目逻辑如下:
- 部署一个合约,大小不超过
4
字节 - 调用
check
,参数是我们部署的合约地址 - 调用
execute
,使得返回值为true
,我们即可成为owner
- 部署一个合约,大小不超过
但是我们没法在
4
个字节内emit SendFlag
create2
骚操作,使用如下代码可将不同bytecode
部署到同一个地址上,deployedAddr
即为部署的合约地址
1 | pragma solidity ^0.5.10; |
所以题目的逻辑如下:
- 用
create2
的骚操作,部署一个合约0x33ff
,即selfdestruct(msg.sender)
- 调用
check()
,让target
为我们部署的合约地址 - 给我们部署的合约发一笔空交易,让它自毁
- 再次使用
create2
骚操作,在同一个地址部署合约,合约内容大小不超过10
字节,返回1
- 用
返回值由
return(p, s)
操作码处理,但是在返回值之前,必须先存储在内存中,使用mstore(p, v)
将1
存储在内存中首先,使用
mstore(p, v)
将1
存储在内存中,其中p
是在内存中的存储位置,v
是十六进制值,1
的十六进制是0x01
1
2
30x6001 ;PUSH1 0x01 v
0x6080 ;PUSH1 0x80 p
0x52 ;MSTORE然后,使用
return(p, s)
返回0x01
,其中p
是值0x2a
存储的位置,s
是值0x2a
存储所占的大小0x20
,占32
字节1
2
30x6020 ;PUSH1 0x20 s
0x6080 ;PUSH1 0x80 p
0xf3 ;RETURN
所以我们只需使用
Deployer.deploy
部署0x600160805260206080f3
即可,正好10 opcodes
- 调用
execute
我们即可成为owner
SafeDelegatecall
1 | pragma solidity ^0.4.23; |
- 题目对
delegatecall
返回值进行检查,有效防止其篡改调用者合约的storage
数据 - 题目有个
backdoor
,存在任意跳转,任意跳转的参数有两个mload(func)
和返回值val
,跳转的地址为它们的差值,跳转的目的地址为0x3c1
即可,这个自己逆向可以分析出来,其中mload(func)
的值为0x48a
,所以返回值val = 0x48a-0x3c1 = 201
- 部署以下合约得到攻击合约地址
addr
,调用execute(addr)
即可
1 | contract hack { |