ctfwriteup.com
Search…
⌃K

Puzzle 7

CALLDATACOPY, CREATE

Puzzle

############
# Puzzle 7 #
############
00 36 CALLDATASIZE
01 6000 PUSH1 00
03 80 DUP1
04 37 CALLDATACOPY
05 36 CALLDATASIZE
06 6000 PUSH1 00
08 6000 PUSH1 00
0A F0 CREATE
0B 3B EXTCODESIZE
0C 6001 PUSH1 01
0E 14 EQ
0F 6013 PUSH1 13
11 57 JUMPI
12 FD REVERT
13 5B JUMPDEST
14 00 STOP
? Enter the calldata:

Solution

Chunk 1

00 36 CALLDATASIZE
01 6000 PUSH1 00
03 80 DUP1
04 37 CALLDATACOPY
CALLDATACOPY
At address 0x04, we are calling CALLDATACOPY(0, 0, 16). This function call copies 16 bytes of calldata to the very beginning of the memory.

Chunk 2

05 36 CALLDATASIZE
06 6000 PUSH1 00
08 6000 PUSH1 00
0A F0 CREATE
CREATE
At address 0x0A, we are calling CREATE(0, 0, calldata_size). This function call creates a new contract and deposits 0 wei into it. The initialization code for the new contract is at memory location 0, which is our input copied during chunk 1. The return value of CREATE is the new contract's address.

Chunk 3

0B 3B EXTCODESIZE
0C 6001 PUSH1 01
0E 14 EQ
This chunk tests if the new contract's code size is 1.

Chunk 4

0F 6013 PUSH1 13
11 57 JUMPI
12 FD REVERT
13 5B JUMPDEST
14 00 STOP
If chunk 3 evaluates to true, then we are jumping to address 0x13.

Building calldata

Since the new contract's code size must be 1, we can build a minimal contract that contains only 1 0x00, which is the opcode for STOP. In other word, the runtime code for this new contract is:
0x00
Write a creation code for it:
PUSH1 0x01 // return just 1 byte
PUSH1 0x00 // runtime code, default is 0x00
RETURN
Compile in Playground:
60016000f3
Last modified 1d ago