[MoeCTF 2022]Broken_hash

最后更新于 2024-09-14 551 字 预计阅读时间: 3 分钟


64位PE程序,ida打开得到分析得到

进入sha1_change函数,该函数对每个input的值进行了以下操作

进入v_k_init函数有

构建结构体得到五个初始魔改向量v,4个k值

进入encrypt函数得到

开始的数据填充区

R < 448,在最后一组的末尾填充1个“1”及若干个“0”,直到满足448b(b + paddingLength % 512 = 448);再在这448位的基础上填充64位,这64位是M的原始长度的二进制表示

R >= 448,在最后一组的末尾填充1个“1”及若干个“0”,使最后一组位数达到512;再新增一组,添加448个“0”和64位M的原始长度的二进制表示。

每个字符为1字节,0x38*8=448bit,input>0x38填充到512字节后添加448个“0”和64位M的原始长度进行两次sha1,else则直接添加原始长度进行一次she1

进入sha1函数

对应以下,k的值会随着轮数的不同而不同

进入encrypt的最后部分

最后的结果只取了魔改sha1结果移位后的前四字节

在后续代码中发现了SEH

汇编中可以看到

v7在程序一开头就赋值

当我们没调试后并且输入错误后error函数中会变成1/0出发异常到新的分支执行语句,该程序的流程为:判断是否为调试状态----->按照目前状态判断是否执行SEH反调试----->输入flag(长度为88)----->进入魔改sha1----->对比

我们可以借此修改代码使其输出i值,因为每输入正确一个数i的值会增加

将图中nop掉并将箭头处改为i的地址

记录下i的机器码44 24 20

在1e04处改

执行python语句爆破得到flag

import subprocess

flag = 'moectf{'
for i in range(7, 88):
    for j in range(0x21,0x7f):
        tmp = flag + chr(j) * (88 - i)
        p = subprocess.Popen(["C:\\User\\Downloads\\Broken_hash.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        p.stdin.write(tmp.encode())
        p.stdin.close()
        out = p.stdout.read()
        p.stdout.close()

        if out[-1] > i:
            flag += chr(j)
            print(flag)
            break
flag += '}'
print(flag)

此作者没有提供个人介绍。
最后更新于 2024-09-14