首页
论坛
课程
招聘
[原创]KCTF2022春季赛第三题分析(4qwerty7)
2022-5-13 20:13 2175

[原创]KCTF2022春季赛第三题分析(4qwerty7)

2022-5-13 20:13
2175

用 SEH 异常修改了部分内容的AES加密,要求输入被加密后的结果等于特定值。

 

首先密钥是字符串 Enj0y_1t_4_fuuuN 被修改后的 MD5 哈希后的值。

 

MD5 的修改在于其正弦表 sine_table[42] = 0xD4AF3085。

 

然后 AES 加密的逻辑中将 Sbox 的部分内容修改,修改后的 Sbox 表为

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
[
   99, 124, 119, 123, 242, 107, 111, 19748,   1,
  10343, 254, 215, 171, 118, 202, 130, 201, 125,
  2508971, 240, 173, 212, 162, 175, 156, 164,
  114, 192, 183, 253, 147385463, 247, 204,
   52, 165, 229, 241, 113, 2164921,   4, 199,
   35, 19524, 150,   5, 154,   718, 128, 226,
  23539, 178, 117,   9, 131442627, 110,
   90, 1608259, 214, 17941, 22747, 132,
   83, 209,   0, 23732, 252, 17791, 106, 203,
  19057747688, 207, 208, 239, 170, 251,
   677751, 13369, 249,   2, 1278060,
  159, 168811064, 143, 146, 15756, 245,
  188, 182, 2183316, 255, 243, 210, 20512,
   19, 23695, 1516823, 196, 167, 12661,
  1009325, 11596, 12979, 2203442,
  144, 13670, 238, 18420, 2229411, 219,
  2245058, 16373,   63692, 194, 211,
  17298, 145, 149, 228, 121, 231, 20055, 109,
  141, 21378, 169, 10886, 244, 234, 101, 122,
  174,   8, 186, 120374628, 166, 180, 198,
  232, 221, 1163175, 189, 139, 138, 11262,
  181, 10272,   3, 24614975387, 185,
  134, 19329, 158, 225, 248, 15217, 105, 217,
  142, 148, 15530, 135, 233, 2068540, 223,
  140, 161, 13713, 191, 23066, 10465, 153,
   4515, 17684, 18722
]

密钥扩展部分未使用被修改的部分。

 

行移位的代码被改成逆行移位;同时最终比较的结果中也有两字节被修改,结果为 577CF56D56967745B0BDA1C789A5ABDCF4F24BFEBEF5F55C4D30420F2B3BE6CB

 

找份AES随便改改就行

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
197
#My AES implementation
# By Daniel Miller
 
def xor(s1, s2):
    return tuple(a^b for a,b in zip(s1, s2))
 
