首页
社区
课程
招聘
[原创]KCTF 2025 第2题 初窥门径wp
发表于: 2025-8-26 08:40 4922

[原创]KCTF 2025 第2题 初窥门径wp

2025-8-26 08:40
4922

用ida打开查看main函数, 发现验证成功需要sub_701280返回1;
sub_701280函数中先将输入根据字符串"0123456789abcdefghijklmnopqrstuvwxyz"变换为序号, 其后代码为:

要反回1需要最后dword_703020[80 * input_divide_12 + 10 * input_divide_12 + 10 * last_input_mod_12 + input_mod_12] == 8114而且之前通过sub_7011C0abs32(input_mod_12 - v19) + abs32(last_input_mod_12 - v20) + abs32(input_divide_12 - v21) != 1的检查;
分析sub_7011C0发现该函数在将输入的数字分解为两个质数的乘积, 然后的abs32...判断保证每轮input_mod_12, last_input_mod_12, input_divide_12中只能有一个增减1;
于是在dword_703020中遍历搜索满足条件的路径:

...
    if ( (input_i & 1) != 0 )
    {
        v12 = v18 + 1;
        input_mod_12 = input_converted_idx % 12;
        v18 = v12;
        if ( v12 == 1
        && dword_703020[80 * input_divide_12 + 10 * input_divide_12 + 10 * last_input_mod_12 + input_mod_12] != 0x2C0E )
        {
        return 0;
        }
        v11 = v16;
        if ( v16 == v17 - 1
        && dword_703020[80 * input_divide_12 + 10 * input_divide_12 + 10 * last_input_mod_12 + input_mod_12] != 8114 )
        {
        return 0;
        }
        if ( v12 > 1 )
        {
        if ( v16 < v17
            && (!(unsigned __int8)sub_7011C0(
                                    dword_703020[80 * input_divide_12
                                                + 10 * input_divide_12
                                                + 10 * last_input_mod_12
                                                + input_mod_12],
                                    (int)&v22,
                                    (int)&vars0)
            || v22 < 2
            || vars0 < 2
            || v22 == vars0)
            || abs32(input_mod_12 - v19) + abs32(last_input_mod_12 - v20) + abs32(input_divide_12 - v21) != 1 )
        {
            return 0;
        }
        v11 = v16;
        }
        v19 = input_mod_12;
        v20 = last_input_mod_12;
        v21 = input_divide_12;
        if ( v11 == v17 - 1
        && dword_703020[80 * input_divide_12 + 10 * input_divide_12 + 10 * last_input_mod_12 + input_mod_12] == 8114 )
        {
        return 1;
        }
        v5 = v17;
    }
...
    if ( (input_i & 1) != 0 )
    {
        v12 = v18 + 1;
        input_mod_12 = input_converted_idx % 12;
        v18 = v12;
        if ( v12 == 1
        && dword_703020[80 * input_divide_12 + 10 * input_divide_12 + 10 * last_input_mod_12 + input_mod_12] != 0x2C0E )
        {
        return 0;
        }
        v11 = v16;
        if ( v16 == v17 - 1
        && dword_703020[80 * input_divide_12 + 10 * input_divide_12 + 10 * last_input_mod_12 + input_mod_12] != 8114 )
        {
        return 0;
        }
        if ( v12 > 1 )
        {
        if ( v16 < v17
            && (!(unsigned __int8)sub_7011C0(
                                    dword_703020[80 * input_divide_12
                                                + 10 * input_divide_12
                                                + 10 * last_input_mod_12
                                                + input_mod_12],
                                    (int)&v22,
                                    (int)&vars0)
            || v22 < 2
            || vars0 < 2
            || v22 == vars0)
            || abs32(input_mod_12 - v19) + abs32(last_input_mod_12 - v20) + abs32(input_divide_12 - v21) != 1 )
        {
            return 0;
        }
        v11 = v16;
        }
        v19 = input_mod_12;
        v20 = last_input_mod_12;
        v21 = input_divide_12;
        if ( v11 == v17 - 1
        && dword_703020[80 * input_divide_12 + 10 * input_divide_12 + 10 * last_input_mod_12 + input_mod_12] == 8114 )
        {
        return 1;
        }
        v5 = v17;
    }
