game- misc?

情景再现(非预期)

附件给了两个, 程序是个贪吃蛇?

image-20230325164723412

image-20230325164929268

查壳

image-20230325164750590

然后拖入ida分析

image-20230325164850328

发现这儿有个png文件 要被读取, 那么根据 经验 给的另一个附件 感觉就是把那个文件变为png 然后读出flag

核心:

计算出 怎么把给的附件 变为 png 的文件头

根本就不用看程序到底是干啥的

image-20230325165930097

计算出 ^ 0x80 正好是png的文件头

image-20230325165909083

然后exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enc = open("sinke", mode="rb")
encData = enc.read()

encDataLen = len(encData)

# 输出的文件
decData = open(r"flag.png", "wb")

# key
key = bytes(b"0x80")

# 循环解密
for i in range(encDataLen):
decData.write(bytes([encData[i] ^ 0x80]))

decData.close()

enc.close()



然后 得到flag

image-20230325170155482

预期解

没有 预期解 各种花里胡哨的 操作都能做出来

正经人 谁去 玩游戏

逆向就是来破解的(Orz)

然后的话 笔者的思路就是上面那样

(感觉出题人应该随便拿以前做的某个项目 做一层迷惑 然后 当作签到题嘛 嘿嘿)

easykernel - 魔改tea系列

? kernel - 内核

我拿到 我想 what? 让我去找的漏洞嘛

.ko 就是内核文件

不扯了 讲思路

直接拖入ida 静态分析

image-20230325171655863

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
unsigned __int64 __fastcall dev_write(__int64 a1, __int64 a2, unsigned __int64 a3)
{
unsigned int v3; // edx
unsigned int sum; // eax
int key2; // er15
unsigned int v6; // er11
int key4; // er13
int key5; // er12
unsigned int v9; // ebx
unsigned int v10; // er10
unsigned int v11; // er9
unsigned int v12; // edi
unsigned int v13; // esi
unsigned int v14; // er8
unsigned int v15; // ecx
int v16; // er12
int key9; // [rsp+4h] [rbp-B4h]
int key8; // [rsp+8h] [rbp-B0h]
int key7; // [rsp+Ch] [rbp-ACh]
int key6; // [rsp+10h] [rbp-A8h]
int key3; // [rsp+14h] [rbp-A4h]
int key1; // [rsp+18h] [rbp-A0h]
__int64 v25[2]; // [rsp+28h] [rbp-90h]
__int64 s2[4]; // [rsp+38h] [rbp-80h] BYREF
int v27; // [rsp+58h] [rbp-60h]
unsigned int s1; // [rsp+5Ch] [rbp-5Ch] BYREF
unsigned int v29; // [rsp+60h] [rbp-58h]
unsigned int v30; // [rsp+64h] [rbp-54h]
unsigned int v31; // [rsp+68h] [rbp-50h]
unsigned int v32; // [rsp+6Ch] [rbp-4Ch]
unsigned int v33; // [rsp+70h] [rbp-48h]
unsigned int v34; // [rsp+74h] [rbp-44h]
unsigned int v35; // [rsp+78h] [rbp-40h]
unsigned int v36; // [rsp+7Ch] [rbp-3Ch]
unsigned __int64 v37; // [rsp+80h] [rbp-38h]

v37 = __readgsqword(0x28u);
v27 = 1182995140;
s2[0] = 0x7FB3950C883B3AALL;
s2[1] = 0x7AB57E2775BC5959LL;
s2[2] = 0xADA35753C0249800LL;
s2[3] = 0x6E14AF04BF1D493FLL;
v25[0] = 0xE000004DBLL;
v25[1] = 0x2A600000017LL;
if ( a3 > 0x23 )
copy_from_user(&s1, a2, 36LL);
key1 = 14;
v3 = v36;
sum = 0x67616C66;
key2 = 678;
key3 = 23;
v6 = v29;
key4 = 1243;
key5 = 14;
key6 = 678;
v9 = s1; // 这是原密钥
key7 = 1243;
v10 = v30;
key8 = 14;
v11 = v31;
v12 = v33;
v13 = v34;
key9 = 23;
v14 = v32;
v15 = v35;
while ( 1 )
{
v9 += ((v3 ^ key5) + (v6 ^ sum)) ^ (((4 * v6) ^ (v3 >> 5)) + ((v6 >> 3) ^ (16 * v3)));
v6 += ((v9 ^ key4) + (v10 ^ sum)) ^ (((4 * v10) ^ (v9 >> 5)) + ((16 * v9) ^ (v10 >> 3)));
v10 += ((v6 ^ key2) + (sum ^ v11)) ^ (((4 * v11) ^ (v6 >> 5)) + ((16 * v6) ^ (v11 >> 3)));
v11 += ((v10 ^ key9) + (sum ^ v14)) ^ (((4 * v14) ^ (v10 >> 5)) + ((16 * v10) ^ (v14 >> 3)));
v14 += ((v11 ^ key8) + (v12 ^ sum)) ^ (((4 * v12) ^ (v11 >> 5)) + ((16 * v11) ^ (v12 >> 3)));
v12 += ((v14 ^ key7) + (v13 ^ sum)) ^ (((4 * v13) ^ (v14 >> 5)) + ((16 * v14) ^ (v13 >> 3)));
v13 += ((v12 ^ key6) + (v15 ^ sum)) ^ (((4 * v15) ^ (v12 >> 5)) + ((16 * v12) ^ (v15 >> 3)));// 移位混合运算
v15 += ((v13 ^ key3) + (sum ^ v3)) ^ (((16 * v13) ^ (v3 >> 3)) + ((4 * v3) ^ (v13 >> 5)));
v16 = (v15 ^ key1) + (v9 ^ sum);
sum += 0x67616C66;
v3 += v16 ^ (((16 * v15) ^ (v9 >> 3)) + ((4 * v9) ^ (v15 >> 5)));
if ( sum == 0xD89114C8 ) // 0xD89114C8 = 12 *0x67616C66
break; // sum == 0xD89114C8
// 跳出while
// 执行原密钥流
key5 = *((_DWORD *)v25 + ((sum >> 2) & 3));
key2 = *((_DWORD *)v25 + (((unsigned __int8)(sum >> 2) ^ 2) & 3));// 生成新密钥
key4 = *((_DWORD *)v25 + (((unsigned __int8)(sum >> 2) ^ 1) & 3));
key8 = key5;
key1 = key5;
key9 = *((_DWORD *)v25 + (~(unsigned __int8)(sum >> 2) & 3));
key7 = *((_DWORD *)v25 + (((unsigned __int8)(sum >> 2) ^ 5) & 3));
key6 = *((_DWORD *)v25 + (((unsigned __int8)(sum >> 2) ^ 6) & 3));
key3 = *((_DWORD *)v25 + (((unsigned __int8)(sum >> 2) ^ 7) & 3));
}
v33 = v12;
v34 = v13;
v36 = v3;
s1 = v9;
v29 = v6;
v30 = v10;
v31 = v11;
v32 = v14;
v35 = v15;
byte_CA8 = memcmp(&s1, s2, 36uLL) == 0;
return a3;
}

