Mine

DIE打开是x64的win程序,无壳,直接IDA.

进去一看,好家伙,c++的程序用gcc编译,那就分析吧.

image-20231013124905486

用控制台尝试运行一下,可以知道这是一个扫雷游戏,游戏题优先去找游戏终止判定,往往游戏胜利后会有一些关于flag的操作.

image-20231013125635703

中文乱码不影响,我们很容易能够找到游戏主循环体:

image-20231013125853759

1和2即为循环终止条件和当前成功找到的地雷数.

再往后看找到游戏胜利处理:

image-20231013130011930 image-20231013130051478

这里C++的代码不予解释…别问,问就是去打基础…

我们发现ans数组在运行时初始化,我们通过交叉引用可以找到,直接写代码:

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

int main() {
char enc[] = "*ur)O}t@r{u!c&|}d\\9m>M4NtsrjL";
int len = strlen(enc);
for (int i = 0; i < len; i++) {
printf("%c", (len-i)^enc[i]);
}
return 0;
}

得到结果:

7ii3VecVgof3r6ssiP2g7E3HqwqhM

或者可以去开挂然后动调,但是我懒得去搞了…比赛的时候试了一下,没有问题,我的做法是把

while ( 100 - mine_sum != res )100给patch成25(mine_sum初始值是25),这样游戏直接胜利(我不会玩扫雷).

一样可以输出结果.

最后就是最抽象的了,我们要进行base58解码,还得是那个特定的网站才行…我一度以为我做错了…

image-20231013132203167

结束…

easyEZbaby_app

这题也很简单,会一点java就好.

我们看到apk先丢到模拟器跑一下看看(我没搞,直接看的代码Orz),然后喂给JADX反编译.

onClick()方法中可以看到只要求出这里的obj和obj2即可:

image-20231013145006310 从checkUsername()方法中知道obj字符串就是"zhishixuebao"md5摘要的各个奇数位的字符:

image-20231013145254632 写脚本:

1
2
3
4
5
6
7
from hashlib import md5

str = "zhishixuebao"
md5_str = md5(str.encode('utf-8')).hexdigest()
# 取出偶数下标的字符
print(md5_str[::2])
#7afc4fcefc616ebd

分析checkPass()方法,我们直接爆破即可(懒得反推了,实际上就换一下位置就行…):

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

int main() {
for (int i = 0; i < 15; ++i) {
for (int c = 0; c <= 128; ++c) {
int temp = ((((255 - i) + 2) - 98) - c);
if (temp == '0') {
putchar(c); // onmlkjihgfedcba
break;
}
}
}
return 0;
}

连接起来就是:

flag{7afc4fcefc616ebdonmlkjihgfedcba}

结束…

ezOrz

这题我出的…不难吧…怎么这道题做出来的人最少…我反思Orz

程序有一个加壳,先使用UPX去壳.

使用IDA分析可得,题目中有一个密钥,要用其进行加密.

但是密钥经过了处理,将密钥的每个字节进行了高4位和低4位的交换.然后,将输入的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
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int swap_bit4(char *a, int len) {
for (int i = 0; i < len; ++i) {
char temp = a[i];
temp = (temp << 4) + (temp >> 4);
a[i] = temp;
}
return 0;
}

int my_xor(char *a, int len) {
for (int i = len - 2; i >= 0; --i) {
a[i] ^= a[i + 1];
}
return 0;
}

int main() {
//buf需要动态调试从IDA导出
char buf[50] = {
174, 27, 224, 233, 184, 51, 180, 156, 177, 124,
40, 208, 154, 101, 186, 235, 67, 239, 136, 12,
46, 86, 0
};
for(int i=0;i<19;++i)
printf("%d ",buf[i]);
char v[] = "Jan_Ye_yyds_Orz";
int len = 19;
swap_bit4(v, 15);

for (int i = 0; i < 19; i++) {
buf[i] ^= v[i % strlen(v)];
}
my_xor(buf, 19);

for (int i = 0; i < 19; ++i) {
putchar(buf[i]);
}
return 0;
}

flag{V3ry_ez_1sn!t}

结束…

ezpy

这题还是我出的…巨简单,RC4直接把密文当明文再跑一遍就行.

简单的将密文进行base64解码,然后进行RC4解密即可.

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
import base64

keys = 'Flag{This_a_Flag}'
flag = "xxxxxxxxxxxxxxxx"
def do_something(enc='', key=''):
enc += '\0'
s_box = list(range(256))
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
i = j = 0
res = []
for s in enc:
i = (i + 1) % 256
j = (j + s_box[i]) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
t = (s_box[i] + s_box[j]) % 256
k = s_box[t]
res.append(chr(ord(s) ^ k))

res_str = ''
for i in res:
# print(i, end="")
res_str += i
return res_str

res = 'wq3CocO5wqXDtEotBDA6XsKrw7DDvsOxw54fOjrCpMO/b8OcwrfCgMOi'
res = base64.b64decode(res.encode()).decode()
res = do_something(res, keys)
print(res)

# res = wq3CocO5wqXDtEotBDA6XsKrw7DDvsOxw54fOjrCpMO/b8OcwrfCgMOi

flag{Ju2t_4n_3x4mple_RCa}

结束…

eazyre

有UPX3.95加壳,直接用upx脱壳,再分析:

image-20231013151027895

找字符串,发现f_part2有flag的后半截:

image-20231013151132760

part1函数中有前半截,直接按r快捷键然后排列处理一下出flag(注意小端序转换):

image-20231013151300702

flag{UPX_4nd_0n3_4nd_tw0}

结束…

eazyxor

第一步对flag进行循环异或加密,密钥为"SCNU".

然后将flag每一个字符转换为特定数量的’1’和一个’0’,其中’1’的数量为该字符的ASCII码.

提取出数据直接写解密程序即可:

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
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
unsigned char enc[] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 255
};
int idx = 0, idx_flag = 0;
int c = 0;
int flag[100];
while (1) {
if (enc[idx] == 255)
break;
if (enc[idx] == 1)
c++;
if (enc[idx] == 0) {
flag[idx_flag++] = c;
c = 0;
}
idx++;
}

char key[] = "SCNU";
for (int i = 0; i < idx_flag; ++i)
putchar(flag[i] ^ key[i % 4]);
return 0;
}

flag{Winn3r_n0t_L0s3r_#}

结束…

toddler_regs

这个题我当时最后一个点莫名其妙跑出来的…

动调修改,第一步运行到stage_1()的调用处,patch汇编,把32改成23:

image-20231013153754275

然后同样在调用j_stage_2_fake()时将call指令patch为call j_stage_2_real:

image-20231013154357033

然后继续单步调试,直到提示从指定的地址读取flag,我们按g快捷键跳转过去提取出来即可:

image-20231013154450248 image-20231013154512103
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
unsigned char flag[] =
{
102, 108, 97, 103, 123, 88, 112, 48, 105, 110,
116, 95, 49, 115, 95, 110, 49, 99, 51, 95,
98, 117, 116, 95, 88, 112, 48, 105, 110, 116,
74, 78, 85, 95, 105, 115, 95, 119, 101, 49,
114, 100, 125, 0, 0, 0, 0, 0, 0, 0
};
puts(flag);
return 0;
}

flag{Xp0int_1s_n1c3_but_Xp0intJNU_is_we1rd}

结束…