BUU_RE学习记录

一、easyre

1.010打开,直接搜flag,得到flag

BUU_RE学习记录

二、reverse1

1.先查壳,得知是64位无壳,直接用IDA打开

BUU_RE学习记录

2.shiftF12查找字符串,发现关键语句

BUU_RE学习记录

3.查看相应代码,F5反编译

BUU_RE学习记录

4.发现关键的比较函数,看一下分别比较的字符串

BUU_RE学习记录

5.发现是输入的str1和程序中的str2({hello_world})相比较,那么flag就是{hello_world}

BUU_RE学习记录

三.reverse2

1.查壳,64位,非exe

BUU_RE学习记录

2.IDA打开,shift12发现关键语段

BUU_RE学习记录

3.找到对应的函数,发现是一个将flag和输入的字符串进行对比

BUU_RE学习记录

4.代码表现出了flag的加密过程,但是根据代码的判断应该会存在一个原flag字符串,回去查找字符串,发现了一个特殊意义的str

BUU_RE学习记录

5.之前提到的flag加密代码的含义就是逐个遍历flag的字符,如果字符为i或者r,那就把它改为1。直接写个脚本跑一下(或者可直接手动)。

点击查看代码
#include <iostream> #include <stdlib.h> #include <stdio.h>  int main() {     int i = 0;     char flag[] = "hacking_for_fun}";     for (i = 0; i <= 15; ++i)     {         if (flag[i] == 'i' || flag[i] == 'r')             flag[i] = '1';     }     printf("%s", flag); 	return 0; } 

6.得到flag

flag{hack1ng_fo1_fun} 

四.内涵的软件

1.查壳,无壳,IDA(非64位)打开,进入main函数,进入main_0函数

BUU_RE学习记录

2.找到一串字符串,就是flag(改一下前面的头)

BUU_RE学习记录

flag{49d3c93df25caad81232130f3d2ebfad} 

五、新年快乐

1.查壳,发现是UPX

BUU_RE学习记录

2.使用UPXshell解压缩去壳

BUU_RE学习记录

3.IDA(非32位)打开,找到main函数,发现关键语句

BUU_RE学习记录

4.根据比较函数发现,str2就是flag的正确形式,再看str2的来源,是使用了strcpy函数,那么flag就是HappyNewYear!

flag{HappyNewYear!} 

六、xor

1.查壳,发现是64位无壳,使用IDA打开,找到main函数

BUU_RE学习记录

2.代码的意思就是将首先判断长度是否为33,不是就failed,然后如果长度正确,就使用for循环由后一个异或前一个。找到原来的字符串

BUU_RE学习记录

3.写个脚本,利用异或的特点,得到flag(需要注意到的是有一些字符本身就是ASCII码,不能再将其转为ASCII码,否则会异或出错)

点击查看代码
s = ['f','10','k','12','w','&','O','.','@','17','x','13','Z',';','U','17','p','25','F','31','v','"','M','#','D','14','g','6','h','15','G','2','O','0'] ls = [] for i in range(0,len(s)):     if len(s[i]) > 1 or s[i] == '6' or s[i] == '0':         ls.append(int(s[i]))     else:         ls.append(ord(s[i])) for i in range(1,33):     print(chr(ls[i] ^ ls[i - 1]),end = '')  

4.得到flag(直接异或得到的字符串前面少一个f)

flag{QianQiuWanDai_YiTongJiangHu} 

七、helloword

1.得到一个apk文件,使用IDA打开,注意选择APK

BUU_RE学习记录

2.shiftF12搜索字符串,发现flag

BUU_RE学习记录

flag{7631a988259a00816deda84afb29430a} 

八、reverse3

1.查壳,无壳,使用IDA(非64)打开

BUU_RE学习记录

2.shift12搜索字符串,看到了base64和加密表以及关键词flag

BUU_RE学习记录

3.追踪找到关键函数

BUU_RE学习记录

4.关键函数代码审计一下,简单来说就是先将输入的str经过base64加密然后逐位与0123...相加,然后与str2进行比较,str2可以直接找到。直接写脚本逆回去

点击查看代码
str = "e3nifIH9b_C@n@dH" s = list(str) ls = '' for i in range(len(s)):     ls += chr(ord(s[i]) - i)  print(base64.b64decode(ls)) 

BUU_RE学习记录

5.运行后得到flag

flag{i_l0ve_you} 

