ctfwriteup.com
Search…
⌃K

# Puzzle 10

## Puzzle

#############
# Puzzle 10 #
#############
00 6020 PUSH1 20
02 6000 PUSH1 00
04 6000 PUSH1 00
06 37 CALLDATACOPY
07 6000 PUSH1 00
0A 7FF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0 PUSH32 F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0
2B 16 AND
2C 6020 PUSH1 20
2E 6020 PUSH1 20
30 6000 PUSH1 00
32 37 CALLDATACOPY
33 6000 PUSH1 00
36 17 OR
37 7FABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB PUSH32 ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB
58 14 EQ
59 605D PUSH1 5D
5B 57 JUMPI
5C FD REVERT
5D 5B JUMPDEST
5E 00 STOP
? Enter the calldata:

## Solution

Pseudocode:
calldatacopy(0, 0, 0x20); // store 1st 32 bytes of calldata in memory
calldata_first_half = mload(0x00); // load 1st 32 bytes of calldata onto the stack
calldatacopy(0, 0x20, 0x20); // store 2nd 32 bytes of calldata in memory
calldata_second_half = mload(0x00) // load 2nd 32 bytes of calldata onto the stack
first_computation = calldata_first_half & 0xF0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0;
second_computation = first_computation | calldata_second_half;
if (second_computation == 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB) {
jump(0x5D);
}
`first_computation` can be zeroed out if `calldata_first_half` contains only `0x00`, so we only have to worry about the second half of calldata.
Recall that `0 | 1 == 1`, a generalization of that is `0x0000... | x == x`. In order to get `first_computation | calldata_second_half == 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB`, we can simply let ``calldata_second_half = 0xABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB`.