class AES(object):
    def __init__(self):
        self.Gmul = {}
        for f in (0x02, 0x03, 0x0e, 0x0b, 0x0d, 0x09):
            self.Gmul[f] = tuple(self.gmul(f, x) for x in range(0,0x100))
 
    Rcon = ( 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a )
    Ori = tuple(list(bytes.fromhex('637C777BF26B6FC53001672BFED7AB76CA82C97DFA5947F0ADD4A2AF9CA472C0B7FD9326363FF7CC34A5E5F171D8311504C723C31896059A071280E2EB27B27509832C1A1B6E5AA0523BD6B329E32F8453D100ED20FCB15B6ACBBE394A4C58CFD0EFAAFB434D338545F9027F503C9FA851A3408F929D38F5BCB6DA2110FFF3D2CD0C13EC5F974417C4A77E3D645D197360814FDC222A908846EEB814DE5E0BDBE0323A0A4906245CC2D3AC629195E479E7C8376D8DD54EA96C56F4EA657AAE08BA78252E1CA6B4C6E8DD741F4BBD8B8A703EB5664803F60E613557B986C11D9EE1F8981169D98E949B1E87E9CE5528DF8CA1890DBFE6426841992D0FB054BB16')))
    Sbox = (
   99, 124, 119, 123, 242, 107, 111, 19748,   1,
  10343, 254, 215, 171, 118, 202, 130, 201, 125,
  2508971, 240, 173, 212, 162, 175, 156, 164,
  114, 192, 183, 253, 147385463, 247, 204,
   52, 165, 229, 241, 113, 2164921,   4, 199,
   35, 19524, 150,   5, 154,   718, 128, 226,
  23539, 178, 117,   9, 131442627, 110,
   90, 1608259, 214, 17941, 22747, 132,
   83, 209,   0, 23732, 252, 17791, 106, 203,
  19057747688, 207, 208, 239, 170, 251,
   677751, 13369, 249,   2, 1278060,
  159, 168811064, 143, 146, 15756, 245,
  188, 182, 2183316, 255, 243, 210, 20512,
   19, 23695, 1516823, 196, 167, 12661,
  1009325, 11596, 12979, 2203442,
  144, 13670, 238, 18420, 2229411, 219,
  2245058, 16373,   63692, 194, 211,
  17298, 145, 149, 228, 121, 231, 20055, 109,
  141, 21378, 169, 10886, 244, 234, 101, 122,
  174,   8, 186, 120374628, 166, 180, 198,
  232, 221, 1163175, 189, 139, 138, 11262,
  181, 10272,   3, 24614975387, 185,
  134, 19329, 158, 225, 248, 15217, 105, 217,
  142, 148, 15530, 135, 233, 2068540, 223,
  140, 161, 13713, 191, 23066, 10465, 153,
   4515, 17684, 18722
            )
    Sbox_inv = None
 
    @staticmethod
    def rot_word(word):
        return word[1:] + word[:1]
 
    @staticmethod
    def sub_word(word):
        return (AES.Sbox[b] for b in word)
 
    def key_schedule(self):
        expanded = []
        expanded.extend(list(self.key))
        for i in range(self.nk, self.nb * (self.nr + 1)):
            t = expanded[(i-1)*4:i*4]
            if i % self.nk == 0:
                t = xor( AES.sub_word( AES.rot_word(t) ), (AES.Rcon[i // self.nk],0,0,0) )
            elif self.nk > 6 and i % self.nk == 4:
                t = AES.sub_word(t)
            expanded.extend( xor(t, expanded[(i-self.nk)*4:(i-self.nk+1)*4]))
        return expanded
 
    def add_round_key(self, rkey):
        for i, b in enumerate(rkey):
            self.state[i] ^= b
 
    def sub_bytes(self):
        for i, b in enumerate(self.state):
            self.state[i] = AES.Sbox[b]
 
    def inv_sub_bytes(self):
        for i, b in enumerate(self.state):
            self.state[i] = AES.Sbox_inv[b]
 
    def shift_rows(self):
        rows = []
        for r in range(4):
            rows.append( self.state[r::4] )
            rows[r] = rows[r][r:] + rows[r][:r]
        self.state = [ r[c] for c in range(4) for r in rows ]
 
    def inv_shift_rows(self):
        rows = []
        for r in range(4):
            rows.append( self.state[r::4] )
            rows[r] = rows[r][4-r:] + rows[r][:4-r]
        self.state = [ r[c] for c in range(4) for r in rows ]
 
    @staticmethod
    def gmul(a, b):
        p = 0
        for c in range(8):
            if b & 1:
                p ^= a
            a <<= 1
            if a & 0x100:
                a ^= 0x11b
            b >>= 1
        return p
 
    def mix_columns(self):
        ss = []
        for c in range(4):
            col = self.state[c*4:(c+1)*4]
            ss.extend((
                        self.Gmul[0x02][col[0]] ^ self.Gmul[0x03][col[1]] ^                col[2]  ^                col[3] ,
                                       col[0]  ^ self.Gmul[0x02][col[1]] ^ self.Gmul[0x03][col[2]] ^                col[3] ,
                                       col[0]  ^                col[1]  ^ self.Gmul[0x02][col[2]] ^ self.Gmul[0x03][col[3]],
                        self.Gmul[0x03][col[0]] ^                col[1]  ^                col[2]  ^ self.Gmul[0x02][col[3]],
                    ))
        self.state = ss
 
    def inv_mix_columns(self):
        ss = []
        for c in range(4):
            col = self.state[c*4:(c+1)*4]
            ss.extend((
                        self.Gmul[0x0e][col[0]] ^ self.Gmul[0x0b][col[1]] ^ self.Gmul[0x0d][col[2]] ^ self.Gmul[0x09][col[3]],
                        self.Gmul[0x09][col[0]] ^ self.Gmul[0x0e][col[1]] ^ self.Gmul[0x0b][col[2]] ^ self.Gmul[0x0d][col[3]],
                        self.Gmul[0x0d][col[0]] ^ self.Gmul[0x09][col[1]] ^ self.Gmul[0x0e][col[2]] ^ self.Gmul[0x0b][col[3]],
                        self.Gmul[0x0b][col[0]] ^ self.Gmul[0x0d][col[1]] ^ self.Gmul[0x09][col[2]] ^ self.Gmul[0x0e][col[3]],
                    ))
        self.state = ss
 
    def state_to_mat(self):
        def tt(v):
            if v >= 128:
                v -= 256
            return v
        k = 0
        a = [[0]*4 for _ in range(4)]
        for i in range(4):
            for j in range(4):
                a[j][i] = tt(self.state[k])
                k += 1
        return a
 
    def cipher(self, block):
        n = self.nb * 4
        self.state = list(block)
        keys = self.key_schedule()
        self.add_round_key(keys[0:n])
        for r in range(1, self.nr):
            self.sub_bytes()
            self.inv_shift_rows() # changed
            self.mix_columns()
            k = keys[r*n:(r+1)*n]
            self.add_round_key(k)
        self.sub_bytes()
        self.inv_shift_rows() # changed
        self.add_round_key(keys[self.nr*n:])
        return bytes(self.state)
 
    def inv_cipher(self, block):
        n = self.nb * 4
        self.state = list(block)
        keys = self.key_schedule()
        k = keys[self.nr*n:(self.nr+1)*n]
        self.add_round_key(k)
        for r in range(self.nr-1, 0, -1):
            self.shift_rows() # changed
            self.inv_sub_bytes()
            k = keys[r*n:(r+1)*n]
            self.add_round_key(k)
            self.inv_mix_columns()
 
        self.shift_rows() # changed
        self.inv_sub_bytes()
        self.add_round_key(keys[0:n])
        return bytes(self.state)
 
def inv_box_gen(box):
    inv = [0] * 256
    for i, v in enumerate(box):
        inv[v] = i
    return tuple(inv)
 
AES.Sbox_inv = inv_box_gen(AES.Sbox)
 
class AES_128(AES):
    def __init__(self):
        super().__init__()
        self.nb = 4
        self.nr = 10
        self.nk = 4
 
ori = b'1111111111111111'
key = bytes.fromhex('2F65B1FF31ED86D09A285C0F4048059D')
res = bytes.fromhex('1EE3517FDB630179A4109948246918BC')
cipher = AES_128()
cipher.key = key
print(cipher.cipher(ori) == res)
ans = bytes.fromhex('577CF56D56967745B0BDA1C789A5ABDCF4F24BFEBEF5F55C4D30420F2B3BE6CB')
print(cipher.inv_cipher(ans[:16]) + cipher.inv_cipher(ans[16:]))
# flag{db5c6a8dfec4d0ec5569899640}

【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回