BUU_RE学习记录

九、不一样的flag

1.查壳,无壳,使用IDA(非64)打开,shiftF12查找字符串

BUU_RE学习记录

2.发现一串01串,觉得像迷宫题,进入到函数

BUU_RE学习记录

3.果然是迷宫题,根据最后的输出语句可以得知flag就是走出迷宫的1234选择,根据exit()函数可以得知遇到1就退出,那就是从头走到尾同时只走0

BUU_RE学习记录

4.01串一共是25个字符,那就是5x5的矩阵

BUU_RE学习记录

5.直接目测,得到flag

222441144222 

十、SimpleRev

1.查壳,无壳,使用IDA(64位)打开

BUU_RE学习记录

2.shiftF12发现关键语句

BUU_RE学习记录

3.找到关键的程序函数main函数中的Decry()函数

点击查看代码
unsigned __int64 Decry() {   char v1; // [rsp+Fh] [rbp-51h]   int v2; // [rsp+10h] [rbp-50h]   int v3; // [rsp+14h] [rbp-4Ch]   int i; // [rsp+18h] [rbp-48h]   int v5; // [rsp+1Ch] [rbp-44h]   char src[8]; // [rsp+20h] [rbp-40h] BYREF   __int64 v7; // [rsp+28h] [rbp-38h]   int v8; // [rsp+30h] [rbp-30h]   __int64 v9[2]; // [rsp+40h] [rbp-20h] BYREF   int v10; // [rsp+50h] [rbp-10h]   unsigned __int64 v11; // [rsp+58h] [rbp-8h]    v11 = __readfsqword(0x28u);   *(_QWORD *)src = 0x534C43444ELL;   v7 = 0LL;   v8 = 0;   v9[0] = 0x776F646168LL;   v9[1] = 0LL;   v10 = 0;   text = (char *)join(key3, v9);   strcpy(key, key1);   strcat(key, src);   v2 = 0;   v3 = 0;   getchar();   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;   }   printf("Please input your flag:");   while ( 1 )   {     v1 = getchar();     if ( v1 == 10 )       break;     if ( v1 == 32 )     {       ++v2;     }     else     {       if ( v1 <= 96 || v1 > 122 )       {         if ( v1 > 64 && v1 <= 90 )         {           str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;           ++v3;         }       }       else       {         str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97;         ++v3;       }       if ( !(v3 % v5) )         putchar(32);       ++v2;     }   }   if ( !strcmp(text, str2) )     puts("Congratulation!n");   else     puts("Try again!n");   return __readfsqword(0x28u) ^ v11; } 

4.代码审计,首先看比较函数,得知是将text和str2相比较,str2目前找不到相应的字符串,text是由 join(key3, (const char *)v9);组成,key3追踪可得是kills,v9在代码的前面部分,查看十六进制可以看出是大端序存储的,但是在CPU和x86中一般为小端序存储,那么原本的字串就是IDA中转为char后倒转一下

BUU_RE学习记录

5.所以src = NDCLS , v9 = hadow,再查看join函数的源码,可以看出作用就是将key3和v9连接在一起

BUU_RE学习记录

6.所以text=killshadow,接着向下,strcpy(key, key1),key1=ADSFK,将key1复制为key,key=key1=ADSFK;strcat(key, src),将key和src连接,key = ADSFKNDCLS;v5就是key的长度,为10,接下来for循环函数的作用就是判断字符是否为大写,如果为大写就将其变为小写

BUU_RE学习记录

7.接下来就是主要的输入字串处理,而最后与text对比的str2仅由一句话决定str2[v2] = (v1 - 39 - key[v3 % v5] + 97) % 26 + 97,text已经知道了,直接写脚本跑一下

点击查看代码
v3 = 0 key = 'adsfkndcls' text = 'killshadow' key = list(key) text = list(text) for i in range(10):     for j in range(128):         if (j < ord('A') or j > ord('Z')) or (j < ord('z') and j > ord('a')):             continue         if ((j - 39 - ord(key[v3 % 10]) + 97) % 26 + 97 == ord(text[i])):             print(chr(j),end='');             v3 += 1             break 

8.需要注意,因为源码中的key在与str2比较前,经过一个函数转变全部为小写字母,所以写脚本时使用的key也应是小写字母

BUU_RE学习记录

9.得到flag

KLDQCUDFZO

发表评论

相关文章