2021巅峰极客
比赛中没做出来,后面做的

Baby_maze

这个 maze 与一般的 maze 不太一样,不能直接看到地图的全貌,只给你在某处的 WASD 的即移动回显

然后就写了个 python 处理,大概要用 17 分钟可以跑出来

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
#coding=utf-8
from pwn import *
import time
nice = ['Just do it\n','GOGOGO\n','Wuhu~!\n',
'You are so good\n','Nice.\n','Yeah~~~\n',
"Let's go.\n",'So smart\n','Never stop\n','Wuhu\n']

def de(i):
if i == 'W':
return 'S'
elif i == 'S':
return 'W'
elif i == 'A':
return 'D'
elif i == 'D':
return 'A'

def sb(flag,x,y):
#print flag
xx = x
yy = y
for i in 'WSAD':
if i == 'W':
if maze[x][y-1] != 0:#0为未走过
continue
elif i == 'S':
if maze[x][y+1] != 0:
continue
elif i == 'A':
if maze[x-1][y] != 0:
continue
elif i == 'D':
if maze[x+1][y] != 0:
continue
sh.send(i)
time.sleep(0.05)#以防recv不到
recv = sh.recv()
#print recv
if str(recv) in nice:
if i == 'W':
y -= 1
elif i == 'S':
y += 1
elif i == 'A':
x -= 1
elif i == 'D':
x += 1
maze[x][y] = 2#标记可走
sb(flag + i,x,y)#然后走
sh.send(de(i))#走回来
sh.recv()
x = xx
y = yy
elif 'md5' in recv:#输出结果
maze[x][y]=3
print(flag+i)
exit(0)

elif i == 'W':#标记不可走
maze[x][y-1] = 1
elif i == 'S':
maze[x][y+1] = 1
elif i == 'A':
maze[x-1][y] = 1
elif i == 'D':
maze[x+1][y] = 1

maze=[0]*1000
for i in range(1000):
maze[i]=[0]*1000

maze[1][1] = 2#start处可走
maze[1][2] = 2#start往下走一步
sh = process('./maze')
sh.send('S')
sh.recv()
x = 1
y = 2
flag = 'S'
sb(flag,x,y)

另一个大哥的脚本也比较牛,从ida的flag处往前推,推到起点输出flag,一秒钟不要就跑出来了

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
from idc import *
from idautils import *

def run_one(addr, paths, flag):
count = 0
found = False
to_handle_refs = []
for xref in XrefsTo(addr, 0):
count += 1
cur_fm = xref.frm
cur_start = idc.get_func_attr(cur_fm, FUNCATTR_START)
if cur_start not in paths:
fm = cur_fm
fun_start = cur_start
found = True
to_handle_refs.append((fm, fun_start))

if found:
rets = []
for fm, fun_start in to_handle_refs:
case_ea = fm - 5
comment = idc.get_cmt(case_ea, 1)
assert 'case' in comment
c = (chr(int(comment.split('case')[1])))
rets.append((c, fun_start))
return rets

return None

start = 0x54DE35
addr = start
paths = []
flag = ''
queue = [(addr, paths, flag)]

while len(queue) > 0:
new_queue = []
#print ('queue=%d, len=%d' %(len(queue), len(queue[0][2])))
for addr, paths, flag in queue:
#print ('%x' %(addr))
rets = run_one(addr, paths, flag)
#print ('ret=%s' %rets)
if rets is None:
continue
for c, next_fun in rets:
if next_fun == 0x40187c:
print ('succ:S%s' %(flag+c)[::-1])
continue
new_queue.append((next_fun, paths+[addr], flag+c))

queue = new_queue.copy()

medical_app

arm32才是原题目的so,其他版本的so都是编译器写的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool __fastcall Java_come_crack_crackme2_MainActivity_chk(int a1, int a2, int a3)
{
char *v3; // r4
unsigned __int8 v5[260]; // [sp+0h] [bp-118h] BYREF

v3 = (char *)z(a1, a3);
if ( strlen(v3) != 36 )
return 0;
memset(v5, 0, 0x100u);
z2(v5, (unsigned __int8 *)d, 0x10u);//RC4 init
z3(v5, (unsigned __int8 *)v3, 0x24u);//RC4
z4((unsigned int *)v3, 9u, d);//tea
return memcmp(v3, &ss, 0x24u) == 0;
}

下次见到有名字的函数,却没有发现调用的,可以猜测是编译器优化的so

优化一下 z4 函数,改成逆 tea 函数,再将 cmp 带入将输出填入在线 RC4,解得flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

int main()
{
unsigned int d[4] = { 1, 0x10, 0x100, 0x1000 };
unsigned char cmp[] = { 0x3E, 0x97, 0xE5, 0x68, 0x67, 0x73, 0x0C, 0xC2, 0x1B, 0xD4, 0xAF, 0x98, 0xE2, 0x9D, 0x4B, 0xFE, 0x0B, 0xB6, 0xA5, 0x01, 0x46, 0xD6, 0x36, 0x3D, 0xAF, 0x7B, 0xCC, 0xDB, 0x00, 0x4F, 0x41, 0xA0, 0x1A, 0xE7, 0x2C, 0x76};
int sum; // r10
int v11; // r3
unsigned int * ss = (unsigned int *)cmp;
sum = 0;
for(int i = 0; i < 11; ++i)
sum -= 0x60A8894A;
for(int i = 0; i < 11; ++i)
{
v11 = (sum >> 2) & 3;
for(int j = 8; j >= 0 ; --j)
ss[j] -= ((((4 * ss[(j + 1) % 9]) ^ (ss[((j - 1) + 9) % 9] >> 5)) + ((ss[(j + 1) % 9] >> 3) ^ (16 * ss[((j - 1) + 9) % 9]))) ^ ((d[j & 3 ^ v11] ^ ss[((j - 1) + 9) % 9]) + (ss[(j + 1) % 9] ^ sum)));
sum += 0x60A8894A;
}
for(int i = 0; i < 36; ++i)
printf("%02x ",cmp[i]);
}

文章作者: Usher
文章链接: https://usher2008.github.io/2021/08/02/2021%E5%B7%85%E5%B3%B0%E6%9E%81%E5%AE%A2wp/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Usher