Fork me on GitHub
pikachu's Blog

第三届realworld 区块链wp

前言

  • 第三届 realworld, blockchainsWP
  • 总共有三题,队伍总共做出两道,后续会持续更新
  • 随时欢迎大家交流,随便写写
  • 点击这里 -> 题目附件

Montagy

  • 题目目标清空余额
  • 和队友一起做出来的题目,应该是非预期做出来的,这里会将我们的解法和预期解法都稍微写一下

非预期解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <cstdio>
#include <ctime>
#include <cstdint>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

uint64_t forw(uint32_t t1, uint32_t t2, uint32_t m1, uint32_t m2, uint32_t m3, uint32_t m4)
{
uint32_t p1, p2, p3;
uint32_t s = 0x6644498b;
for (int i = 0; i < 16; ++i) {
s = s + 0x68696e74;
p1 = (t1<<4) - m1;
p2 = t1 + s;
p3 = (t1>>5) + m2;
t2 = t2 + (p1^(p2^p3));
p1 = (t2<<4) + m3;
p2 = t2 + s;
p3 = (t2>>5) - m4;
t1 = t1 + (p1^(p2^p3));
}
return ((uint64_t)t1 << 32) | t2;
}

uint64_t back(uint32_t t1, uint32_t t2, uint32_t m1, uint32_t m2, uint32_t m3, uint32_t m4)
{
uint32_t p1, p2, p3;
uint32_t s = (0x6644498b+0x68696e74ull*16) & 0xffffffff;
for (int i = 0; i < 16; ++i) {
p1 = (t2<<4) + m3;
p2 = t2 + s;
p3 = (t2>>5) - m4;
t1 = t1 - (p1^(p2^p3));
p1 = (t1<<4) - m1;
p2 = t1 + s;
p3 = (t1>>5) + m2;
t2 = t2 - (p1^(p2^p3));
s = s - 0x68696e74;
}
return ((uint64_t)t1 << 32) | t2;
}

int main()
{
srand(time(0));
vector<uint64_t> data;
data.reserve(1ull<<31);
uint32_t tb1 = 443551905, tb2 = 186746487;
uint32_t te1 = 1418013151, te2 = 3531071330;
for (uint64_t i = 0; i < (1ull<<31); ++i) {
uint64_t v = forw(tb1, tb2, 0, 0, 0, i);
data.push_back(v);
if (i % 10000000 == 0)
printf("i=%ld\n",i);
}
printf("sort\n");
sort(data.begin(), data.end());
printf("unique\n");
data.erase(unique(data.begin(), data.end()), data.end());
uint64_t gv = 0;
for (uint64_t m3 = 0;; ++m3) {
vector<uint64_t> data2;
data2.reserve(1ull<<30);
for (uint64_t m4 = 0; m4 < (1ull<<30); ++m4) {
uint64_t v = back(te1, te2, 0, 0, m3, m4);
data2.push_back(v);
if (m4 % 10000000 == 0)
printf("i=%ld\n", m4);
}
printf("sort\n");
sort(data2.begin(), data2.end());
uint64_t i = 0, j = 0;
while (i < data.size() && j < data2.size()) {
if (data[i] == data2[j]) {
gv = data[i];
break;
}
else if (data[i] < data2[j])
++i;
else
++j;
}
if (gv != 0) {
printf("gv=%lx\n", gv);
printf("m3=%lx\n", m3);
for (uint64_t m4 = 0; m4 < (1ull<<30); ++m4) {
uint64_t v = back(te1, te2, 0, 0, m3, m4);
if (v == gv) {
printf("m4=%lx\n", m4);
break;
}
}
break;
}
}
for (uint64_t i = 0; i < (1ull<<31); ++i) {
uint64_t v = forw(tb1, tb2, 0, 0, 0, i);
if (v == gv) {
printf("m4=%lx\n", i);
break;
}
}
return 0;
}
  • 这是我们部署的 newPuzzle ,我们是直接改的题目中的 newPuzzle ,把 0x403 字节位置的 0x14(等于) 改为了 0x10(小于),这样随便找一个 seed 满足条件即可,当然也可以直接写一个攻击合约调用题目的 solve 也行(填充到指定字节,然后碰撞也可以)
1
0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610542806100606000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806304f77cfa146100515780634059e88714610073578063fd922a42146101c5578063ffa644851461020f575b600080fd5b61005961028e565b604051808215151515815260200191505060405180910390f35b6101c36004803603604081101561008957600080fd5b81019080803590602001906401000000008111156100a657600080fd5b8201836020820111156100b857600080fd5b803590602001918460018302840111640100000000831117156100da57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561013d57600080fd5b82018360208201111561014f57600080fd5b8035906020019184600183028401116401000000008311171561017157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610362565b005b6101cd61049e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61028c600480360361012081101561022657600080fd5b810190808035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291908035906020019092919080359060200190929190803590602001909291905050506104c3565b005b6000806009546008546007541818600654600554600454181860035460025460015418180101905060006009546006546003540101600854600554600254010160075460045460015401011818905063aabbccdd818301106102ef57600080fd5b708261e26b90505061031256e5afb60721cb821161030c57600080fd5b8082027ef35b6080614321368282376084810151606401816080016143855161051756101561033a57600080fd5b6f65e670d9bd540cea22fdab97e36840e2818303101561035957600080fd5b60019250505090565b61036a61028e565b61037357600080fd5b716111d850336107ef16565b908018915a905660701b6dffffffffffffffffffffffffffff19168280519060200120101561049a576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166376fe1e92826040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561043557808201518184015260208101905061041a565b50505050905090810190601f1680156104625780820380516001836020036101000a031916815260200191505b5092505050600060405180830381600087803b15801561048157600080fd5b505af1158015610495573d6000803e3d6000fd5b505050505b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b88600181905550876002819055508660038190555085600481905550846005819055508360068190555082600781905550816008819055508060098190555050505050505050505056fea265627a7a723158205b60025b80600514615676d5110000000000000000000000001230212a0000000100000000000000000032
  • 因为我们是直接改的题目中的 puzzle ,所以我们需要绕过 loose ,这里是 1ph0n 师傅提供的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# loose() writeup

