XCTF_Reverse_elrond32

XCTF Reverse板块中的elrond32题目,个人解法
ExeinfoPE查看文件信息,32bit,那就用32位的IDA分析

进入Main函数:

猜测 if ( a1 > 1 && sub_8048414(a2[1], 0)) 条件满足,即输出flag函数 sub_8048538(a2[1]);
sub_8048538():

分析可得输出flag部分代码为(C):

1
2
3
for (int i = 0; i <= 32; ++i ) {
flag[i] = v2[i] ^ a2[i % 8];
}

unk_8048760 (v2):

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

.rodata:08048760 unk_8048760 db 0Fh ; DATA XREF: sub_8048538+12↑o
.rodata:08048761 db 0
.rodata:08048762 db 0
.rodata:08048763 db 0
.rodata:08048764 db 1Fh
.rodata:08048765 db 0
.rodata:08048766 db 0
.rodata:08048767 db 0
.rodata:08048768 db 4
.rodata:08048769 db 0
.rodata:0804876A db 0
.rodata:0804876B db 0
.rodata:0804876C db 9
.rodata:0804876D db 0
.rodata:0804876E db 0
.rodata:0804876F db 0
.rodata:08048770 db 1Ch
.rodata:08048771 db 0
.rodata:08048772 db 0
.rodata:08048773 db 0
.rodata:08048774 db 12h
.rodata:08048775 db 0
.rodata:08048776 db 0
.rodata:08048777 db 0
.rodata:08048778 db 42h ; B
.rodata:08048779 db 0
.rodata:0804877A db 0
.rodata:0804877B db 0
.rodata:0804877C db 9
.rodata:0804877D db 0
.rodata:0804877E db 0
.rodata:0804877F db 0
.rodata:08048780 db 0Ch
.rodata:08048781 db 0
.rodata:08048782 db 0
.rodata:08048783 db 0
.rodata:08048784 db 44h ; D
.rodata:08048785 db 0
.rodata:08048786 db 0
.rodata:08048787 db 0
.rodata:08048788 db 0Dh
.rodata:08048789 db 0
.rodata:0804878A db 0
.rodata:0804878B db 0
.rodata:0804878C db 7
.rodata:0804878D db 0
.rodata:0804878E db 0
.rodata:0804878F db 0
.rodata:08048790 db 9
.rodata:08048791 db 0
.rodata:08048792 db 0
.rodata:08048793 db 0
.rodata:08048794 db 6
.rodata:08048795 db 0
.rodata:08048796 db 0
.rodata:08048797 db 0
.rodata:08048798 db 2Dh ; -
.rodata:08048799 db 0
.rodata:0804879A db 0
.rodata:0804879B db 0
.rodata:0804879C db 37h ; 7
.rodata:0804879D db 0
.rodata:0804879E db 0
.rodata:0804879F db 0
.rodata:080487A0 db 59h ; Y
.rodata:080487A1 db 0
.rodata:080487A2 db 0
.rodata:080487A3 db 0
.rodata:080487A4 db 1Eh
.rodata:080487A5 db 0
.rodata:080487A6 db 0
.rodata:080487A7 db 0
.rodata:080487A8 db 0
.rodata:080487A9 db 0
.rodata:080487AA db 0
.rodata:080487AB db 0
.rodata:080487AC db 59h ; Y
.rodata:080487AD db 0
.rodata:080487AE db 0
.rodata:080487AF db 0
.rodata:080487B0 db 0Fh
.rodata:080487B1 db 0
.rodata:080487B2 db 0
.rodata:080487B3 db 0
.rodata:080487B4 db 8
.rodata:080487B5 db 0
.rodata:080487B6 db 0
.rodata:080487B7 db 0
.rodata:080487B8 db 1Ch
.rodata:080487B9 db 0
.rodata:080487BA db 0
.rodata:080487BB db 0
.rodata:080487BC db 23h ; #
.rodata:080487BD db 0
.rodata:080487BE db 0
.rodata:080487BF db 0
.rodata:080487C0 db 36h ; 6
.rodata:080487C1 db 0
.rodata:080487C2 db 0
.rodata:080487C3 db 0
.rodata:080487C4 db 7
.rodata:080487C5 db 0
.rodata:080487C6 db 0
.rodata:080487C7 db 0
.rodata:080487C8 db 55h ; U
.rodata:080487C9 db 0
.rodata:080487CA db 0
.rodata:080487CB db 0
.rodata:080487CC db 2
.rodata:080487CD db 0
.rodata:080487CE db 0
.rodata:080487CF db 0
.rodata:080487D0 db 0Ch
.rodata:080487D1 db 0
.rodata:080487D2 db 0
.rodata:080487D3 db 0
.rodata:080487D4 db 8
.rodata:080487D5 db 0
.rodata:080487D6 db 0
.rodata:080487D7 db 0
.rodata:080487D8 db 41h ; A
.rodata:080487D9 db 0
.rodata:080487DA db 0
.rodata:080487DB db 0
.rodata:080487DC db 0Ah
.rodata:080487DD db 0
.rodata:080487DE db 0
.rodata:080487DF db 0
.rodata:080487E0 db 14h
.rodata:080487E1 db 0
.rodata:080487E2 db 0

这里选中数据后Shift + E 发现有很多的0x00

使用LazyIDA提取数据,转换为DWORD (Double Word, 双字节, 占四BYTE,就可以把我们要的数据后边的0x00去除,避免出现一些问题) (选取数据,右键,Convert,Convert to C/C++ array (DWORD) )
1
2
3
4
5
6
7
unsigned int unk_8048760[33] = {
0x0000000F, 0x0000001F, 0x00000004, 0x00000009, 0x0000001C, 0x00000012, 0x00000042, 0x00000009,
0x0000000C, 0x00000044, 0x0000000D, 0x00000007, 0x00000009, 0x00000006, 0x0000002D, 0x00000037,
0x00000059, 0x0000001E, 0x00000000, 0x00000059, 0x0000000F, 0x00000008, 0x0000001C, 0x00000023,
0x00000036, 0x00000007, 0x00000055, 0x00000002, 0x0000000C, 0x00000008, 0x00000041, 0x0000000A,
0x00000014
};

回到Main函数继续分析sub_8048414(a2[1], 0):

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
int __cdecl sub_8048414(_BYTE *a1, int a2)
{
int result; // eax

switch ( a2 )
{
case 0:
if ( *a1 == 105 )
goto LABEL_19;
result = 0;
break;
case 1:
if ( *a1 == 101 )
goto LABEL_19;
result = 0;
break;
case 3:
if ( *a1 == 110 )
goto LABEL_19;
result = 0;
break;
case 4:
if ( *a1 == 100 )
goto LABEL_19;
result = 0;
break;
case 5:
if ( *a1 == 97 )
goto LABEL_19;
result = 0;
break;
case 6:
if ( *a1 == 103 )
goto LABEL_19;
result = 0;
break;
case 7:
if ( *a1 == 115 )
goto LABEL_19;
result = 0;
break;
case 9:
if ( *a1 == 114 )
LABEL_19:
result = sub_8048414(a1 + 1, 7 * (a2 + 1) % 11);
else
result = 0;
break;
default:
result = 1;
break;
}
return result;
}

看到是一个很长的控制流, **_BYTE a1, int a2* 就是带入的 a2[1], 0
当 a2 = 0 时,进入 case0,a1被赋值为105,进入LABEL_19,调用了sub_8048414 我们所在的函数,所以判断这就是一个递归
每次完成赋值goto到 LABEL_19 会对a2重新运算 7 * (a2 + 1) % 11 ,写一个脚本跑一下 (当然也可以手算)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>

int main() {
unsigned int a1[] = {105, 101, 0, 110, 100, 97, 103, 115, 0, 114};
int a2 = 0;
for (int i = 0; i < 8; i++)
{
printf("%d,", a1[a2]);
a2 = 7 * (a2 + 1) % 11;
}
return 0;
}

// 105,115,101,110,103,97,114,100,

编写解密脚本(C):

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

int main() {
unsigned int a2[] = {105, 115, 101, 110, 103, 97, 114, 100};
unsigned int v2[33] = {
0x0000000F, 0x0000001F, 0x00000004, 0x00000009, 0x0000001C, 0x00000012, 0x00000042, 0x00000009,
0x0000000C, 0x00000044, 0x0000000D, 0x00000007, 0x00000009, 0x00000006, 0x0000002D, 0x00000037,
0x00000059, 0x0000001E, 0x00000000, 0x00000059, 0x0000000F, 0x00000008, 0x0000001C, 0x00000023,
0x00000036, 0x00000007, 0x00000055, 0x00000002, 0x0000000C, 0x00000008, 0x00000041, 0x0000000A,
0x00000014
};
char flag[50] = {0};

for (int i = 0; i <= 32; ++i ) {
flag[i] = v2[i] ^ a2[i % 8];
}

printf("%s",flag);
return 0;
}

// flag{s0me7hing_S0me7hinG_t0lki3n}

写的不好,有不对的地方请指出,谢谢 ><