首页
社区
课程
招聘
[原创]KCTF2022春季赛第三题分析(4qwerty7)
发表于: 2022-5-13 20:13 6345

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

2022-5-13 20:13
6345

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

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

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

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

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

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

找份AES随便改改就行

 
 
 
[
   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
]
[
   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
]
 
 
#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}
#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):

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//