BUU_RE学习记录

时间:2022-12-18 18:08:19

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