-
-
[原创]KCTF2025 day7 wp
-
发表于: 2025-8-27 22:52 4587
-
题目为了混淆用string_to_code(buf)替换了很多立即数, 实际上string_to_code就是一个map, 用以下patcher可以美化一下代码:
程序第一步是将输入的前10字节从十六进制字符转成数字, 然后通过这些hexnum初始化了两个矩阵:
然后判断了一些条件后检验输入的11~14字节是否满足某些条件, 一眼丁真出asas:
写个z3就能解出符合条件的14字节输入了:
坏消息是总共有400多个可行解, 这时候观察一血会发现他在一小时二十分左右提交了正确序列号, 如果他的python, z3版本和我相同并且是从头试到尾那么他应该是20分左右解出题目, 花了1个小时交序列号, 在第30~39个内大概率有正确序列号, 找到正确序列号在第31个:
下次出题的自己能不能验证一下有没有多解
from idc import GetDisasm, patch_bytefrom ida_ua import insn_t, decode_insnfrom keystone import *ks = Ks(KS_ARCH_X86, KS_MODE_32)def patch_bytes(address, new_bytes): """ Patch the bytes at the given address with the new bytes. """ for i, byte in enumerate(new_bytes): patch_byte(address + i, byte)start = 0x0804888Fend = 0x08049461mapping = { "act": 0, "abort": 1, "con": 0, "cancel": 1, "enable": 2, "reset": 4, "start": 2, "stop": 3, "run": 2, "reboot": 4, }_ = insn_t()while start <= end: disasm = GetDisasm(start) length = decode_insn(_, start) if disasm == 'call string_to_code': key = GetDisasm(start - 7).split()[-1].strip().strip('"') # print(f"Found {key} at {hex(start - 7)}") new_code = f"mov eax, {mapping[key]}" asm_code = bytes(ks.asm(new_code)[0]).ljust(12, b'\x90') patch_bytes(start - 7, asm_code) print(f"Patched {hex(start)} with {asm_code}") start += lengthfrom idc import GetDisasm, patch_bytefrom ida_ua import insn_t, decode_insnfrom keystone import *ks = Ks(KS_ARCH_X86, KS_MODE_32)def patch_bytes(address, new_bytes): """ Patch the bytes at the given address with the new bytes. """ for i, byte in enumerate(new_bytes): patch_byte(address + i, byte)start = 0x0804888Fend = 0x08049461mapping = { "act": 0, "abort": 1, "con": 0, "cancel": 1, "enable": 2, "reset": 4, "start": 2, "stop": 3, "run": 2, "reboot": 4, }_ = insn_t()while start <= end: disasm = GetDisasm(start) length = decode_insn(_, start) if disasm == 'call string_to_code': key = GetDisasm(start - 7).split()[-1].strip().strip('"') # print(f"Found {key} at {hex(start - 7)}") new_code = f"mov eax, {mapping[key]}" asm_code = bytes(ks.asm(new_code)[0]).ljust(12, b'\x90') patch_bytes(start - 7, asm_code) print(f"Patched {hex(start)} with {asm_code}") start += lengthidx1 = 0;idx2 = 0;idx3 = 0;idx4 = 0;idx5 = 0;idx6 = 0;cns2 = 0;for ( i = 0; i <= 4; ++i ){ for ( j = 0; j <= 4; ++j ) { if ( i || j != 3 ) { if ( i != 1 || j ) { if ( i == 1 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; m2[2][idx4++] = m1[i][j]; } else if ( i == 2 && j == 1 ) { m1[i][1] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; m2[1][idx3++] = m1[i][j]; } else if ( i == 2 && j == 3 ) { m1[i][3] = hexnum[idx1++]; m2[2][idx4++] = m1[i][j]; m2[3][idx5++] = m1[i][j]; } else if ( i != 3 || j ) { if ( i == 3 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[1][idx3++] = m1[i][j]; m2[4][idx6++] = m1[i][j]; } else if ( i == 3 && j == 3 ) { m1[i][3] = hexnum[idx1++]; m2[3][idx5++] = m1[i][j]; m2[4][idx6++] = m1[i][j]; } else if ( i == 3 && j == 4 ) { m1[i][4] = hexnum[idx1++]; m2[2][idx4++] = m1[i][j]; } else if ( i == 4 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[3][idx5++] = m1[i][j]; } else { m1[i][j] = i + j; } } else { m1[i][0] = hexnum[idx1++]; m2[4][idx6++] = m1[i][j]; } } else { m1[i][0] = hexnum[idx1++]; m2[1][idx3++] = m1[i][j]; } } else { m1[i][3] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; } if ( i == 4 ) cns2 += m1[4][j]; } if ( stat("/etc/rc.d", (struct stat *)buf) ) cns2 += m2[i][j];}idx1 = 0;idx2 = 0;idx3 = 0;idx4 = 0;idx5 = 0;idx6 = 0;cns2 = 0;for ( i = 0; i <= 4; ++i ){ for ( j = 0; j <= 4; ++j ) { if ( i || j != 3 ) { if ( i != 1 || j ) { if ( i == 1 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; m2[2][idx4++] = m1[i][j]; } else if ( i == 2 && j == 1 ) { m1[i][1] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; m2[1][idx3++] = m1[i][j]; } else if ( i == 2 && j == 3 ) { m1[i][3] = hexnum[idx1++]; m2[2][idx4++] = m1[i][j]; m2[3][idx5++] = m1[i][j]; } else if ( i != 3 || j ) { if ( i == 3 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[1][idx3++] = m1[i][j]; m2[4][idx6++] = m1[i][j]; } else if ( i == 3 && j == 3 ) { m1[i][3] = hexnum[idx1++]; m2[3][idx5++] = m1[i][j]; m2[4][idx6++] = m1[i][j]; } else if ( i == 3 && j == 4 ) { m1[i][4] = hexnum[idx1++]; m2[2][idx4++] = m1[i][j]; } else if ( i == 4 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[3][idx5++] = m1[i][j]; } else { m1[i][j] = i + j; } } else { m1[i][0] = hexnum[idx1++]; m2[4][idx6++] = m1[i][j]; } } else { m1[i][0] = hexnum[idx1++]; m2[1][idx3++] = m1[i][j]; } } else { m1[i][3] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; } if ( i == 4 ) cns2 += m1[4][j]; } if ( stat("/etc/rc.d", (struct stat *)buf) ) cns2 += m2[i][j];}cns1 = 1;for ( i = 0; i <= 4; ++i ){ n19 = 0; for ( j = 0; j <= 2; ++j ) { n19 += m2[i][j]; n19 -= 5; } if ( n19 != 19 ) cns1 = 0;}memset(s, 0, sizeof(s));v22 = open("/proc/self/as", (int)"r");if ( v22 == -1 ) ++cns2;if ( devctl(v22, 0x41100801, s, 272, 0) ) ++cns2;if ( cns2 != m1[0][0] + m1[0][3] * m1[0][2] * m1[0][1] * m1[0][4] + (s[8] & 0x80) - 34 ) cns1 = 0;sm = 123;if ( input[10] == 97 ) // asas sm += 45;if ( input[10] == 115 ) sm -= 45;if ( input[11] == 97 ) sm += 67;if ( input[11] == 115 ) sm -= 67;if ( input[12] == 97 ) sm += 8;if ( input[12] == 115 ) sm -= 8;if ( input[13] == 97 ) sm += 9;if ( input[13] == 115 ) sm -= 9;if ( sm != 100 ) cns1 = 0;if ( cns1 == 1 && strlen(input) <= 0xE ) puts("ok");else puts("no");return 0;cns1 = 1;for ( i = 0; i <= 4; ++i ){ n19 = 0; for ( j = 0; j <= 2; ++j ) { n19 += m2[i][j]; n19 -= 5; } if ( n19 != 19 ) cns1 = 0;}memset(s, 0, sizeof(s));v22 = open("/proc/self/as", (int)"r");if ( v22 == -1 ) ++cns2;if ( devctl(v22, 0x41100801, s, 272, 0) ) ++cns2;if ( cns2 != m1[0][0] + m1[0][3] * m1[0][2] * m1[0][1] * m1[0][4] + (s[8] & 0x80) - 34 ) cns1 = 0;sm = 123;if ( input[10] == 97 ) // asas sm += 45;if ( input[10] == 115 ) sm -= 45;if ( input[11] == 97 ) sm += 67;if ( input[11] == 115 ) sm -= 67;if ( input[12] == 97 ) sm += 8;if ( input[12] == 115 ) sm -= 8;if ( input[13] == 97 ) sm += 9;if ( input[13] == 115 ) sm -= 9;if ( sm != 100 ) cns1 = 0;if ( cns1 == 1 && strlen(input) <= 0xE ) puts("ok");else puts("no");return 0;from z3 import *ans = [BitVec('ans_%d' % i, 8) for i in range(10)]s = Solver()for i in range(10): s.add(And(ans[i] >= 0, ans[i] <= 0xf))idx1 = 0idx2 = 0idx3 = 0idx4 = 0idx5 = 0idx6 = 0cns2 = 0m1 = [[0] * 5 for _ in range(5)]m2 = [[0] * 3 for _ in range(5)]"""emulate: for ( i = 0; i <= 4; ++i ) { for ( j = 0; j <= 4; ++j ) { if ( i || j != 3 ) { if ( i != 1 || j ) { if ( i == 1 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; m2[2][idx4++] = m1[i][j]; } else if ( i == 2 && j == 1 ) { m1[i][1] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; m2[1][idx3++] = m1[i][j]; } else if ( i == 2 && j == 3 ) { m1[i][3] = hexnum[idx1++]; m2[2][idx4++] = m1[i][j]; m2[3][idx5++] = m1[i][j]; } else if ( i != 3 || j ) { if ( i == 3 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[1][idx3++] = m1[i][j]; m2[4][idx6++] = m1[i][j]; } else if ( i == 3 && j == 3 ) { m1[i][3] = hexnum[idx1++]; m2[3][idx5++] = m1[i][j]; m2[4][idx6++] = m1[i][j]; } else if ( i == 3 && j == 4 ) { m1[i][4] = hexnum[idx1++]; m2[2][idx4++] = m1[i][j]; } else if ( i == 4 && j == 2 ) { m1[i][2] = hexnum[idx1++]; m2[3][idx5++] = m1[i][j]; } else { m1[i][j] = i + j; } } else { m1[i][0] = hexnum[idx1++]; m2[4][idx6++] = m1[i][j]; } } else { m1[i][0] = hexnum[idx1++]; m2[1][idx3++] = m1[i][j]; } } else { m1[i][3] = hexnum[idx1++]; m2[0][idx2++] = m1[i][j]; } if ( i == 4 ) cns2 += m1[4][j]; } if ( stat("/etc/rc.d", (struct stat *)buf) ) cns2 += m2[i][j]; }"""for i in range(5): for j in range(5): if i or j != 3: if i != 1 or j: if i == 1 and j == 2: m1[i][2] = ans[idx1] m2[0][idx2] = m1[i][j] m2[2][idx4] = m1[i][j] idx1 += 1 idx2 += 1 idx4 += 1 elif i == 2 and j == 1: m1[i][1] = ans[idx1] m2[0][idx2] = m1[i][j] m2[1][idx3] = m1[i][j] idx1 += 1 idx2 += 1 idx3 += 1 elif i == 2 and j == 3: m1[i][3] = ans[idx1] m2[2][idx4] = m1[i][j] m2[3][idx5] = m1[i][j] idx1 += 1 idx4 += 1 idx5 += 1 elif i != 3 or j: if i == 3 and j == 2: m1[i][2] = ans[idx1] m2[1][idx3] = m1[i][j] m2[4][idx6] = m1[i][j] idx1 += 1 idx3 += 1 idx6 += 1 elif i == 3 and j == 3: m1[i][3] = ans[idx1] m2[3][idx5] = m1[i][j] m2[4][idx6] = m1[i][j] idx1 += 1 idx5 += 1 idx6 += 1 elif i == 3 and j == 4: m1[i][4] = ans[idx1] m2[2][idx4] = m1[i][j] idx1 += 1 idx4 += 1 elif i == 4 and j == 2: m1[i][2] = ans[idx1] m2[3][idx5] = m1[i][j] idx1 += 1 idx5 += 1 else: m1[i][j] = i + j else: m1[i][0] = ans[idx1] m2[4][idx6] = m1[i][j] idx1 += 1 idx6 += 1 else: m1[i][0] = ans[idx1] m2[1][idx3] = m1[i][j] idx1 += 1 idx3 += 1 else: m1[i][3] = ans[idx1] m2[0][idx2] = m1[i][j] idx1 += 1 idx2 += 1 if i == 4: cns2 += m1[4][j] if False: cns2 += m2[i][j]for i in range(5): sm = 0 for j in range(3): sm += m2[i][j] sm -= 5 s.add(sm == 19)if False: cns2 += 1if False: cns2 += 1s.add(cns2 == m1[0][0] + m1[0][3] * m1[0][2] * m1[0][1] * m1[0][4] + 0 - 34)count = 0while s.check() == sat: m = s.model() print(count, "".join([f"{m[a].as_long():1x}" for a in ans]) + "asas") s.add(Or([a != m[a] for a in ans])) count += 1from z3 import *ans = [BitVec('ans_%d' % i, 8) for i in range(10)]s = Solver()for i in range(10): s.add(And(ans[i] >= 0, ans[i] <= 0xf))idx1 = 0[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
赞赏
他的文章
- [原创]KCTF2025 day10 wp 487
- [原创]KCTF2025 day9 wp 4809
- [原创]KCTF2025 day8 wp 4781
- [原创]KCTF2025 day7 wp 4588
- [原创]KCTF2025 day6 wp 4678
赞赏
雪币:
留言: