唯一做出来的一道…

Reverse

ISA Intrusion

这个题是在线平台,貌似是ARM架构的汇编,同时有其他题的代码,将本题的汇编代码复制到第一个选项去调试分析.

发现实际上程序对栈底的一段数据进行了3轮循环,每个循环都进行一种变换.

代码第一次尝试运行,发现并没有以正常的0值返回,而是返回65:

image-20231113235555883

下断点进行调试发现程序始终在最开头的一个简单的循环运行,最终崩溃(貌似是循环太大了,对这种汇编不是很了解),静态分析发现这个循环可以直接删除:

image-20231114000137754

后面的分析就很简单了,就是压栈4段数据,其中栈底的那一段是密文.

代码使用另外的3段数据对密文依次进行3次循环,每次循环都进行简单的变换(按位异或,按位与,按位或).

然后发现程序在最后的4行进行了一个syscall,经过测试(当时因为发现还有其他代码,可能也算是非预期?)发现R8寄存器中存储的是"系统调用号"(ARM也有这个吧大概?),不过和x86,x64不一样.

这里的2对应exit,1对应write,所以把代码最后的4行换成如下的5行:

1
2
3
4
5
6
7
8
9
; MOV R1, 0;
; MOV R8, 2;
; SYSCALL;
; ADD SP, 412;
MOV R1,R4;
MOV R2,200;
MOV R8,1; 1相当于x86的write的系统调用号
SYSCALL;
ADD SP,412;

这样就能输出栈底的flag(起始地址为0xffffff88):

image-20231114001113136

注意得记得把开头的那个循环删掉.


或者费劲点也可以复制出来手动输出:

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

int main() {
char ogn[] = "ffffff8865636b68ffffff8c33327472ffffff906d30737bffffff946d317433ffffff9837695f33ffffff9c34655f73ffffffa072336973ffffffa45f30375fffffffa8346e7964ffffffac5f63316dffffffb05f763372ffffffb47435756affffffb87434705fffffffbc6c266863ffffffc05f6b6f30ffffffc46d5f7434ffffffc8726f6d33ffffffcc00007d79";
char str[1000] = {0};
for (int i = 0, j = 0; i < strlen(ogn); i += 8, j += 8) {
i += 8;
strncpy(str + j, ogn + i, 8);
}
for(int i=0;i<strlen(str);i+=2){
printf("\\x%c%c",str[i],str[i+1]);
}
putchar('\n');
return 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
// print_flag.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

int main() {
// export_data.exe输出的结果放入
char str[1000]="\x65\x63\x6b\x68\x33\x32\x74\x72\x6d\x30\x73\x7b\x6d\x31\x74\x33\x37\x69\x5f\x33\x34\x65\x5f\x73\x72\x33\x69\x73\x5f\x30"
"\x37\x5f\x34\x6e\x79\x64\x5f\x63\x31\x6d\x5f\x76\x33\x72\x74\x35\x75\x6a\x74\x34\x70\x5f\x6c\x26\x68\x63\x5f\x6b\x6f\x30"
"\x6d\x5f\x74\x34\x72\x6f\x6d\x33\x00\x00\x7d\x79";
// 4个字符一组进行翻转
for (int i = 0; i < 1000; i += 4) {
char tmp = str[i];
str[i] = str[i + 3];
str[i + 3] = tmp;
tmp = str[i + 1];
str[i + 1] = str[i + 2];
str[i + 2] = tmp;
}
printf("%d\n", strlen(str));
puts(str);
return 0;
}

运行结果:

image-20231114001249077

结束…

附带当时拷贝下来的汇编指令:

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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
SUB SP, 412;
MOV R1, 0;
MOV R1, SP;
MOV SP, FP;
SUB SP, 4;
PUSH 0xcd98394d;
PUSH 0xb3d55b45;
PUSH 0xdfcd034a;
PUSH 0xa7dd4e9f;
PUSH 0xe306c1ea;
PUSH 0x7bfba3;
PUSH 0xf69fbcc5;
PUSH 0x4493b0c7;
PUSH 0xf48710fc;
PUSH 0x4605c0a1;
PUSH 0x7714569d;
PUSH 0x99e0ee;
PUSH 0x418372ef;
PUSH 0x810089a6;
PUSH 0xf613a578;
PUSH 0x327f241e;
PUSH 0x39b92ff4;
PUSH 0x3ce1d9c7;
PUSH 0x28a53724;
PUSH 0xc341fce;
PUSH 0x93e9df15;
PUSH 0xde0c7383;
PUSH 0x161c73a6;
PUSH 0x5fed2896;
PUSH 0xe302a383;
MOV SP, R1;
MOV R1, SP;
MOV SP, FP;
SUB SP, 104;
PUSH 0xb18e3a66;
PUSH 0x93af8a20;
PUSH 0x71426981;
PUSH 0x855ec36b;
PUSH 0x51b4612d;
PUSH 0x7227ddc8;
PUSH 0x2f2fbbd6;
PUSH 0x63e8c5b;
PUSH 0x5ac9e294;
PUSH 0xe30baa4b;
PUSH 0x8e009a51;
PUSH 0x6e5e1eac;
PUSH 0x5bed520d;
PUSH 0xafac26ce;
PUSH 0xa46a180c;
PUSH 0x4cf5b158;
PUSH 0x148d9fbd;
PUSH 0xa008a3c0;
PUSH 0x8d4e9273;
PUSH 0xb21906e5;
PUSH 0xd20edf1;
PUSH 0x179f5e2d;
PUSH 0xdfcc7b6c;
PUSH 0xfdc42107;
PUSH 0x1ecbb256;
MOV SP, R1;
MOV R1, SP;
MOV SP, FP;
SUB SP, 204;
PUSH 0x83e9fcd4;
PUSH 0xdf852e9a;
PUSH 0x51709534;
PUSH 0xdd7c720b;
PUSH 0x4d4d5f38;
PUSH 0x8da3d994;
PUSH 0x264ff8ec;
PUSH 0xbd52ff7b;
PUSH 0x73ff6db7;
PUSH 0x7ffff535;
PUSH 0x5feb7f33;
PUSH 0xfd3e69ff;
PUSH 0xf5b5ff5f;
PUSH 0xf57775ff;
PUSH 0xfff673fb;
PUSH 0xdf777bfd;
PUSH 0xf6ef7ff6;
PUSH 0x7f36b7ff;
PUSH 0x7a377bfb;
PUSH 0x75f7fff7;
PUSH 0x777fdf3b;
PUSH 0x7f7df673;
PUSH 0x7f3ff77f;
PUSH 0x7ff6f67e;
PUSH 0x6777ef6a;
MOV SP, R1;
MOV R1, SP;
MOV SP, FP;
SUB SP, 304;
PUSH 0x0;
PUSH 0x0;
PUSH 0x0;
PUSH 0x0;
PUSH 0x0;
PUSH 0x0;
PUSH 0x0;
PUSH 0x4161;
PUSH 0x50210d13;
PUSH 0x48511414;
PUSH 0x66b2330;
PUSH 0x200021;
PUSH 0x6410501d;
PUSH 0x50115002;
PUSH 0xd060202;
PUSH 0x1612029;
PUSH 0x104a4924;
PUSH 0x43100558;
PUSH 0x52104820;
PUSH 0x404650;
PUSH 0x21204d13;
PUSH 0x24205011;
PUSH 0x24207331;
PUSH 0x11127462;
PUSH 0x226a28;
MOV SP, R1;
MOV R1, [FP-4];
MOV R1, 0;
MOV R2, FP;
SUB R2, 204;
MOV R3, R2;
ADD R3, R1;
MOV R4, FP;
SUB R4, 104;
MOV R5, R4;
ADD R5, R1;
MOV R6, [R3];
XOR [R5], R6;
ADD R1, 4;
LT R1, 100;
JNZ -159;
MOV R1, 0;
MOV R3, FP;
SUB R3, 304;
MOV R5, R3;
ADD R5, R1;
MOV R6, R4;
ADD R6, R1;
MOV R7, [R5];
AND [R6], R7;
ADD R1, 4;
LT R1, 100;
JNZ -134;
MOV R1, 0;
MOV R5, FP;
SUB R5, 404;
MOV R6, R5;
ADD R6, R1;
MOV R7, R4;
ADD R7, R1;
MOV R8, [R6];
OR [R7], R8;
ADD R1, 4;
LT R1, 100;
JNZ -133;
; MOV R1, 0;
; MOV R8, 2;
; SYSCALL;
; ADD SP, 412;
MOV R1,R4;
MOV R2,200;
MOV R8,1; 1相当于x86的write的系统调用号
SYSCALL;
ADD SP,412;

;R8 -> 系统调用号
; syscall: 3->read,1->print_to_shell,2->exit
;print_to_shell: R1->buf?,R2->len,R8=1(syscall)
;FP->ebp