首页
社区
课程
招聘
[原创]KCTF 2024 第六题 WriteUp
发表于: 2024-8-27 00:28 3069

[原创]KCTF 2024 第六题 WriteUp

2024-8-27 00:28
3069

首先x64dbg挂上,验证一遍给的用户名和序列号能否通过,发现可以通过,看来没加反调试或者反调试被ScyllaHide给干掉了,好事

用IDA看了看,关键的部分是这个函数,用x64dbg下硬件断点设置日志输出,把这两个地方call的地址都记录下来

其中,v13的基本上都是上面这种,调用的外部函数,或者.text段中的被虚拟化的函数

而rcx的则是零散的加了混淆的代码块,基本上就popfq的下一条指令是真实指令,别的都是保存、恢复上下文和修改控制流的指令,写个脚本通过刚才记录的call地址把代码还原出来(如果想看仔细一点就把去重的逻辑删掉,输出的内容会多很多)

代码很清楚,没有嵌套混淆,也没有奇奇怪怪的扩展指令集优化

简单描述一下算法,就是把输入的16字节用户名(不满16字节则填充0x00)和"welcome_to_fzbz,"异或,再把输入的64字节0-9、A-F序列号转换为32字节,然后进行4次大循环,每次循环处理8字节序列号,其中用到了异或后的16字节用户名,最后把处理完的序列号和"welcome_to_fzbz,my_name_is_sbzx!"判断是否相同,我写了一个每一次大循环的python等价代码

每个input、output都是4字节,两个加起来8字节,用户名的部分我硬编码到算法代码里了

一直做到这个部分,都一路顺畅,很快搞完没有卡壳,然后……求逆算法花了巨多的时间,期间试过用z3来求解,然后发现挂了半天啥也没算出来,问GPT也是一通胡言乱语,最后还是用笨办法老老实实手动搞完的

fn = ...
fp = open(..., "w")
visited = set()
 
for i in fn.splitlines():
    ea = int(i, 16)
 
    if ea in visited:
        continue
 
    visited.add(ea)
    idaapi.create_insn(ea + 1)
    fp.write(hex(ea))
    fp.write("\t\t")
    fp.write(generate_disasm_line(ea + 1, 0))
    fp.write("\n")
 
fp.close()
fn = ...
fp = open(..., "w")
visited = set()
 
for i in fn.splitlines():
    ea = int(i, 16)
 
    if ea in visited:
        continue
 
    visited.add(ea)
    idaapi.create_insn(ea + 1)
    fp.write(hex(ea))
    fp.write("\t\t")
    fp.write(generate_disasm_line(ea + 1, 0))
    fp.write("\n")
 
fp.close()
import ctypes
 
input_A = ...
input_B = ...
rsp_1 = ctypes.c_uint(input_A)
rsp_2 = ctypes.c_uint(input_B)
rsp_0 = ctypes.c_uint(0x2538263C)
rsp_5 = ctypes.c_uint(0x5F656D6F)
eax = ctypes.c_uint(0)
ecx = ctypes.c_uint(0)
edx = ctypes.c_uint(0)
 
for _ in range(0x1F):
    eax.value = rsp_2.value
    eax.value <<= 6
    ecx.value = rsp_0.value
    ecx.value &= 0xFF
    eax.value += ecx.value
    ecx.value = rsp_0.value
    edx.value = rsp_2.value
    edx.value += ecx.value
    ecx.value = edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_2.value
    ecx.value >>= 3
    edx.value = rsp_0.value
    edx.value >>= 8
    edx.value &= 0xFF
    ecx.value += edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_1.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_1.value = eax.value
    eax.value = rsp_5.value
    ecx.value = rsp_0.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_0.value = eax.value
    eax.value = rsp_1.value
    eax.value <<= 6
    ecx.value = rsp_0.value
    ecx.value >>= 0x18
    ecx.value &= 0xFF
    eax.value += ecx.value
    ecx.value = rsp_0.value
    edx.value = rsp_1.value
    edx.value += ecx.value
    ecx.value = edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_1.value
    ecx.value >>= 3
    edx.value = rsp_0.value
    edx.value >>= 0x10
    edx.value &= 0xFF
    ecx.value += edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_2.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_2.value = eax.value
 
