d3ctf

Posted by marginal on 2022-03-15
Estimated Reading Time 6 Minutes
Words 1.3k In Total
Viewed Times

这次写了两道的wp, 第一道u3d的游戏队友出得比我快, 就没写了.

d3thon

打开一看发现是python导入pyd一类的东西, 用python3.10可以跑起来.

lbc包含了指令的逻辑, byte_analizer.so是类似解释器的东西, pyd的逆向非常困难, 所以我直接通过输入输出来猜测lbc文件中的逻辑. (byte_ananlizer有成员Variables来获得变量值

结果如下

1
2
3
4
5
6
7
8
9
10
kZslMZYnvPBwgdCz   print
oGwDokoxZgoeViFcAF 赋值(如果赋值为KezJKhCxGRZnfLCGT, 则为输入
RDDDZUiIKbxCubJEN jmp
todeVDuRkYSIITaT 转为2进制
uPapnsSbmeJLjin 转为10进制
kuhisCvwaXWfqCs -flag - 1
IEKMEDdrPpzpdKy add
OcKUQCYqhwHXfAgGZH xor
FLNPsiCIvICFtzpUAR sub
OuGFUKNGxNLeHOudCK cmp

lbc中加密的逻辑为

把非01的字符转为ord值, 再转为2进制, 2进制字符串串联起来, 转为10进制, 最后进行运算

解题脚本:

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
#a是那一堆很复杂的运算
k = {}
for i in range(2,10):
k[str(i)] = "{0:b}".format(ord(str(i))).zfill(8)

for i in range(97, 123):
k[chr(i)]="{0:b}".format(i).zfill(8)

b = -194952731925593882593246917508862867371733438849523064153861650948471779982880938
i = len(a) - 1
while i >= 0:
if (a[i - 1] == "xor"):
b ^= int(a[i])
i -= 2
elif (a[i - 1] == "add"):
b -= int(a[i])
i -= 2
elif (a[i - 1] == "sub"):
b += int(a[i])
i -= 2
elif (a[i] == "????????:flag"): #-flag - 1的运算
b = -b - 1
i -= 1
else :
print("error")

c = bin(b)[2:]

s = ""
i = len(c)
while i >= 8:
for key, value in k.items():
if (c[i - 8:i] == k[key]):
s = key + s
i -= 8
break
print(s)
print(i)
#1101000011011100110010001110010110000100110100011000010011011001100010011000100110010001100100001101000110010000110111001110000110001100111001001101000110010100110#11000110010001100100011100100110010001101010011011101100001011001100011001100110101 01100101
#4729a4a6bbdd4d78c94e6229257af35e

d3w0w

这个题目感觉是一个迷宫题, 要求迷宫得玩家打造那种, 并且给出了迷宫的要求

对输入的转化(输入只能由39位, 减去前缀, 只有32位)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
case '1':
*(_DWORD *)(a2 + 24 * v5 + 4 * v4) |= 8u;// 上
*(_DWORD *)(a2 + 24 * --v5 + 4 * v4) |= 2u;
goto LABEL_14;
case '2':
*(_DWORD *)(a2 + 24 * v5 + 4 * v4) |= 2u;// 下
*(_DWORD *)(a2 + 24 * ++v5 + 4 * v4) |= 8u;
goto LABEL_14;
case '3':
*(_DWORD *)(a2 + 24 * v5 + 4 * v4) |= 4u;// 左
*(_DWORD *)(a2 + 24 * v5 + 4 * v4-- - 4) |= 1u;
goto LABEL_14;
case '4':
*(_DWORD *)(a2 + 24 * v5 + 4 * v4) |= 1u;// 右
*(_DWORD *)(a2 + 24 * v5 + 4 * v4++ + 4) |= 4u;

输入转化的值,只看低4位:

第4位表示能往上走, 第3位表示能向左走, 第2位表示能向下走, 第1位表示能向右走, 设置迷宫时只能一步步顺序设置.

迷宫校验为64位模式进行校验, 所以得从64位的角度进行反编译

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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
for ( i = 0; i < 6; ++i )
{
for ( j = 0; j < 6; ++j )
{
if ( (unsigned int)retaddr[6 * i + j] > 0xF )
return 1i64;
v16 = retaddr[6 * i + j] % 0x10u / 8;
v24 = j;
v17 = retaddr[6 * i + j] % 8u / 4 + v16;
v25 = j;
v18 = retaddr[6 * i + j] % 4u / 2 + v17;
v26 = j;
if ( retaddr[6 * i + j] % 2u + v18 > 2 ) //每个点的通道不能超过两个
return 1i64;
//检验边界
if ( !j && retaddr[6 * i] % 8u / 4 )
return 1i64;
if ( j == 5 && retaddr[6 * i + 5] % 2u )
return 1i64;
if ( !i && retaddr[j] % 0x10u / 8 )
return 1i64;
if ( i == 5 && retaddr[j + 30] % 4u / 2 )
return 1i64;
}
}
//特殊点1
for ( k = 0; (unsigned __int64)k < 3; ++k )
{
v4 = v22[k] / 10;
v7 = v22[k] % 10;
//结合下面的条件, 方向必须垂直
if ( retaddr[6 * v4 + v7] % 0x10u / 8 && retaddr[6 * v4 + v7] % 4u / 2 )
return 1i64;
if ( retaddr[6 * v4 + v7] % 8u / 4 && retaddr[6 * v4 + v7] % 2u )
return 1i64;
v19 = retaddr[6 * v4 + v7] % 0x10u / 8;
v27 = v7;
v20 = retaddr[6 * v4 + v7] % 4u / 2 + v19;
v28 = v7;
v21 = retaddr[6 * v4 + v7] % 2u + v20;
v29 = v7;
if ( retaddr[6 * v4 + v7] % 8u / 4 + v21 != 2 ) //必须有两个通道
return 1i64;
//此节点通向的第一个点和该点有相同方向通道(该节点通向的第一个节点的方向)
if ( retaddr[6 * v4 + v7] % 0x10u / 8 )
{
if ( !(retaddr[6 * v4 - 6 + v7] % 0x10u / 8) )
return 1i64;
}
else if ( retaddr[6 * v4 + v7] % 4u / 2 )
{
if ( !(retaddr[6 * v4 + 6 + v7] % 4u / 2) )
return 1i64;
}
else if ( retaddr[6 * v4 + v7] % 8u / 4 )
{
if ( !(retaddr[6 * v4 - 1 + v7] % 8u / 4) )
return 1i64;
}
else if ( retaddr[6 * v4 + v7] % 2u && !(retaddr[6 * v4 + 1 + v7] % 2u) )
{
return 1i64;
}
}
//特殊点二2
for ( m = 0; (unsigned __int64)m < 0xA; ++m )
{
v5 = v23[m] / 10;
v8 = v23[m] % 10;
//方向必须平行
if ( (!(retaddr[6 * v5 + v8] % 0x10u / 8) || !(retaddr[6 * v5 + v8] % 4u / 2))
&& (!(retaddr[6 * v5 + v8] % 8u / 4) || !(retaddr[6 * v5 + v8] % 2u)) )
{
return 1i64;
}
//必须有通道垂直该节点的方向
if ( retaddr[6 * v5 + v8] % 0x10u / 8
&& retaddr[6 * v5 + v8] % 4u / 2
&& !(retaddr[6 * v5 - 6 + v8] % 8u / 4)
&& !(retaddr[6 * v5 - 6 + v8] % 2u)
&& !(retaddr[6 * v5 + 6 + v8] % 8u / 4)
&& !(retaddr[6 * v5 + 6 + v8] % 2u) )
{
return 1i64;
}
if ( retaddr[6 * v5 + v8] % 8u / 4
&& retaddr[6 * v5 + v8] % 2u
&& !(retaddr[6 * v5 + 1 + v8] % 0x10u / 8)
&& !(retaddr[6 * v5 + 1 + v8] % 4u / 2)
&& !(retaddr[6 * v5 - 1 + v8] % 0x10u / 8)
&& !(retaddr[6 * v5 - 1 + v8] % 4u / 2) )
{
return 1i64;
}
}
//上下左右的顺序寻路, 不能返回上个节点, 要求回到原点
if ( *retaddr % 0x10u / 8 )
{
v6 = -1;
do
{
LABEL_79:
if ( !(retaddr[6 * v6 + v9] % 0x10u / 8) || v6 - 1 == v12 && v9 == v13 )
{
if ( !(retaddr[6 * v6 + v9] % 4u / 2) || v6 + 1 == v12 && v9 == v13 )
{
if ( !(retaddr[6 * v6 + v9] % 8u / 4) || v6 == v12 && v9 - 1 == v13 )
{
if ( !(retaddr[6 * v6 + v9] % 2u) || v6 == v12 && v9 + 1 == v13 )
//走到死胡同
return 1i64;
v12 = v6;
v13 = v9++;
}
else
{
v12 = v6;
v13 = v9--;
}
}
else
{
v12 = v6;
v13 = v9;
++v6;
}
}
else
{
v12 = v6;
v13 = v9;
--v6;
}
}
while ( v6 || v9 );
return 0i64;
}
else
{
if ( *retaddr % 4u / 2 )
{
v6 = 1;
goto LABEL_79;
}
if ( *retaddr % 8u / 4 )
{
v9 = -1;
goto LABEL_79;
}
if ( *retaddr % 2u )
{
v9 = 1;
goto LABEL_79;
}
return 1i64;
}
}

最后画图

Untitled


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !