RE

kernel

在固件 kernel.sys 中发现关键加密
sub_140001740是xtea加密函数,key[4] = {0x1234,0x3A4D,0x5E6F,0xAA33}
20240529151742
xtea魔改过
20240529153534
密文
20240529153746

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
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
void decrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], delta = 0x61CEEEEF, sum = 0 - delta * num_rounds;
for (i=0; i < num_rounds; i++) {
v1 -= (((v0 << 3) ^ (v0 >> 6)) + v0) ^ (sum + key[(sum>>11) & 3]);
sum += delta;
v0 -= (((v1 << 2) ^ (v1 >> 6)) + v1) ^ (sum + key[sum & 3]);

}
v[0] = v0; v[1] = v1;
}
void encrypt(uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0=v[0], v1=v[1], sum=0, delta = 0x61CEEEEF;
for (i=0; i < 32; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum -= delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
}
v[0]=v0; v[1]=v1;
}
int main() {
uint32_t const k[4] = {0x1234,0x3A4D,0x5E6F,0xAA33};
uint32_t enc[] = {
0x8CCAF011, 0x835A03B8, 0x6DCC9BAD, 0xE671FA99, 0xE6011F35, 0xE5A56CC8, 0xD4847CFA, 0x5D8E0B8E};
unsigned int r = 33;
for(int i=0; i<8; i+=2){
decrypt(r, &enc[i], k);
}
printf("Decrypted data is: %s\n",(char*)enc);//端序出错
for(int i=0; i<8; i++){
printf("%c%c%c%c",enc[i]>>24&0xff, enc[i]>>16&0xff, enc[i]>>8&0xff, enc[i]&0xff);
}
return 0;
}
/*
Decrypted data is: galfiLx{QSS1YzRzfM3wePOHCAkJ}m4m4
flag{xLi1SSQzRzYw3MfHOPeJkACm4m}
*/

crazyaes

先修复文件,PE头的P被修改了,改回来
20240529155025
然后查壳发现有UPX壳,特征被修改了,改成UPX0,UPX1
20240529190440
脱壳完有个花指令,nop一下
20240529213808
分析发现关键加密
20240602163711
点进去发现是AES加密
20240602181408
多了两个异或 0xA1 和 0x54
20240603205857
20240603210048
key 第 2 位被修改了
20240603210548
所以就是AES在字节替换和列混合的矩阵相乘的时候多了异或

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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
from Crypto.Util.number import *

class AES:

MIX_C = [[0x2, 0x3, 0x1, 0x1], [0x1, 0x2, 0x3, 0x1], [0x1, 0x1, 0x2, 0x3], [0x3, 0x1, 0x1, 0x2]]
I_MIXC = [[0xe, 0xb, 0xd, 0x9], [0x9, 0xe, 0xb, 0xd], [0xd, 0x9, 0xe, 0xb], [0xb, 0xd, 0x9, 0xe]]
RCon = [0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000]

S_BOX = [[99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118],
[202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192],
[183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21],
[4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117],
[9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132],
[83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207],
[208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168],
[81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210],
[205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115],
[96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219],
[224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121],
[231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8],
[186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138],
[112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158],
[225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223],
[140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22]]

I_SBOX = [[82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251],
[124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203],
[84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78],
[8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37],
[114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146],
[108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132],
[144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6],
[208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107],
[58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115],
[150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110],
[71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27],
[252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244],
[31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95],
[96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239],
[160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97],
[23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125]]

def SubBytes(self, State):
# 字节替换
return [self.S_BOX[i][j]^0xA1 for i, j in
[(_ >> 4, _ & 0xF) for _ in State]]

def SubBytes_Inv(self, State):
# 字节逆替换
State = [i^0xA1 for i in State]
return [self.I_SBOX[i][j] for i, j in
[(_ >> 4, _ & 0xF) for _ in State]]

def ShiftRows(self, S):
# 行移位
return [S[ 0], S[ 5], S[10], S[15],
S[ 4], S[ 9], S[14], S[ 3],
S[ 8], S[13], S[ 2], S[ 7],
S[12], S[ 1], S[ 6], S[11]]

def ShiftRows_Inv(self, S):
# 逆行移位
return [S[ 0], S[13], S[10], S[ 7],
S[ 4], S[ 1], S[14], S[11],
S[ 8], S[ 5], S[ 2], S[15],
S[12], S[ 9], S[ 6], S[ 3]]

def MixColumns(self, State):
# 列混合
return self.Matrix_Mul(self.MIX_C, State)

def MixColumns_Inv(self, State):
# 逆列混合
return self.Matrix_Mul(self.I_MIXC, State)

def RotWord(self, _4byte_block):
# 用于生成轮密钥的字移位
return ((_4byte_block & 0xffffff) << 8) + (_4byte_block >> 24)

def SubWord(self, _4byte_block):
# 用于生成密钥的字节替换
result = 0
for position in range(4):
i = _4byte_block >> position * 8 + 4 & 0xf
j = _4byte_block >> position * 8 & 0xf
result ^= self.S_BOX[i][j] << position * 8
return result

def mod(self, poly, mod = 0b100011011):
# poly模多项式mod
while poly.bit_length() > 8:
poly ^= mod << poly.bit_length() - 9
return poly

def mul(self, poly1, poly2):
# 多项式相乘
result = 0
for index in range(poly2.bit_length()):
if poly2 & 1 << index:
result ^= poly1 << index
return result

def Matrix_Mul(self, M1, M2): # M1 = MIX_C M2 = State
# 用于列混合的矩阵相乘
M = [0] * 16
for row in range(4):
for col in range(4):
for Round in range(4):
M[row + col*4] ^= self.mul(M1[row][Round], M2[Round+col*4])
M[row + col*4] = self.mod(M[row + col*4])
M[row + col*4] ^= 0x54
return M

