Bytectf 2019 NaughtyBoy Writeup

Bytectf 2019 NaughtyBoy Writeup

Category: RE

Score: 689

Solved: 10

First blood

题目放出来了一个小时才看题,运气比较好,拿了个安卓逆向一血(估计师傅们都去打n1ctf了

解题过程

拖进JEB,定位到MainActivity,定位到setOnClickListener

image-20190909154913842

跟进发现它把函数名加密了

image-20190909155044819

猜测就是这个native方法来检查输入了:

image-20190909155343583

native层居然没有动态注册方法,很多函数名都没去掉,

image-20190909155508805

看到有两个反调试。

第一个是看tracer pid的:

image-20190909155557760

第二个是看进程中是否有名为android_x86_server的进程:

image-20190909155636029

check中只调用了第二个反调试检测,很容易绕过了,把android_x86_server改个名字就好了。

image-20190909155802710

不管那么多了,直接开始调试

image-20190909160655079

image-20190909160709601

可以看到这获取到的直接是我们的输入,java层没有做任何变换,那就不用管java层那一堆花里胡哨的了,native层这个函数检查了一下开头结尾、长度就进入了sub——400B5B。

这个函数在x86的so中反编译出来又臭又长:

image-20190909160947240

在32位arm的so中比较清晰:

image-20190909161013975

分析发现就是一个消除数字的小游戏,要将数组中的素数也就是0x4f消除掉,只能留中间一个。游戏玩法就不再赘述,观察一下代码即可发现规律。

image-20190909161109292

写出解密脚本

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
char_array0 = [
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0x2D, 0x2D, 0x4F, 0x2D, 0x4F, 0x2D, 0x2D,
0x2D, 0x4F, 0x2D, 0x2D, 0x2D, 0x4F, 0x2D,
0x2D, 0x2D, 0x4F, 0x2D, 0x2D, 0x4F, 0x2D,
0xFF, 0xFF, 0x2D, 0x4F, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
]
s0 = "451"

char_array1 = [
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0x2D, 0x2D, 0x4F, 0x2D, 0x4F, 0x4F, 0x2D,
0x2D, 0x4F, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x4F, 0x2D, 0x2D, 0x2D, 0x2D,
0xFF, 0xFF, 0x2D, 0x4F, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
]
s1 = "253"

char_array2 = [
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0x2D, 0x2D, 0x4F, 0x4F, 0x2D, 0x2D, 0x2D,
0x2D, 0x4F, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x4F, 0x2D, 0x2D, 0x2D, 0x2D,
0xFF, 0xFF, 0x2D, 0x4F, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
]
s2 = "233"

char_array3 = [
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0x2D, 0x4F, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x4F, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x4F, 0x2D, 0x2D, 0x2D, 0x2D,
0xFF, 0xFF, 0x2D, 0x4F, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
]
s3 = "212"

char_array3 = [
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x4F, 0x4F, 0x2D, 0x2D, 0x2D, 0x2D,
0xFF, 0xFF, 0x2D, 0x4F, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
]
s4 = "414"

char_array3 = [
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x4F, 0x2D, 0x2D, 0x2D,
0xFF, 0xFF, 0x2D, 0x4F, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
]
s5 = "531"

char_array3 = [
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
0x2D, 0x2D, 0x2D, 0x4F, 0x2D, 0x2D, 0x2D,
0xFF, 0xFF, 0x2D, 0x4F, 0x2D, 0xFF, 0xFF,
0xFF, 0xFF, 0x2D, 0x2D, 0x2D, 0xFF, 0xFF,
]

input_str = s0+s1+s2+s3+s4+s5
print input_str

flag = "good"
flag += input_str[4:]

print "bytectf{" + flag + "}"

# bytectf{good53233212414531}

其他

  • native函数中还有一些花里胡哨的操作,调试一下或者复制出来跑一跑就可以知道其功能
  • 输入的前四个字节会经过shift函数,有了需要的结果后,我直接暴力跑出来了的。
  • idb在附件文件夹中 libnative-lib.idb
  • 杂七杂八的c语言脚本
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
//
// Created by G6 on 2019-09-06.
//


#include "defs.h"
#include <stdio.h>
#include <cstdlib>

char ccc[64];

unsigned int sub_400ADE(void)
{
char *v0; // r4
unsigned int result; // r0
char v2; // r5
char *v3; // r1

v0 = ccc;
result = 0;
do
{
v3 = v0;
if ( result <= 0xD && (1 << result) & 0x31E3 || result - 35 <= 0xD && (1 << (result - 35)) & 0x31E3 )
{
++v0;
v2 = -1;
}
else
{
++v0;
if ( result - 16 <= 0x16 && (1 << (result - 16)) & 0x424445 )
v2 = 79;
else
v2 = 45;
}
++result;
*v3 = v2;
}
while ( result != 49 );
return result;
}

int __fastcall sub_4008D0(int *a1)
{
int v1; // r1
int v2; // r1

v1 = *a1;
if ( *a1 << 31 )
{
if ( v1 & 2 )
{
if ( v1 & 4 )
{
if ( v1 & 8 )
{
if ( v1 & 0x10 )
{
if ( v1 & 0x20 )
{
if ( v1 & 0x40 )
v2 = v1 & 0xFFFFFF00 | 0x80;
else
v2 = v1 & 0xFFFFFF80 | 0x40;
}
else
{
v2 = v1 & 0xFFFFFFC0 | 0x20;
}
}
else
{
v2 = v1 & 0xFFFFFFE0 | 0x10;
}
}
else
{
v2 = v1 & 0xFFFFFFF0 | 8;
}
}
else
{
v2 = v1 & 0xFFFFFFF8 | 4;
}
}
else
{
v2 = v1 & 0xFFFFFFFC | 2;
}
}
else
{
v2 = v1 | 1;
}
*a1 = v2;
return v2;
}

union aaa{
unsigned int inte;
unsigned char charr[4];
};

int __fastcall shift(aaa result)
{
unsigned char v1; // r2
unsigned char v2; // r3
unsigned char v3; // r12
unsigned int v4; // r1



v1 = result.charr[1];
v2 = result.charr[2];
v3 = result.charr[3];
result.charr[0] ^= 0x87u;
result.charr[1] = v1 ^ 0x42;
result.charr[2] = v2 ^ 0x71;
result.charr[3] = v3 ^ 0x48;
v4 = result.inte ^ (result.inte >> 4) & 0x3333333;
result.inte = v4 ^ 2 * v4 & 0xBEEFDEAC ^ ((v4 ^ 2 * v4 & 0xBEEFDEAC) >> 15) & 0x1BEEF;
return result.inte;
}

int main(){
sub_400ADE();
unsigned int v0 = 0x7c4270b6;
unsigned int v1 = v0 ^ (v0 >> 4) & 0x3333333;
unsigned int v2 = v1 ^ 2 * v1 & 0xBEEFDEAC;
unsigned int v3 = v2 ^ ((v1 ^ 2 * v1 & 0xBEEFDEAC) >> 15) & 0x1BEEF;

uint8 v40 = (uint8)v3 - 48;

int v20;
int j = 0;
for(int i = 0;; v20 = i, j++){
if(j > 64)
break;
sub_4008D0(&i);
//printf("%d\n", v20);
}

for(unsigned int i = 0; i < 0x7FFFFFFF; i++){
aaa a;
a.inte = i;
if(shift(a) == 0x32313534)
printf("%d", i);
}

}