2024 春秋杯冬季赛 DAY3 RE wp

前言:先把day3的题复现了一下 其他的题目复现完在写一下吧

easyasm

ida打开附件 根据题目也可以知道是要看汇编的题

汇编开头给了两个数据

Patr1ck-day3-wp-6

Patr1ck-day3-wp-7

猜测一个密文一个密钥
首先对key进行了一个冒泡排序 两个字节一排 提取出来key
0x2030, 0x3040, 0x4050, 0x1022, 0x2011, 0x1666, 0x1522, 0x8899, 0x4155, 0x4044, 0x4288, 0x3321, 0x6033, 0xFFFF, 0x2221, 0x3366, 0x222C, 0x2CCC, 0x22CC, 0xCC22, 0xC2C2
随后继续往下看 发现一个 xor

Patr1ck-day3-wp-8

以大概的逻辑就是密文跟排序后的密钥异或 这里我写了一个脚本验证了一下 用密文的前五位异或一下flag{ 发现结果跟排序后的密钥一致

Patr1ck-day3-wp-9

直接写脚本即可

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
flag = 'flag{'  
enc = [0x44, 0x7C, 0x43, 0x72, 0x1D, 0x72, 0x74, 0x41, 0x05, 0x14,
0x19, 0x1A, 0x19, 0x0F, 0xF5, 0x10, 0xAE, 0x18, 0x6D, 0x01,
0x10, 0x56, 0x00, 0x1E, 0x26, 0x71, 0x65, 0x73, 0x78, 0x72,
0xEB, 0x72, 0x52, 0x06, 0xAA, 0xBB, 0xA3, 0xA4, 0x1B, 0xFC]
#for i in range(5):
#print(hex(enc[i] ^ ord(flag[i])),end=',')
#print()
word_10200 = [0x2030, 0x3040, 0x4050, 0x1022, 0x2011, 0x1666, 0x1522, 0x8899, 0x4155, 0x4044, 0x4288, 0x3321, 0x6033, 0xFFFF, 0x2221, 0x3366, 0x222C, 0x2CCC, 0x22CC, 0xCC22, 0xC2C2]
for i in range(len(word_10200)):
for j in range(len(word_10200) - 1 - i):
if word_10200[j] > word_10200[j + 1]:
word_10200[j], word_10200[j + 1] = word_10200[j + 1], word_10200[j]
key = []
for num in word_10200:
low = num & 0xFF
high = (num >> 8) & 0xFF
key.append(low)
key.append(high)
#print(','.join(hex(x) for x in key))
enc = [0x44, 0x7C, 0x43, 0x72, 0x1D, 0x72, 0x74, 0x41, 0x05, 0x14,
0x19, 0x1A, 0x19, 0x0F, 0xF5, 0x10, 0xAE, 0x18, 0x6D, 0x01,
0x10, 0x56, 0x00, 0x1E, 0x26, 0x71, 0x65, 0x73, 0x78, 0x72,
0xEB, 0x72, 0x52, 0x06, 0xAA, 0xBB, 0xA3, 0xA4, 0x1B, 0xFC,
0xC7, 0x82]
flag = []
for i in range(len(enc)):
flag.append(enc[i] ^ key[i])
print(chr(flag[i]), end='')
#flag{dea54885-92b4-11ef-b153-3c0af33af908}

ooooore

ida打开附件 全是花指令 一点一点去掉 后来看大佬的wp 发现用010批量去除能更快一点

Patr1ck-day3-wp-10

直接在010里全部替换为90 打开就能正确的反编译
密文和输入

Patr1ck-day3-wp-11

交叉引用密文就可以找到最后比较的部分

Patr1ck-day3-wp-12

随后看字符串时候发现一个RC4的字符

Patr1ck-day3-wp-13

所以直接在比较的地方打个断点 找加密后的密文 写脚本即可

1
2
3
4
5
6
7
8
9
10
11
12
13
print("1"*42)  
get=[ 0xD6, 0xB0, 0x2E, 0x79, 0xD9, 0xE6, 0x67, 0x8B, 0x13, 0xB7,
0x9A, 0x43, 0xFE, 0xE8, 0x29, 0xDD, 0xF8, 0x9E, 0x59, 0x63,
0xFC, 0x88, 0xAD, 0x7D, 0x78, 0x61, 0x32, 0x87, 0x9C, 0xD1,
0x11, 0xF8, 0x26, 0x6A, 0x91, 0x51, 0x85, 0x52, 0xB5, 0x15,
0x82, 0xD1]
enc=[0x81, 0xED, 0x7E, 0x2F, 0x93, 0xB6, 0x6F, 0x8D, 0x43, 0xE5, 0xC9, 0x11, 0xA9, 0xF4, 0x2B, 0xDB, 0xAD, 0xCB, 0x45, 0x66, 0xFA, 0xDF, 0xA9, 0x61, 0x28, 0x65, 0x31, 0xD7, 0x80, 0xD5, 0x18, 0xFE, 0x25, 0x6E, 0x94, 0x05, 0x83, 0x51, 0xB5, 0x42, 0xD2, 0x9D]
keystream=[(ord("1")^i)&0xff for i in get]
for i in range(len(enc)):
enc[i]^=keystream[i]
enc[i]&=0xff
print("".join(map(chr,enc)))
#flag{a97acbcf-37dd-47f5-a52a-587254e721fa}

赛后看wp的时候 发现是rc4加chacha20 当时没考虑那么多 直接就异或回去了 算是个非预期吧

和谐(复现)

第一次做鸿蒙的逆向 比赛的时候没找到合适的工具 导致一直没什么思路
看完官方wp后 发现使用的工具是https://github.com/ohos-decompiler/abc-decompiler/releases

打开附件
sm4算法 对着源码看 可以看出 修改了密钥拓展的部分

Patr1ck-day3-wp-15

写脚本解密即可 脚本我直接参考的官方的wp了

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

typedef unsigned long ull;
typedef unsigned int uint;
typedef unsigned char uchar;

static const uchar Sbox[16][16] = {
    {0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05},
    {0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99},
    {0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62},
    {0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6},
    {0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8},
    {0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35},
    {0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87},
    {0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e},
    {0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1},
    {0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3},
    {0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f},
    {0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51},
    {0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8},
    {0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0},
    {0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84},
    {0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48}
};

ull leftShift(ull x, int n) {
    return (x << n) | (x >> (32 - n));
}

ull chr2int(uchar *chr) {
    return (chr[0] << 24) | (chr[1] << 16) | (chr[2] << 8) | chr[3];
}

void int2chr(uchar *chr, ull x) {
    chr[0] = (x >> 24) & 0xff;
    chr[1] = (x >> 16) & 0xff;
    chr[2] = (x >> 8) & 0xff;
    chr[3] = x & 0xff;
}

uint transSboxInt(uint temp)
{
 return Sbox[temp>>4][temp&0xf];
}

uint transSbox(uint temp) {
    uint output = 0;
    for (int i = 3; i > -1; i--) {
        output = output << 8;
        output = output | transSboxInt((temp >> (i * 8)) & 0xff);
    }
    return output;
}

uint keyTrans(uint temp) {
    return temp ^ leftShift(temp, 13) ^ leftShift(temp, 23);
}

uint trans(uint temp) {
    temp = transSbox(temp);
    return temp ^ leftShift(temp, 2) ^ leftShift(temp, 10) ^ leftShift(temp, 18) ^ leftShift(temp, 24);
}

void keyExtention_new(uchar K[32], uint RK[32]) {
    uint tk[36];
    for (int i = 0; i < 4; i++) {
        tk[i] = chr2int(K + 4 * i);
    }
    for (int i = 0; i < 32; i++) {
        tk[i + 4] = tk[i + 1] ^ tk[i + 2] ^ tk[i + 3];
        tk[i + 4] = transSbox(tk[i + 4]);
        tk[i + 4] = keyTrans(tk[i + 4]);
        tk[i + 4] = tk[i] ^ tk[i + 4];
        RK[i] = tk[i + 4];
    }
}

void sm4_encrypt_new(uchar *input, uchar *output, uchar *K) {
    uint RK[32];
    keyExtention_new(K, RK);
    uint X[36];
    for (int i = 0; i < 4; i++) {
        X[i] = chr2int(input + 4 * i);
    }
    for (int i = 0; i < 32; i++) {
        X[i + 4] = X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ RK[i];
        X[i + 4] = trans(X[i + 4]);
        X[i + 4] = X[i] ^ X[i + 4];
    }
    for (int i = 0; i < 4; i++) {
        output[4 * i] = (X[35 - i] >> 24) & 0xff;
        output[4 * i + 1] = (X[35 - i] >> 16) & 0xff;
        output[4 * i + 2] = (X[35 - i] >> 8) & 0xff;
        output[4 * i + 3] = X[35 - i] & 0xff;
    }
}

void sm4_decrypt_new(uchar *input, uchar *output, uchar *K) {
    uint RK[32];
    keyExtention_new(K, RK);
    uint X[36];
    for (int i = 0; i < 4; i++) {
        X[35 - i] = chr2int(input + 4 * i);
    }
    for (int i = 31; i >= 0; i--) {
        X[i] = X[i + 1] ^ X[i + 2] ^ X[i + 3] ^ RK[i];
        X[i] = trans(X[i]);
        X[i] = X[i + 4] ^ X[i];
    }
    for (int i = 0; i < 4; i++) {
        output[4 * i] = (X[i] >> 24) & 0xff;
        output[4 * i + 1] = (X[i] >> 16) & 0xff;
        output[4 * i + 2] = (X[i] >> 8) & 0xff;
        output[4 * i + 3] = X[i] & 0xff;
    }
}


int main() {
    uchar key[16] = {0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05};
    uchar output[48] = {
        24, 138, 76, 64, 151, 159, 65, 33, 3, 90, 97, 15, 62, 105, 82, 235,
        77, 240, 241, 90, 84, 179, 185, 34, 158, 119, 185, 189, 120, 106, 13, 138,
        17, 68, 255, 127, 234, 11, 218, 151, 82, 97, 25, 170, 100, 201, 253, 150,
    };
    uchar input[48] = {0};
    for (int i = 0; i < 48; i++) {
        output[i] = Sbox[output[i] / 16][output[i] % 16];
    }
    uchar output2[48] = {0};
    for (int j = 0; j < 3; j++)
    {
        sm4_decrypt_new(output + j * 16, output2 + j * 16, key);
        for (int i = 0; i < 16; i++) {
            printf("%c", output2[j * 16 + i]);
        }
    }
    printf("n");
    return 0;
}