下载文件 查壳 没有加壳 并且是64
放入ida64
SHIFT+F12
访问字符串
得到关键字符串
双击 然后
CRTL+X
查找交互
F5
反编译
得到了代码 开始代码审计
我们可以发现有两个十六进制的东西
r
对其转换为字符串
src=SLCDN
v9=wodah
然后继续往下看
发现text=join函数 我们进入看看函数做什么
双击进入
char *__fastcall join(const char *a1, const char *a2)
{
size_t v2; // rbx
size_t v3; // rax
char *dest; // [rsp+18h] [rbp-18h]
v2 = strlen(a1);
v3 = strlen(a2);
dest = (char *)malloc(v2 + v3 + 1);
if ( !dest )
exit(1);
关键在这
strcpy(dest, a1); 把a1复制给dest
strcat(dest, a2); 把a2与dest进行拼接
return dest;
}
我们发现join函数是对key3 和v9
双击key3
key3 = kills
v9 = wodah
但是 v9 是小端序 我认为是直接在主函数赋值 key3 是双击进入内存找到的
所以v9 要进行逆序
则拼接完
text=killshadow
strcpy(key, key1);
strcat(key, src);
v2 = 0;
v3 = 0;
又是一拼接 strcat 是拼接
key和src拼接
双击进入key1
所以
key1 = ADSFK
那么key = ADSFK
src=SLCDN
拼接完
key = ADSFKNDCLS
先确定目前已知的东西
key = ADSFKNDCLS
text=killshadow
继续
v5 = strlen(key);
for ( i = 0; i < v5; ++i )
{
if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
key[i] = key[v3 % v5] + 32;
++v3;
}
一个循环
我们把64 和90 r转换一下
很眼熟 我们查看ascii表
能发现是遍历 字母
然后下面+32 是变小写
所以我们需要把key变为小写
下面就是主要的判断语句
if ( v1 <= 96 || v1 > 122 )这个不重要 是对flag进行过滤
{
if ( v1 > 64 && v1 <= 90 ) 这个是对flag进行计算然后得到str2
str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
}
else
{
str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
}
if ( !(v3 % v5) )
putchar(32);
++v2;
}
}
if ( !strcmp(text, str2) ) str2和text进行比较 如果相同 则输出正确
puts("Congratulation!\n");
其实这个是作者故意恶心我们
这个语句其实不管条件成不成立 都执行这个
str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
exp
key ='ADSFKNDCLS'
text='killshadow'
flag=''
key = key.lower()
for i in range(0,10):
for x in range (128): #暴力破解 遍历所有的ascii
if chr(x).isalpha(): #要进行判断 因为我们是暴力破解 所以有符号 我们必须要字符串
a = (x - 39 - ord(key[i]) + 97)% 26 + 97 #str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
if text[i]==chr(a): #进行最终的判断 就是text 和str的判断 但是是单个字符单个字符的判断
flag+=chr(x)
break #一定要break 不然出不来
print('flag{'+flag+'}')
结束该题