for a in range(1, 16):
for b in range(1, 16):
for c in range(1, 16):
if a + b + c == 7 and a ^ b ^ c == 3:
print(a, b, c)
# output:
# 2 2 3
# 2 3 2
# 3 2 2
# match them to:
# a b c
# d e f
# g h i

a = 0x2000000000000000000000000000000000000000000000000000000000000000
b = 0x2000000000000000000000000000000000000000000000000000000000000000
c = 0x3000000000000000000000000000000000000000000000000000000000000000
d = 0x2000000000000000000000000000000000000000000000000000000000000000
e = 0x3000000000000000000000000000000000000000000000000000000000000000
f = 0x2000000000000000000000000000000000000000000000000000000000000000
g = 0x3000000000000000000000000000000000000000000000000000000000000000
h = 0x2000000000000000000000000000000000000000000000000000000000000000
i = 0x2000000000000000000000000000000000000000000000000000000000000000

# test:
t1 = (a^b^c)+(d^e^f)+(g^h^i)
t2 = (a+d+g)^(b+e+h)^(c+f+i)

print(hex(t1))
print(hex(t2))
print((t1 + t2) % 0x10000000000000000000000000000000000000000000000000000000000000000 < 0xaabbccdd )
print(t1 > 0x8261e26b90505061031256e5afb60721cb)
print(0xf35b6080614321368282376084810151606401816080016143855161051756 >= (t1*t2) % 0x10000000000000000000000000000000000000000000000000000000000000000)
print(t1 - t2 >= 0x65e670d9bd540cea22fdab97e36840e2)
  • 然后就可以找一个 seed 符合我们改过之后的条件(条件改为了小于)就行啦
  • 顺便这里插嘴一句,由于我拥有强大的暗黑之力,🤓我找到了所有队伍做这道题目的地址,吼吼哈嘿,快夸我🐶(只标注了一些队伍)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
0x05751749a85D2149C76BC035af4826208Dd9118b  AAA
0x0F4f4c78cE13b69239A676fE65C72bf974b3fCa3
0x6D2BD358b7788E27C271eFE4d40b7A82F6E6c783
0x6BA08F6731509c63026Bc431023F35e49fF4f8fC
0x8FA83b9e152120F11c13d678c7879C3eC2f14DB7
0xA54c712054dEDD5587B5c39F1DF0Aab8BD782B63
0xC66005B6295f396b4289219486aC62aCFC0Ff4d4
0xbc16Cf28E491Ae88C36638642e7673Af4570A1e4
0x3E8C7FEc0166bd59Ca1FcD0672bF8E3915c56Bdf
0x4E8d7823046b3CE7eBd99F7282B18c3DaDD879ED
0x44cE28ad66C38dD334C518EA6f07248a1B3EA08C
0x6B217cbB59e6d0edb104D815db74943670843463
0x60a05Ada89061221e1602957097248FC8c373fE4 0ops
0xDA93b922A68d42Edd7E377f4E06fD574A70B6123
0x726a02a9176e8E458CE8bD75305B92e72a8b4eA2 Sauercloud
0x00E457CD4A251d58D9Af7F674857c78a6Dc73e8F
0x11674249BdC62045947e3022808B6dfD009573B6

预期解法

  • 预期解法应该是比特翻转(这是 tag 中变形 tea 算法的特性),这个在比赛中也发现了,不过队友都碰撞出了,就没有继续向下看,全场队伍应该只有 0ops 是预期解,它们的地址是 https://rinkeby.etherscan.io/address/0x60a05ada89061221e1602957097248fc8c373fe4
  • 改动 6 bit,具体自行分析,或者也可以等官方首席的 WP,不想分析了23333,懒癌患者,等官方 WP 公布之后会搬运过来,我只是个搬运工5555

EasyDefi

  • 这是 sissel 师傅做出来的题目,看看师傅会不会放 wp 啦,我就先不写啦

billboard

  • 未解出,虽然赛后咨询了出题人正确解法,知道了大概原因,但还是准备等待官方 WP 后再更新
  • 👉 官方WP 👈 来啦 🤓
  • 下面是本地复现成功的结果,太感谢 iczc 师傅了

---------------- The End ----------------
谢谢大爷~

Author:pikachu
Link:https://hitcxy.com/2021/rw2021/
Contact:hitcxy@hotmail.com
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处,谢谢!