首页
社区
课程
招聘
[原创] KCTF 2023 第八题 wp - 98k
发表于: 2023-9-17 15:44 8842

[原创] KCTF 2023 第八题 wp - 98k

2023-9-17 15:44
8842

代码量非常少,不过编译器优化得到逻辑很乱。整理下逻辑:

所以问题大致是这样的,给定了 10 个初始比特值,还给了 10 组(实际上是 11 组)比特值,每次从这 10 组中有限制的选择一组出来,异或到初始比特值中,要求最后使 10 个比特值都变成 0 。

将初始比特值和可选择异或的比特值计算出来得到:

也就是每次可以改变 1 比特。限制条件为每隔一轮需要将最低比特改掉;除最低比特外,能修改某个比特位的条件就是它后续的比特位最高位为 1 ,后面的全是 0 (上面代码中 check 的检查)

根据这些限制条件就可以手动构造,再转成输入:

正常来说输入转换得到的数字应该不能为 9 ,但是程序中并没有对 9 做错误的返回,所以可以在输入的任意 4 个连续的偶数位置插 9 (奇数位补0),得到的结果不变,就能构造出多解。上面代码中给出了在末尾补 9 时得到的几组多解。

int check(char* input, int length) {
    char _flag[10][4];
    char key[5][4];
 
    for (int i = 0; i < length; i++) {
        int j = trans(input, i); // 0~9
        if (i & 1) assert(j == 0);
        else assert(j != 0);
        if (!check(key, j)) j = 9;
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 4; b++) {
                key[a][b] ^= _flag[j][b];
            }
        }
        if (j == 9) {
            _flag[9][1] = ~_flag[9][1] & 0x7f;
        }
    }
    int a = 0;
    int b = 0;
    for (int i = 0; i < 5; i++) {
        a ^= key[i][0] ^ key[i][2];
        b ^= key[i][1] ^ key[i][3];
    }
    return (a & 0x1f) == 0 && (b & 0x1f) == 0;
}
int check(char* input, int length) {
    char _flag[10][4];
    char key[5][4];
 
    for (int i = 0; i < length; i++) {
        int j = trans(input, i); // 0~9
        if (i & 1) assert(j == 0);
        else assert(j != 0);
        if (!check(key, j)) j = 9;
        for (int a = 0; a < 5; a++) {
            for (int b = 0; b < 4; b++) {
                key[a][b] ^= _flag[j][b];
            }
        }
        if (j == 9) {
            _flag[9][1] = ~_flag[9][1] & 0x7f;
        }
    }
    int a = 0;
    int b = 0;
    for (int i = 0; i < 5; i++) {
        a ^= key[i][0] ^ key[i][2];
        b ^= key[i][1] ^ key[i][3];
    }
    return (a & 0x1f) == 0 && (b & 0x1f) == 0;
}
01000 10101
 
00000 00001
00000 00010
00000 00100
00000 01000
00000 10000
00001 00000
00010 00000
00100 00000
01000 00000
10000 00000
01000 10101
 
00000 00001
00000 00010
00000 00100
00000 01000
00000 10000
00001 00000
00010 00000
00100 00000
01000 00000
10000 00000
#!/usr/bin/env python3
 
def check(input):
    _flag = list(b'flag{BzcZDnfNIqmQCtkTGlwLyDYeiHIjxSXwkRKzpFPv}\x00\x00')
    key = list(b'Can you crack me?^olo^\x00\x00')
    v7 = _flag[42]
    for i in range(len(input)):
        c = input[i]
        v9 = (c + (0xFFFEC610 >> (i % 31))) % 10
        assert (i & 1) == int(v9 < 1)
        v26 = 0
        for j in range(4):
            v26 |= (key[16 + j] ^ key[12 + j] ^ key[8 + j] ^ key[4 + j] ^ key[j]) << (8 * j)
        # print(hex(v26))
        # print(((v26 >> 16) ^ v26) & 0x1f, ((v26 >> 24) ^ (v26 >> 8)) & 0x1f)
        while v9 >= 1:
            if v9 >= 6:
                if (v26 ^ (v26 >> 16)) & 0x1f != 0:
                    v9 = 9
                    break
                else:
                    v12 = (v26 >> 24) & 0xff
                    v13 = 13 - v9
                    v14 = (v26 >> 8) & 0xff
            else:
                v12 = (v26 >> 16) & 0xff
                v13 = 8 - v9
                v14 = v26 & 0xff
            # print(bin(v12)[2:].rjust(8, '0'), bin(v14)[2:].rjust(8, '0'), v13)
            if (((v14 << v13) + 0x80) & 0xff) != ((v12 << v13) & 0xff):
                v9 = 9
            break
        if v9: print(v9, end=' ')
        for i in range(5):
            for j in range(4):
                key[4 * i + j] ^= _flag[4 * v9 + 5 + j]
        if v9 > 8:
            v7 = ~v7 & 0x7f
            _flag[42] = v7 # 42 - 5 = 37, (9, 1)
    print()
    v26 = 0
    for j in range(4):
        v26 |= (key[16 + j] ^ key[12 + j] ^ key[8 + j] ^ key[4 + j] ^ key[j]) << (8 * j)
    print(hex(v26), bin(((v26 >> 16) ^ v26) & 0x1f)[2: ].rjust(5, '0'), bin(((v26 >> 24) ^ (v26 >> 8)) & 0x1f)[2: ].rjust(5, '0'))
    if ((v26 >> 16) ^ v26) & 0x1f != 0 or ((v26 >> 24) ^ (v26 >> 8)) & 0x1f != 0:
        return False
    else:
        return True
 