bin = open('yegu_cm.exe', 'rb').read()
 
p = bin.find(b'\x0e\x2c\x00\x00\x12\x13\x00\x00')
dword_703020 = memoryview(bin[p:p+0x3458-0x3020]).cast('I')
 
def factors(x):
    r = []
    for i in range(2, x):
        if x % i == 0:
            r.append(i)
    return r
 
def next_step(x, y, z):
    yield x+1, y, z
    yield x, y+1, z
    yield x, y, z+1
    if x >= 1:
        yield x-1, y, z
    if y >= 1:
        yield x, y-1, z
    if z >= 1:
        yield x, y, z-1
 
paths = [[0, 0, 0]]
bstr = '0123456789abcdefghijklmnopqrstuvwxyz'
def search_path(x, y, z):
    idx = x*90 + 10*y + z
    if dword_703020[idx] != 0x1fb2:
        for nx, ny, nz in next_step(x, y, z):
            if [nx, ny, nz] in paths:
                continue
            idx = nx*90 + 10*ny + nz
            if idx >= len(dword_703020):
                continue
            if len(factors(dword_703020[idx])) == 2:
                paths.append([nx, ny, nz])
                search_path(nx, ny, nz)
        paths.pop()
    else:
        print('paths:')
        r = ''
        for p in paths:
            print(p)
            r += bstr[p[1]]
            r += bstr[p[0]*12 + p[2]]
        print(r)
 
search_path(0, 0, 0)
# paths:
# [0, 0, 0]
# [0, 0, 1]
# [0, 1, 1]
# [1, 1, 1]
# [1, 1, 2]
# [1, 1, 3]
# [1, 2, 3]
# [1, 3, 3]
# [1, 3, 2]
# [1, 3, 1]
# [1, 4, 1]
# [1, 5, 1]
# [1, 5, 2]
# [1, 5, 3]
# [0, 5, 3]
# [0, 6, 3]
# [0, 7, 3]
# [0, 7, 2]
# [0, 7, 1]
# [1, 7, 1]
# [1, 7, 0]
# [1, 8, 0]
# [2, 8, 0]
# [2, 8, 1]
# [2, 8, 2]
# [2, 8, 3]
# [2, 8, 4]
# [2, 7, 4]
# [2, 6, 4]
# [1, 6, 4]
# [1, 6, 5]
# [1, 6, 6]
# [1, 6, 7]
# [0, 6, 7]
# [0, 5, 7]
# [0, 5, 6]
# [0, 5, 5]
# [0, 4, 5]
# [0, 3, 5]
# [1, 3, 5]
# [1, 3, 6]
# [1, 3, 7]
# [1, 2, 7]
# [1, 1, 7]
# [1, 1, 8]
# [2, 1, 8]
# [2, 2, 8]
# [2, 2, 9]
# [2, 3, 9]
# [2, 4, 9]
# [2, 5, 9]
# [2, 5, 8]
# [2, 6, 8]
# [2, 7, 8]
# [2, 8, 8]
# [2, 8, 9]
# 0001111d1e1f2f3f3e3d4d5d5e5f53637372717d7c8c8o8p8q8r8s7s6s6g6h6i6j6757565545353h3i3j2j1j1k1w2w2x3x4x5x5w6w7w8w8x
bin = open('yegu_cm.exe', 'rb').read()
 
p = bin.find(b'\x0e\x2c\x00\x00\x12\x13\x00\x00')
dword_703020 = memoryview(bin[p:p+0x3458-0x3020]).cast('I')
 
def factors(x):
    r = []
    for i in range(2, x):
        if x % i == 0:
            r.append(i)
    return r
 
def next_step(x, y, z):
    yield x+1, y, z
    yield x, y+1, z
    yield x, y, z+1
    if x >= 1:
        yield x-1, y, z
    if y >= 1:
        yield x, y-1, z
    if z >= 1:
        yield x, y, z-1
 
paths = [[0, 0, 0]]
bstr = '0123456789abcdefghijklmnopqrstuvwxyz'
def search_path(x, y, z):
    idx = x*90 + 10*y + z
    if dword_703020[idx] != 0x1fb2:
        for nx, ny, nz in next_step(x, y, z):

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

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