rsp_1.value ^= rsp_0.value
rsp_2.value ^= rsp_0.value
rsp_0 = ctypes.c_uint(0x665F6F74)
rsp_5 = ctypes.c_uint(0x2C7A627A)
 
for _ in range(0x1F):
    eax.value = rsp_2.value
    eax.value <<= 4
    ecx.value = rsp_0.value
    ecx.value >>= 0x18
    ecx.value &= 0xFF
    eax.value += ecx.value
    ecx.value = rsp_0.value
    edx.value = rsp_2.value
    edx.value += ecx.value
    ecx.value = edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_2.value
    ecx.value >>= 5
    edx.value = rsp_0.value
    edx.value &= 0xFF
    ecx.value += edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_1.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_1.value = eax.value
    eax.value = rsp_5.value
    ecx.value = rsp_0.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_0.value = eax.value
    eax.value = rsp_1.value
    eax.value <<= 4
    ecx.value = rsp_0.value
    ecx.value >>= 0x10
    ecx.value &= 0xFF
    eax.value += ecx.value
    ecx.value = rsp_0.value
    edx.value = rsp_1.value
    edx.value += ecx.value
    ecx.value = edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_1.value
    ecx.value >>= 5
    edx.value = rsp_0.value
    edx.value >>= 8
    edx.value &= 0xFF
    ecx.value += edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_2.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_2.value = eax.value
 
output_A = rsp_0.value ^ rsp_1.value
output_B = rsp_0.value ^ rsp_2.value
import ctypes
 
input_A = ...
input_B = ...
rsp_1 = ctypes.c_uint(input_A)
rsp_2 = ctypes.c_uint(input_B)
rsp_0 = ctypes.c_uint(0x2538263C)
rsp_5 = ctypes.c_uint(0x5F656D6F)
eax = ctypes.c_uint(0)
ecx = ctypes.c_uint(0)
edx = ctypes.c_uint(0)
 
for _ in range(0x1F):
    eax.value = rsp_2.value
    eax.value <<= 6
    ecx.value = rsp_0.value
    ecx.value &= 0xFF
    eax.value += ecx.value
    ecx.value = rsp_0.value
    edx.value = rsp_2.value
    edx.value += ecx.value
    ecx.value = edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_2.value
    ecx.value >>= 3
    edx.value = rsp_0.value
    edx.value >>= 8
    edx.value &= 0xFF
    ecx.value += edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_1.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_1.value = eax.value
    eax.value = rsp_5.value
    ecx.value = rsp_0.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_0.value = eax.value
    eax.value = rsp_1.value
    eax.value <<= 6
    ecx.value = rsp_0.value
    ecx.value >>= 0x18
    ecx.value &= 0xFF
    eax.value += ecx.value
    ecx.value = rsp_0.value
    edx.value = rsp_1.value
    edx.value += ecx.value
    ecx.value = edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_1.value
    ecx.value >>= 3
    edx.value = rsp_0.value
    edx.value >>= 0x10
    edx.value &= 0xFF
    ecx.value += edx.value
    eax.value ^= ecx.value
    ecx.value = rsp_2.value
    ecx.value += eax.value
    eax.value = ecx.value
    rsp_2.value = eax.value
 
rsp_1.value ^= rsp_0.value
rsp_2.value ^= rsp_0.value
rsp_0 = ctypes.c_uint(0x665F6F74)
rsp_5 = ctypes.c_uint(0x2C7A627A)
 
for _ in range(0x1F):
    eax.value = rsp_2.value
    eax.value <<= 4
    ecx.value = rsp_0.value
    ecx.value >>= 0x18
    ecx.value &= 0xFF
    eax.value += ecx.value
    ecx.value = rsp_0.value
    edx.value = rsp_2.value

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

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