-
-
[原创]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_7011C0与abs32(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 rdef 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-1paths = [[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]# 0001111d1e1f2f3f3e3d4d5d5e5f53637372717d7c8c8o8p8q8r8s7s6s6g6h6i6j6757565545353h3i3j2j1j1k1w2w2x3x4x5x5w6w7w8w8xbin = 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 rdef 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-1paths = [[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实战!
赞赏
他的文章
赞赏
雪币:
留言: