Press "Enter" to skip to content

redemption_code WriteUp

题目来源

2021 虎符CTF

初步分析

我们首先使用file命令初步分析

这是一个运行在Linux上的Mips32架构的可执行文件

逆向分析

我们使用IDA打开文件

main()

我们观察main函数:

发现主要的处理过程应该在pre()和server_check_redemption_code()两个函数

pre()

pre()函数中,只对flag的长度做了要求,为14字节,仍然通过server_check_redemption_code()函数来判断flag,我们可以推断对flag的检查主要在该函数中

server_check_redemption_code()

这个函数主要功能在如下两个部分:

将输入映射到二维数组

这里我们a2即是我们输入的flag,v10是flag的长度。

我们主要关注循环中判断处的逻辑

j == a2[i]时,s[i][j] = i + 1s[i][a2[i]] = i + 1, 即每一行a2[i]的位置值为i + 1

计算偏移值

这里a1是作为参数给定的字符串。

根据上一步我们计算出的表,为使v7 == v10成立,我们需要使得a1中存在子字符串为我们的flag,这样才能让v7依次由0变化到v10,此时k是子字符串结束的位置,那么k - v10 + 1即是flag相对于a1的偏移量。

我们再回到pre()函数中调用server_check_redemption_code()处:

这里要求返回不为-1,即是要求输入的flag为"Ninja Must Die 3 Is A Cruel Game, So Hard For Me"的子串。

我们回到main()函数中调用server_check_redemption_code()处:

这里要求返回值为7,根据我们之前对server_check_redemption的分析,即是要求flag的第一个字母是"I Love Ninja Must Die 3. Beautiful Art And Motive Operation Is Creative."下标为7的字符,即第八个字符,而pre()中又要求flag长度为14,因此flag为"Ninjia Must Die"

Flag

flag{Ninja Must Die}

感想

好用的工具是很重要的,比赛的时候我用的IDA版本不能反编译mips,就用ghidra了,可读性很差,最后没能做出来。

附件