一眼tea 又一眼xtea

算了 算啦 啥也不是 tea系列魔改

1
2
3
4
5
6
7
8
9
v27 = 1182995140;
s2[0] = 0x7FB3950C883B3AALL;
s2[1] = 0x7AB57E2775BC5959LL;
s2[2] = 0xADA35753C0249800LL;
s2[3] = 0x6E14AF04BF1D493FLL;
// 密文 正好4 * 9 = 36个字节

v25[0] = 0xE000004DBLL;
v25[1] = 0x2A600000017LL; // 密钥key

image-20230325172016174

s1-明文 , s2- 密文

cmp 很重要嘿嘿

image-20230325172744010

贴exp

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
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <iostream>
#include <Windows.h>
using namespace std;

void encry()
{
unsigned int key4; // edx
unsigned int sum; // eax
int key2; // r15d
unsigned int v6; // r11d
int key3; // r13d
int key1; // r12d
unsigned int v9; // ebx
unsigned int v10; // r10d
unsigned int v11; // r9d
unsigned int v12; // edi
unsigned int v13; // esi
unsigned int v14; // r8d
unsigned int v15; // ecx
unsigned int v17; // ecx
int v16; // r12d
int key5; // [rsp+4h] [rbp-B4h]
int v19; // [rsp+8h] [rbp-B0h]
int key6; // [rsp+Ch] [rbp-ACh]
int key7; // [rsp+10h] [rbp-A8h]
int key8; // [rsp+14h] [rbp-A4h]
int v23; // [rsp+18h] [rbp-A0h]
//__int64 key[2]; // [rsp+28h] [rbp-90h]
__int64 s2[4]; // [rsp+38h] [rbp-80h] BYREF
int v27; // [rsp+58h] [rbp-60h]
unsigned int s1; // [rsp+5Ch] [rbp-5Ch] BYREF
unsigned int v29; // [rsp+60h] [rbp-58h]
unsigned int v30; // [rsp+64h] [rbp-54h]
unsigned int v31; // [rsp+68h] [rbp-50h]
unsigned int v32; // [rsp+6Ch] [rbp-4Ch]
unsigned int v33; // [rsp+70h] [rbp-48h]
unsigned int v34; // [rsp+74h] [rbp-44h]
unsigned int v35; // [rsp+78h] [rbp-40h]
unsigned int v36; // [rsp+7Ch] [rbp-3Ch]


BYTE mycryp[] = { 0xaa, 0xb3, 0x83, 0xc8, 0x50, 0x39, 0xfb, 0x7, 0x59, 0x59, 0xbc, 0x75, 0x27, 0x7e, 0xb5, 0x7a, 0x0, 0x98, 0x24, 0xc0, 0x53, 0x57, 0xa3, 0xad, 0x3f, 0x49, 0x1d, 0xbf, 0x4, 0xaf, 0x14, 0x6e };

v27 = 1182995140;
s2[0] = 0x7FB3950C883B3AALL;
s2[1] = 0x7AB57E2775BC5959LL;
s2[2] = 0xADA35753C0249800LL;
s2[3] = 0x6E14AF04BF1D493FLL;


//key[0] = 0xE000004DBLL;
//key[1] = 0x2A600000017LL;
uint32_t key[] = { 0x4DB,0xE,0x17,0x2A6 };

s1 = {};
/*if (a3 > 0x23)
copy_from_user(&s1, a2, 36LL);*/





v9 = 0xC883B3AA;
v6 = 0x7FB3950;
v10 = 0x75BC5959;
v11 = 0x7AB57E27;
v14 = 0xC0249800;
v12 = 0xADA35753;
v13 = 0xBF1D493F;
v15 = 0x6E14AF04;
v17 = 0x468312C4;


//sum = 0x4d89114c8;

sum = (0x67616C66 * 11);
int delta = 0x67616C66;

//计算轮数
//int count = 0;
//while (1)
//{
// sum = sum - delta;
// count++;
// if (sum == 0)
// {
// break;
// }
//}
//printf("%d\n", count);


//轮数为12, 然后解密
for (int tmp = 0; tmp < 11; tmp++)
{
if (sum != 0x67616C66)
{
//key生成
key1 = *(key + ((sum >> 2) & 3));
key2 = *(key + (((sum >> 2) ^ 2) & 3));
key3 = *(key + (((sum >> 2) ^ 1) & 3));
v19 = key1;
v23 = key1;
key5 = *(key + (~(sum >> 2) & 3));
key6 = *(key + (((sum >> 2) ^ 5) & 3));
key7 = *(key + (((sum >> 2) ^ 6) & 3));
key8 = *(key + (((sum >> 2) ^ 7) & 3));
}
else
{
//初始化key
v23 = 14;
key2 = 678;
key8 = 23;
key3 = 1243;
key1 = 14;
key7 = 678;
v19 = 14;
key5 = 23;
key6 = 1243;
}
v17 -= (v15 ^ v23) + (v9 ^ sum) ^ (((16 * v15) ^ (v9 >> 3)) + ((4 * v9) ^ (v15 >> 5)));
v15 -= ((v13 ^ key8) + (sum ^ v17)) ^ (((16 * v13) ^ (v17 >> 3)) + ((4 * v17) ^ (v13 >> 5)));
v13 -= ((v12 ^ key7) + (v15 ^ sum)) ^ (((4 * v15) ^ (v12 >> 5)) + ((16 * v12) ^ (v15 >> 3)));
v12 -= ((v14 ^ key6) + (v13 ^ sum)) ^ (((4 * v13) ^ (v14 >> 5)) + ((16 * v14) ^ (v13 >> 3)));
v14 -= ((v11 ^ v19) + (v12 ^ sum)) ^ (((4 * v12) ^ (v11 >> 5)) + ((16 * v11) ^ (v12 >> 3)));
v11 -= ((v10 ^ key5) + (sum ^ v14)) ^ (((4 * v14) ^ (v10 >> 5)) + ((16 * v10) ^ (v14 >> 3)));
v10 -= ((v6 ^ key2) + (sum ^ v11)) ^ (((4 * v11) ^ (v6 >> 5)) + ((16 * v6) ^ (v11 >> 3)));
v6 -= ((v9 ^ key3) + (v10 ^ sum)) ^ (((4 * v10) ^ (v9 >> 5)) + ((16 * v9) ^ (v10 >> 3)));
v9 -= ((v17 ^ key1) + (v6 ^ sum)) ^ (((4 * v6) ^ (v17 >> 5)) + ((v6 >> 3) ^ (16 * v17)));
sum -= 0x67616C66;

}

printf("%c%c%c%c", *((char*)&v9 + 0), *((char*)&v9 + 1), *((char*)&v9 + 2), *((char*)&v9 + 3));
printf("%c%c%c%c", *((char*)&v6 + 0), *((char*)&v6 + 1), *((char*)&v6 + 2), *((char*)&v6 + 3));
printf("%c%c%c%c", *((char*)&v10 + 0), *((char*)&v10 + 1), *((char*)&v10 + 2), *((char*)&v10 + 3));
printf("%c%c%c%c", *((char*)&v11 + 0), *((char*)&v11 + 1), *((char*)&v11 + 2), *((char*)&v11 + 3));
printf("%c%c%c%c", *((char*)&v14 + 0), *((char*)&v14 + 1), *((char*)&v14 + 2), *((char*)&v14 + 3));
printf("%c%c%c%c", *((char*)&v12 + 0), *((char*)&v12 + 1), *((char*)&v12 + 2), *((char*)&v12 + 3));
printf("%c%c%c%c", *((char*)&v13 + 0), *((char*)&v13 + 1), *((char*)&v13 + 2), *((char*)&v13 + 3));
printf("%c%c%c%c", *((char*)&v15 + 0), *((char*)&v15 + 1), *((char*)&v15 + 2), *((char*)&v15 + 3));
printf("%c%c%c%c", *((char*)&v17 + 0), *((char*)&v17 + 1), *((char*)&v17 + 2), *((char*)&v17 + 3));


}

int main()
{

encry();
return 0;
}

// 541c290d-e89f-4539-8d24-2ccbd1ead8ae