题目信息

1
2
3
4
5
6
7
8
9
10
11
12
13
[+] You need to implement a smart contract as the gas machine, and send us its RUNTIME bytecode.
We will check it for 1000 times.
Each time we call the machine with no input data and a random amount of gas between [21100, 99999]. All gas should be used, while the tx must not fail.

[+] Limit: Forbidden opcodes: [240, 241, 242, 244, 245, 250, 255]; Max length: 100
f0 CREATE
f1 CALL
f2 CALLCODE
f4 DELEGATECALL
f5 CREATE2
fa STATICCALL
ff SELFDESTRUCT
[+] Note: Istanbul

解题思路

  • 用循环消耗 gas 到某一边界值
  • 字节码最后面填充 jumpdest
  • 根据剩余的 gas 选择 jump 到后面的 jumpdest

调试思路

使用如下脚本部署字节码

1
2
3
4
5
6
7
8
9
10
pragma solidity ^0.5.10;

contract Test {

constructor(bytes memory a) payable public {
assembly {
return(add(0x20, a), mload(a))
}
}
}

Untitled 1.png

部署成功后将直接发送交易给合约

Untitled 2.png

Untitled 3.png

最后即可成功

Untitled 4.png

Untitled 5.png

解题脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python

# 22 * 2 = 44
code = ""
code += "5b" # jumpdest 1
code += "5a" # gas 2
code += "6040" # push1 3
code += "10" # lt 3
code += "6000" # push1 3
code += "57" # jumpi 10
code += "5a" # gas 2
code += "606b" # push1 3
code += "03" # sub 3
code += "56" # jump 8
code += "5b" * 0x50 # jumpdest 1
code += "00" # stop
print(code)
print(len(code))