X-NUCA 2019 线上赛damnV 分值:323 已解答:12Ahh.... So boring.
其实这是一道很简单的逆向题,只是用了 KVM 虚拟机。本来可以更快做出来的,可惜时间都花在逆向虚拟机的运行参数上了...
程序要求输入233个80字节的 payload。每个 payload 要经过18次 check(check 代码运行在 KVM 虚拟机上)。每轮 check 成功后,打乱 check 的执行顺序,再重新 check 下一个 payload。
全局变量check_list数组记录了每次 check 的种类id、需要读入的 payload 长度payload_size和 check 时使用的数据data。
struct Check{__int32 id;__int32 payload_size;__int32 data[16];};
一共有四种 check,代码开头位于0x203530。
第一种 check 是计算payload的 crc32 哈希值,检查是否等于data[0],可以直接爆破:
第二种 check 的算法看不懂,不过可以爆破:
第三种 check 是自定义字母表的 base64:
第四种 check 是简单的异或:
程序先创建了一个 KVM 虚拟机。
具体的创建流程可以参考这篇文章。
创建后,在虚拟机内存地址0处下了一个断点。
开始 check 前,将虚拟机rip设置为0,然后将 check 代码复制到虚拟机内存。
从check_list载入 check 的信息。
运行虚拟机,并读入payload_size字节的payload。
虚拟机触发断点,返回程序。程序按照id将rip重新设置为 check 的入口地址,并将payload和data复制到虚拟机内存,然后重新运行虚拟机。
虚拟机停机后,程序检查返回值。如果为1,说明 check 成功。
每经过18次 check 后,从头到尾历遍check_list数组上的元素,用rand函数生成的随机数选择另一个元素,与其交