'''
flag = [0x3f] * 62
 
for i in range(len(flag)):
    if i & 1:
        flag[i] = (10 - (0xFFFEC610 >> (i % 31))) % 10
    else:
        flag[i] = (9 - (0xFFFEC610 >> (i % 31))) % 10
    while flag[i] < 0x30:
        flag[i] += 10
 
print(bytes(flag))
# 38968638916054237581658165816584705954700796332849074907490749
 
print(check(bytes(flag)))
'''
 
 
key = b'Can you crack me?^ol'
 
s = [0] * 2
for i in range(2):
    for j in range(0, len(key), 4):
        s[i] ^= (key[j + i] ^ key[j + i + 2]) & 0x1f
 
_flag = b'BzcZDnfNIqmQCtkTGlwLyDYeiHIjxSXwkRKzpFPvp9Pv'
# _flag = b'BzcZDnfNIqmQCtkTGlwLyDYeiHIjxSXwkRKzp9Pv'
t = []
for i in range(11):
    t.append([])
    for j in range(2):
        t[-1].append((_flag[4 * i + j] ^ _flag[4 * i + j + 2]) & 0x1f)
 
print(' '.join(bin(i)[2:].rjust(5, '0') for i in s[::-1]))
print()
for _t in t:
    print(' '.join(bin(i)[2:].rjust(5, '0') for i in _t[::-1]))
 
flag = []
values = [
       # 01000 10101
    1, # 01000 10110
    2, # 01000 10011
    1, # 01000 10000
    5, # 01001 10001
    1, # 01001 10010
    2, # 01001 10111
    1, # 01001 10100
    3, # 01001 11101
    1, # 01001 11110
    2, # 01001 11011
    1, # 01001 11000
    4, # 01001 01001
    1, # 01001 01010
    2, # 01001 01111
    1, # 01001 01100
    3, # 01001 00101
    1, # 01001 00110
    2, # 01001 00011
    1, # 01001 00000
    6, # 01011 00001
    1, # 01011 00010
    2, # 01011 00111
    1, # 01011 00100
    3, # 01011 01101
    1, # 01011 01110
    2, # 01011 01011
    1, # 01011 01000
    4, # 01011 11001
    1, # 01011 11010
    2, # 01011 11111
    1, # 01011 11100
    3, # 01011 10101
    1, # 01011 10110
    2, # 01011 10011
    1, # 01011 10000
    5, # 01010 10001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7, # 01110 00001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, # 01111 10001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6, # 01101 00001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, # 01100 10001
    1, # 01100 10010
    2, # 01100 10111
    1, # 01100 10100
    3, # 01100 11101
    1, # 01100 11110
    2, # 01100 11011
    1, # 01100 11000
    4, # 01100 01001
    1, 2, 1, 3, 1, 2, 1, # 01100 00000
    8# 00100 00001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, # 00101 10001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6, # 00111 00001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, # 00110 10001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 7, # 00010 00001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, # 00011 10001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6, # 00001 00001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, # 00000 10001
    1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1,
]
 
values += [9, 9, 9, 9] * 0
 
