分析
该文件为64位的ELF文件,运行在linux平台
使用IDA64打开
进入Decry函数
输入flag和成功的提示
看看如何才能成功拿到flag
这里比较text和str2,text是源代码就有的
那么str2应该就是我们输入的内容
先分析text的内容是什么
进入join函数
该函数将两个输入字符串连接在一起,并返回一个新的字符串,表示连接后的结果。
char *__fastcall join(const char *a1, const char *a2)
{size_t v2; // 用于存储第一个输入字符串的长度size_t v3; // 用于存储第二个输入字符串的长度char *dest; // 用于存储连接后的字符串的指针// 计算第一个输入字符串的长度v2 = strlen(a1);// 计算第二个输入字符串的长度v3 = strlen(a2);// 分配足够的内存来存储连接后的字符串,加1是为了存储字符串结尾的空字符 '\0'dest = (char *)malloc(v2 + v3 + 1);// 检查内存分配是否成功if (!dest)exit(1); // 如果分配失败,则退出程序// 将第一个输入字符串复制到目标字符串strcpy(dest, a1);// 将第二个输入字符串连接到目标字符串末尾strcat(dest, a2);// 返回连接后的字符串return dest;
}
我们不难得到text的值
点击一下0x776F646168LL然后按r
因为是小端序,所以低位在前,高位在后,所以最后需要反过来
hadow
killshadow
接下来就看要如何输入才能构造出这个字符串
将所有字符显示出来,点击在数字上然后按r,这样看着更直观
这里贴上ascii码表链接作为对照: https://tool.oschina.net/commons?type=4
如果你输入的是大写字母,那么就执行下面的语句
str2[v2] = (v1 - 39 - key[v3 % v5] + 'a') % 26 + 'a';
++v3;
如果是小写就执行
str2[v2] = (v1 - 39 - key[v3 % v5] + 'a') % 26 + 'a';
++v3;
输入其他的字符就不进行处理
你会发现这两条语句是一样的,也就是说只要输入的是英文,就执行这条语句,后面 %26说明最后运算出来的结果都不会大于26,最后加上a,也就是说最后计算出来的范围是小写字母
这里我们还需要知道key是什么
这里将key1的值给了key,然后在key的末尾追加了src (这里的SLCDN同样要反过来,图上写错了)
最后下面的for循环将key中所有的字母都小写了
所以最后key的值为 adsfkndcls
v3的值为10
v5的值为10
EXP
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{int v3 = 10, v5 = 10, l, a;char key[] = "adsfkndcls";char str2[20];int base = 65; // 以大写为基数// str2[v2] = (v1 - 39 - key[v3 % v5] + 'a') % 26 + 'a';// str2[v2] = (v1 - key[v3 % v5] + 58) % 26 + 'a';// str2[v2] = (23 - key[v3 % v5] + 58) % 26 + 'a';char text[] = "killshadow";for (int i = 0; i < strlen(text); i++){l = (base + 58 - key[v3 % v5]) % 26; // 这里之所以多了个65是因为字母的最小ASCII码就是65a = text[i] - 'a';// 有两种情况,大于 answer 和小于 answerif (l > a)printf("%c", base + 26 - l + a);elseprintf("%c", base + a - l);v3++;}
}
最终flag
flag{KLDQCUDFZO}
其实还有个答案,就是以小写为基数,将base改为97
flag{efxkwoxzti}
但是flag就只有一个,那就是那个大写的falg
其他解法
还有一种解法就是直接进行暴力破解
因为我们的输入也就是英文字母
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{int v3 = 10, v5 = 10, l, a;char text[] = "killshadow";char key[] = "adsfkndcls";char str2[20];int base = 65;for (int n = 0; n < strlen(text); n++){for (int i = base; i < 26 + base; i++){// str2[v2] = (v1 - 39 - key[v3 % v5] + 'a') % 26 + 'a';if ((i - 39 - key[v3 % v5] + 'a') % 26 + 'a' == text[n]){printf("%c", i);v3++;break;}}}
}