前两天在一个CTF比赛中拿到一个exe文件,当时由于时间匆忙没来得及解答,这两天研究了一下,写一下解题思路。
查壳
对于逆向类题目,exe文件拿到手第一步肯定要先查一下有没有壳,如果有壳,先脱壳,再用静态或者动态分析研究。
很幸运,没有壳。
分析
先运行一下程序,看看是啥情况。
我们看到有这么两行字,直接拖到IDA Pro里,打开strings界面,找一下这两行字。
在strings界面,我们还有额外的收获,直接显示了我们想要的结果,那么这肯定就是最后显示答案的程序语句输出了,直接双击语句跳转到IDA视图。
在IDA视图里,我们看到语句的输出是由main函数来控制的,鼠标双击红框内的main函数,再按F5,查看伪代码如下:
通过上面的伪代码可以看到,程序的主逻辑如下:
1、首先对输入的字符串进行长度判断,如果长度和给定的字符串(Hv1g_1g_M0if_Tzou_v4v4v)长度不一致,那么直接输出“YouBadGuy”,退出程序;
2、若长度和给定字符串的长度一致,则进行for循环对输入的字符串进行变换;
3、对输入的字符串进行变换后和给定的字符串进行比较,如果一致就输出“I Agree With You”,并且打印出flag,如果不一致,则输出“YouBadGuy”,退出程序;
所以我们的目标就是找到一个字符串,通过for循环转换后和目标字符串一致即可。到这里问题就转换为已知输出的字符串和转换规则,求输入的字符串。那么我们来看一下转换规则:
unsigned int v5; // kr04_4
int i; // ecx
char v8; // al
char v9; // dl
for ( i = 0; i <= (signed int)(v5 - 2); ++i )
{
v8 = v10[i];
if ( v8 > 90 || v8 < 65 )
{
if ( v8 > 122 || v8 < 97 )
continue;
v9 = (v8 - 83) % 26 + 97;
}
else
{
v9 = (v8 - 51) % 26 + 65;
}
v10[i] = v9;
}
对上面的伪代码进行分析,可以得出以下结论:
1、当输入的字符为数字(48-57)和特殊字符(91-96)时,不进行转换;
2、当输入的字符为大写字母(65-90)的时候,对字符进行凯撒加密,密钥为14;
3、当输入的字符为小写字母(97-122)的时候,对字符进行凯撒加密,密钥为14.
到了这里,问题再度转化为凯撒解密,已知密文和密钥,求解明文,直接上Visual Studio,C语言凯撒解密,随便编了一下,算法如下:
#include<stdio.h>
#include<stdlib.h>
void main()
{
char M[20] = "Hv1g1gM0ifTzouv4v4v";
char N = "0";
char m = "0";
for (int i = 0; i < 20; ++i)
{
N = M[i];
if (65 <= N && N <= 90)
{
N = (N - 53) % 26 + 65;
M[i] = N;
printf("%c", M[i]);
continue;
}
else if (97 <= N && N <= 122)
{
N = (N - 85) % 26 + 97;
M[i] = N;
printf("%c", M[i]);
continue;
}
printf("%c", M[i]);
}
system("pause");
}
执行后得到如下结果:
将得到的结果输入到程序里