for i in range(2 * len(values)):
    if i & 1:
        flag.append((0 - (0xFFFEC610 >> (i % 31))) % 10)
    else:
        flag.append((values[i // 2] - (0xFFFEC610 >> (i % 31))) % 10)
    while flag[-1] < 0x30:
        flag[-1] += 10
 
print(bytes(flag))
print(check(bytes(flag)))
 
 
# 582606981190746395118531851185249089744027265368693769576937697816165851808443150195011501950410798490871663488927792799277958360668112074539521851185318514909974002766535869476937695769681626582180144305010501950115040079949037162348792789277927995826067811907483951185218511853490897410272653986937694769376988161658318084433501950105019504207984904716634829277927892779584606681100745395418511852185149009740027365358697769376947696816365821809443050125019501050400790490371673487927
# 58260698119074639511853185118524908974402726536869376957693769781616585180844315019501150195041079849087166348892779279927795836066811207453952185118531851490997400276653586947693769576968162658218014430501050195011504007994903716234879278927792799582606781190748395118521851185349089741027265398693769476937698816165831808443350195010501950420798490471663482927792789277958460668110074539541851185218514900974002736535869776937694769681636582180944305012501950105040079049037167348792749074907
# 5826069811907463951185318511852490897440272653686937695769376978161658518084431501950115019504107984908716634889277927992779583606681120745395218511853185149099740027665358694769376957696816265821801443050105019501150400799490371623487927892779279958260678119074839511852185118534908974102726539869376947693769881616583180844335019501050195042079849047166348292779278927795846066811007453954185118521851490097400273653586977693769476968163658218094430501250195010504007904903716734879274907490749389686
# 582606981190746395118531851185249089744027265368693769576937697816165851808443150195011501950410798490871663488927792799277958360668112074539521851185318514909974002766535869476937695769681626582180144305010501950115040079949037162348792789277927995826067811907483951185218511853490897410272653986937694769376988161658318084433501950105019504207984904716634829277927892779584606681100745395418511852185149009740027365358697769376947696816365821809443050125019501050400790490371673487927490749074938968638916054
# 58260698119074639511853185118524908974402726536869376957693769781616585180844315019501150195041079849087166348892779279927795836066811207453952185118531851490997400276653586947693769576968162658218014430501050195011504007994903716234879278927792799582606781190748395118521851185349089741027265398693769476937698816165831808443350195010501950420798490471663482927792789277958460668110074539541851185218514900974002736535869776937694769681636582180944305012501950105040079049037167348792749074907493896863891605423758165
# 5826069811907463951185318511852490897440272653686937695769376978161658518084431501950115019504107984908716634889277927992779583606681120745395218511853185149099740027665358694769376957696816265821801443050105019501150400799490371623487927892779279958260678119074839511852185118534908974102726539869376947693769881616583180844335019501050195042079849047166348292779278927795846066811007453954185118521851490097400273653586977693769476968163658218094430501250195010504007904903716734879274907490749389686389160542375816581658165
#!/usr/bin/env python3
 
def check(input):
    _flag = list(b'flag{BzcZDnfNIqmQCtkTGlwLyDYeiHIjxSXwkRKzpFPv}\x00\x00')
    key = list(b'Can you crack me?^olo^\x00\x00')
    v7 = _flag[42]
    for i in range(len(input)):
        c = input[i]
        v9 = (c + (0xFFFEC610 >> (i % 31))) % 10
        assert (i & 1) == int(v9 < 1)
        v26 = 0
        for j in range(4):
            v26 |= (key[16 + j] ^ key[12 + j] ^ key[8 + j] ^ key[4 + j] ^ key[j]) << (8 * j)
        # print(hex(v26))
        # print(((v26 >> 16) ^ v26) & 0x1f, ((v26 >> 24) ^ (v26 >> 8)) & 0x1f)
        while v9 >= 1:
            if v9 >= 6:
                if (v26 ^ (v26 >> 16)) & 0x1f != 0:
                    v9 = 9
                    break
                else:
                    v12 = (v26 >> 24) & 0xff
                    v13 = 13 - v9
                    v14 = (v26 >> 8) & 0xff
            else:
                v12 = (v26 >> 16) & 0xff
                v13 = 8 - v9
                v14 = v26 & 0xff
            # print(bin(v12)[2:].rjust(8, '0'), bin(v14)[2:].rjust(8, '0'), v13)
            if (((v14 << v13) + 0x80) & 0xff) != ((v12 << v13) & 0xff):
                v9 = 9
            break
        if v9: print(v9, end=' ')
        for i in range(5):
            for j in range(4):
                key[4 * i + j] ^= _flag[4 * v9 + 5 + j]
        if v9 > 8:
            v7 = ~v7 & 0x7f
            _flag[42] = v7 # 42 - 5 = 37, (9, 1)
    print()
    v26 = 0
    for j in range(4):
        v26 |= (key[16 + j] ^ key[12 + j] ^ key[8 + j] ^ key[4 + j] ^ key[j]) << (8 * j)
    print(hex(v26), bin(((v26 >> 16) ^ v26) & 0x1f)[2: ].rjust(5, '0'), bin(((v26 >> 24) ^ (v26 >> 8)) & 0x1f)[2: ].rjust(5, '0'))
    if ((v26 >> 16) ^ v26) & 0x1f != 0 or ((v26 >> 24) ^ (v26 >> 8)) & 0x1f != 0:
        return False
    else:
        return True
 
'''
flag = [0x3f] * 62
 
for i in range(len(flag)):
    if i & 1:
        flag[i] = (10 - (0xFFFEC610 >> (i % 31))) % 10
    else:
        flag[i] = (9 - (0xFFFEC610 >> (i % 31))) % 10
    while flag[i] < 0x30:
        flag[i] += 10
 
print(bytes(flag))
# 38968638916054237581658165816584705954700796332849074907490749
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

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