骑着驴子追宝马 发表于 2021-11-13 16:54

BUUCTF-[羊城杯 2020]easyre1

BUUCTF-[羊城杯 2020]easyre1 首先下载好文件后查壳,无壳,直接用IDA打开int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // eax
int v5; // eax
int result; // eax
char Str; // BYREF
char Str1; // BYREF
char v9; // BYREF
char v10; // BYREF
char Str2; // BYREF
int v12; // BYREF

_main(argc, argv, envp);
strcpy(Str2, "EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG");
puts("Hello, please input your flag and I will tell you whether it is right or not.");
scanf("%38s", Str);//长度38
if ( strlen(Str) != 38
    || (v3 = strlen(Str), encode_one(Str, v3, v10, &v12))
    || (v4 = strlen(v10), encode_two(v10, v4, v9, &v12))
    || (v5 = strlen(v9), encode_three(v9, v5, Str1, &v12))
    || strcmp(Str1, Str2) )   //3次加密
{
    printf("Something wrong. Keep going.");
    result = 0;
}
else
{
    puts("you are right!");
    result = 0;
}
return result;
}

直接进入main函数,从这四条语句发现,是要输入38位的flag,对38位的字符串加密然后与其比较EmBmP5Pmn7QcPU4gLYKv5QcMmB3PWHcP5YkPq3=cT6QckkPckoRG1.首先进入第一个加密算法encode_one__int64 __fastcall encode_one(const char *a1, int a2, char *a3, int *a4)
{
int v5; // esi
int v6; // esi
int v7; // esi
int v8; //
int v9; //
int v11; //
int i; //
unsigned __int8 *v13; //

v13 = a1;
if ( !a1 || !a2 )
    return 0xFFFFFFFFi64;
v11 = 0;
if ( a2 % 3 )
    v11 = 3 - a2 % 3;
v9 = a2 + v11;
v8 = 8 * (a2 + v11) / 6;
for ( i = 0; i < v9; i += 3 )
{
    *a3 = alphabet[*v13 >> 2];
    if ( a2 + v11 - 3 == i && v11 )
    {
      if ( v11 == 1 )
      {
      v5 = cmove_bits(*v13, 6u, 2u);
      a3 = alphabet, 0, 4u)];
      a3 = alphabet, 4u, 2u)];
      a3 = '=';
      }
      else if ( v11 == 2 )
      {
      a3 = alphabet;
      a3 = '=';
      a3 = '=';
      }
    }
    else
    {
      v6 = cmove_bits(*v13, 6u, 2u);
      a3 = alphabet, 0, 4u)];
      v7 = cmove_bits(v13, 4u, 2u);
      a3 = alphabet, 0, 6u)];
      a3 = alphabet & 0x3F];
    }
    a3 += 4;
    v13 += 3;
}
if ( a4 )
    *a4 = v8;
return 0i64;
}

跟进去发现是一个base64加密,alphabet跟进发现是码表
https://img-blog.csdnimg.cn/974ddcf781b54916b2c0fa5a346cadec.png

2.进入encode_two __int64 __fastcall encode_two(const char *a1, int a2, char *a3, int *a4)
{
char *Source; //
char *v6; //

Source = (char *)a1;
v6 = a3;
if ( !a1 || !a2 )
    return 0xFFFFFFFFi64;
strncpy(a3, a1 + 26, 0xDui64);
strncpy(v6 + 13, Source, 0xDui64);
strncpy(v6 + 26, Source + 39, 0xDui64);
strncpy(v6 + 39, Source + 13, 0xDui64);
return 0i64;
}

经过分析,可以很容易的知道,是将字符串的每13位调换位置
https://img-blog.csdnimg.cn/30637be8009c4c578caf1e5ec3dedb87.png

3.进入encode_three_int64 __fastcall encode_three(const char *a1, int a2, char *a3, int *a4)
{
char v5; //
int i; //
char *v7; //
const char *v8; //

v8 = a1;
if ( !a1 || !a2 )
    return 0xFFFFFFFFi64;
v7 = a3;
for ( i = 0; i < a2; ++i )
{
    v5 = *v8;
    if ( *v8 <= 64 || v5 > 90 )
    {
      if ( v5 <= 96 || v5 > 122 )
      {
      if ( v5 <= 47 || v5 > 57 )
          *v7 = v5;
      else
          *v7 = (v5 - 48 + 3) % 10 + 48;
      }
      else
      {
      *v7 = (v5 - 97 + 3) % 26 + 97;
      }
    }
    else
    {
      *v7 = (v5 - 65 + 3) % 26 + 65;
    }
    ++v7;
    ++v8;
}
return 0i64;
}

这是一个凯撒加密,偏移量为3第一步解密,经过凯撒解密后得到字符串,然后进行位置的调换和base64的解密 ,附上脚本
import base64
data = "BjYjM2Mjk4NzMR1dIVHs2NzJjY0MTEzM2VhMn0=zQ3NzhhMzhlOD"

raw = ["0" for _ in range(38)]

raw = data
raw = data
raw = data
raw = data

print(base64.b64decode("".join(raw).encode()).decode())得到flagGWHT{672cc4778a38e80cb362987341133ea2}

ctf101 发表于 2021-12-26 15:20

萌新,学习一下大佬的逆向思路
页: [1]
查看完整版本: BUUCTF-[羊城杯 2020]easyre1