五层合约,构造符合要求的msg.data可以完成题目任务。
题目简介
五层合约,构造符合要求的msg.data可以完成题目任务。需要满足如下条件:
合约一
满足给出的条件:require(ecrecover(keccak256(“solved”), v, r, s) == 0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF); 该地址私钥可查到,为0x02
签名用这个工具生成
https://gist.github.com/onyb/cf795c819fdf8aa6015de2772fde24de
v,r,s分别是msg.data的前三个slot的值,其中v & 0xff == 0x1b
合约二
msg.data的slot0的高字节和blockhash相同,这里就决定了要用攻击合约。
合约三
msg.data的slot1和slot2末尾不为0,且相加后有整数上溢。前三个合约都限制的是v,r,s的值
合约四
有些复杂
- data[0x24:0x44]-data[0x44:0x64] == data[0x64:0x84] - data[0x84:0xa4]
- data从0x24开始,与从0xa4开始,对应位置同奇偶(4组)
合约五
设msg.data[0xc4:0xe4] % 6 -> k,有 data[0x04+k0x20 : 0x04+k0x20 + 0x20] == keccak256(“choose”) (六个data的slot里,选一个是keccak256(“choose”))
最终的攻击合约
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| pragma solidity 0.4.24;
contract AA{ address public next; constructor(bytes memory a) payable public { next = 0x111; assembly { return(add(0x20, a), mload(a)) } } }
contract BB{ constructor() payable public{ address a = 0x111; a.call(bytes4(0xf4ab27cc), blockhash(block.number-1)|0xff1b ,0x3ec07bbb0fe7fd6e6d2abbb5f0a0c9947173da8daa5265f6231beea212772585,0x26236f50af44e91e608d5946b411a4f86a83ace0543bf8efca7bee233d1f98db,0xe201a979a73f6a2947c212ebbed36f5d85b35629db25dfd9441d562a1c6ca896,0xc9649d0f469c55d93b24b07c82444ac17ec3287c850f72d2eb7d55ab47151bec,0x0000000000000000000000000000000000000000000000000000000000000001,0x0000000000000000000000000000000000000000000000000000000000000003,0x0000000000000000000000000000000000000000000000000000000000000000, 0xc9649d0f469c55d93b24b07c82444ac17ec3287c850f72d2eb7d55ab47151bec); } }
|