> 文章列表 > BUUCTF-SimpleRev

BUUCTF-SimpleRev

BUUCTF-SimpleRev

下载文件 查壳 没有加壳 并且是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; // rbxsize_t v3; // raxchar *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进行计算然后得到str2str2[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):   #暴力破解  遍历所有的asciiif 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+'}')

结束该题