title: 攻防世界 parallel-comparator-200 date: 2021年8月12日 19点36分 tags: 攻防世界 categories: 攻防世界
今天碰到了一道特别坑的题目,来自攻防世界 parallel-comparator-200
这道题很坑,非常坑,我们可以看到,下载题目之后,得到的是一个.c代码。直接DEVC++打开了。发现是代码,那么直接分析给的代码就行啦?
自我分析得出结果
1、分析源代码
我的第21行,它一开始是random函数,但是运行并不好使,我就改为了rand。
然后运行成功之后,我一开始发现输入什么都是错的。
根据这个main函数,我们知道,需要这个is_ok = 1,那么才会输出You win!,所以is_ok要等于 1,
我们看到,这里有is_ok,一开始是 等于1,但是经过一个for循环之后,就返回0了,所以这里,这两个数组需要相等。
再看这里,这两个数组需要相等,那么result 就得等于0,所以推得result = 0;
再看这里。
这个pthread_create这里,百度一手,是多线程的意思。 这是题外话。
既然知道了result = 0,找到result,发现
我们可以看到,(argument[0] + argument[1]) ^ argument[2]
^异或:两个值异或,值要不一样才为1。所以这里他们要相等,相等就为0了。
既然知道了argument[0] + argument[1] = argument[2]
我们看到这里。
2、自己加的一个C语言代码小技巧(解题最重要的一步)
我在分析的头皮发麻的时候,突然发现这里有一个随机数,突发奇想,我们直接把这个值打印出来,看看它每次都是多少,所以在这里我自己运用了一个小技巧。
在这里,我加了一行代码,printf(“%d”, initialization_number);
这个技巧也是自己学习C语言的时候,老师所讲,在这里运用上了。哈哈哈哈
然后我开始实验,经过我的几次实验发现,这个随机数的值都是一样的,我这里是41 .
我于是把后面的64改了,再实验,还是发现每次得到的值都是一样,且随着我修改64的值,这个随机值也是跟着减少,但是每次随机都是一样的。于是便大胆猜测到这个initialization_number = 41,带入到后面的first_letter,
也就是41 对26取余 等于 15,15 + 97 = 112;
也就是first_letter = 112;
接下来就是argument【1】的值了。这是已经告诉的。
3、自己写的一个脚本(不是爆破)
然后写一个C语言脚本来算。
但是得出来的答案不对。
这个地方我疑惑不解,然后查看大佬的wp,发现,first_letter在windows上的值是112,但是在linux的值是108,然后我把脚本改为108,居然成功了。我wtf???
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#define FLAG_LEN 20
int main(void)
{
char differences[FLAG_LEN] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};
char flag[] = "";
int i;
for(i = 0; i<FLAG_LEN; i++)
{
flag[i] = 108 + differences[i];
printf("%c", flag[i]);
}
return 0;
}
观看大佬的wp,进行复盘,查看其他解法
(1)C语言爆破脚本,来自攻防世界此题的wp中,作者是AugustKing。
#include <stdio.h>
#define FLAG_LEN 20
int main(int argc, char* argv[]) {
char flag[21] = {0};
char differences[FLAG_LEN] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1,
-7, 6, -13, 13, 3, 9, -13, -11, 6, -7};
for (size_t i = 0; i < 64; i++) {
for (size_t j = 0; j < 20; j++) {
flag[j] = ((i % 26) + 97) + differences[j];
}
printf("%s\n", flag);
}
return 0;
}
我们可以发现,大佬这里,没有自己算出first的值,而是爆破解出。
得出flag。
总结
这个题,说实话,有点坑,我还费力的去查函数的作用,从这个题来讲,还是选择爆破更好,不然就像我一样,first的值定不下来,在windows中是112,但是在linux是108,这里用的是108,所以导致我一开始的脚本没有得到答案,但是爆破的话,就不管你是什么了,直接出答案,还是很爽的,但是我不会爆破。
这道题也算是一改往常的藏着掖着,直接把代码给咱们看,来分析它。大概思路通了之后,还是很容易得出flag,但是思路没通就坏了,一开始看到这么长的代码,心里还有点害怕,后面深入分析之后,还是顺利分析出来了。
继续加油啊。
|