def round_key_generator(self, _16bytes_key):
# 轮密钥产生
w = [_16bytes_key >> 96,
_16bytes_key >> 64 & 0xFFFFFFFF,
_16bytes_key >> 32 & 0xFFFFFFFF,
_16bytes_key & 0xFFFFFFFF] + [0]*40
for i in range(4, 44):
temp = w[i-1]
if not i % 4:
temp = self.SubWord(self.RotWord(temp)) ^ self.RCon[i//4-1]
w[i] = w[i-4] ^ temp
return [self.num_2_16bytes(
sum([w[4 * i] << 96, w[4*i+1] << 64,
w[4*i+2] << 32, w[4*i+3]])
) for i in range(11)]

def AddRoundKey(self, State, RoundKeys, index):
# 异或轮密钥
return self._16bytes_xor(State, RoundKeys[index])

def _16bytes_xor(self, _16bytes_1, _16bytes_2):
return [_16bytes_1[i] ^ _16bytes_2[i] for i in range(16)]

def _16bytes2num(cls, _16bytes):
# 16字节转数字
return int.from_bytes(_16bytes, byteorder = 'big')

def num_2_16bytes(cls, num):
# 数字转16字节
return num.to_bytes(16, byteorder = 'big')

def aes_encrypt(self, plaintext_list, RoundKeys):
State = plaintext_list
State = self.AddRoundKey(State, RoundKeys, 0)
xor_key=[0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x03, 0x02, 0x02, 0x03, 0x00, 0x01, 0x03, 0x02, 0x01, 0x00]
State = [State[i]^xor_key[i] for i in range(len(xor_key))]
for Round in range(1, 10):
State = self.SubBytes(State)
State = self.ShiftRows(State)
State = self.MixColumns(State)
State = self.AddRoundKey(State, RoundKeys, Round)
State = [State[i]^xor_key[i] for i in range(len(xor_key))]
State = self.SubBytes(State)
State = self.ShiftRows(State)
State = self.AddRoundKey(State, RoundKeys, 10)
State = [State[i]^xor_key[i] for i in range(len(xor_key))]
return State

def aes_decrypt(self, ciphertext_list, RoundKeys):
State = ciphertext_list
xor_key=[0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x03, 0x02, 0x02, 0x03, 0x00, 0x01, 0x03, 0x02, 0x01, 0x00]
State = [State[i]^xor_key[i] for i in range(len(xor_key))]
State = self.AddRoundKey(State, RoundKeys, 10)
for Round in range(1, 10):
State = self.ShiftRows_Inv(State)
State = self.SubBytes_Inv(State)
State = [State[i]^xor_key[i] for i in range(len(xor_key))]
State = self.AddRoundKey(State, RoundKeys, 10-Round)
State = self.MixColumns_Inv(State)
State = self.ShiftRows_Inv(State)
State = self.SubBytes_Inv(State)
State = self.AddRoundKey(State, RoundKeys, 0)
return State

if __name__ == '__main__':

aes = AES()
key = bytes_to_long(b'gah43jJKgfjGMeAR')
RoundKeys = aes.round_key_generator(key)

#加密
plaintext = bytes_to_long(b'fmcdzRf]3ws^e2o}')
plaintext = aes.num_2_16bytes(plaintext)
ciphertext = aes.aes_encrypt(plaintext, RoundKeys)
print('ciphertext = ' + hex(aes._16bytes2num(ciphertext)))

# 解密
#ciphertext = 0xB43836301E6848575101B7039B98E37E
ciphertext = bytes_to_long(bytes(ciphertext))
ciphertext = aes.num_2_16bytes(ciphertext)
plaintext = aes.aes_decrypt(ciphertext, RoundKeys)
print(bytes(plaintext))
#flag{Re_1ts_f0n}

puzzle

check在parse里
20240603221727
读入a就乘以2,读入b就-1除以3
20240603222248
最后结果是 ISCC2024
20240603222329
DFS梭
20240603224309

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
#include <iostream>
#include <string>
#include <cstring>

int ch2num(int ch) {
return ch ^ 0x8D;
}

std::string code;
bool done = false;
char record[0x100] = { 0 };
int index = 0;

void DFS(int x, char ch) {

if (done) return;
record[index++] = ch;

if (x == 1) {
while (index > 0) {
code.push_back(record[--index]);
}
code.push_back('-');
done = true;
return;
}

if (x % 2 == 0) {
DFS(x / 2, 'a');
}
DFS(x * 3 + 1, 'b');
--index;
}

int main() {
std::string answer = "ISCC2024";
int table[8];
for (int i = 0; i < 8; ++i) {
table[i] = ch2num(answer[i]) - (7 - i);
std::cout << table[i] << std::endl;
}

for (int i = 7; i >= 0; --i) {
std::memset(record, 0, sizeof(record));
index = 0;
done = false;
DFS(table[i], 0);
}
if (!code.empty()) {
code.pop_back();
}

std::cout << code << std::endl;
}
/*
189
216
201
202
188
187
190
185
aaaabaaabaababaaababaaaababaababaaabaababaab-aaaabaaaaabababaaabaaaabaabaabaaaababababaaababababababaababaabababaaabaababababaabababaababaaaabababababa-aaaabaaabaababaaababaaaabaaabababaaababaabab-aaaabaaaaabababaaabaaaabaabaabaaaababababaaababababababaababaabababaaabaababababaabababaababaabaababababaa-aaaabaaabaababaaababaaaaba-aaaaaaaaaabababaab-aaaabaaaaabababaaabaaaabaabaabaaaababababaaababababababaababaabababaaabaababababaabababaababaabaabababababaababaaa-aaaabaaaaabababaaabaaaabaabaabaaaababababaaababababababaababaabababaaabaababababaabababaababaabaabababaaab
flag{W0w_U_Ar3_V3ry_G00d_A7_C0unt1n9_3c968eb5d72c3dca}
*/