BUUCTF Reverse/[ACTF新生赛2020]usualCrypt

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第1张图片

先查看文件信息:没有加壳且为32位程序

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第2张图片
用IDA32位打开找到main函数查看伪代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // esi
  int result; // eax
  int v5[3]; // [esp+8h] [ebp-74h] BYREF
  __int16 v6; // [esp+14h] [ebp-68h]
  char v7; // [esp+16h] [ebp-66h]
  char v8[100]; // [esp+18h] [ebp-64h] BYREF

  sub_403CF8((int)&unk_40E140);
  scanf("%s", v8);
  v5[0] = 0;
  v5[1] = 0;
  v5[2] = 0;
  v6 = 0;
  v7 = 0;
  sub_401080((int)v8, strlen(v8), (int)v5);
  v3 = 0;
  while ( *((_BYTE *)v5 + v3) == byte_40E0E4[v3] )
  {
    if ( ++v3 > strlen((const char *)v5) )
      goto LABEL_6;
  }
  sub_403CF8((int)aError);
LABEL_6:
  if ( v3 - 1 == strlen(byte_40E0E4) )
    result = sub_403CF8((int)aAreYouHappyYes);
  else
    result = sub_403CF8((int)aAreYouHappyNo);
  return result;
}

一点点分析代码

跟进查看发现这是个输出函数,又是一道字符串比较类型的题目

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第3张图片

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第4张图片

输入的flag进行变换后与byte_40E0E4中的值进行比较

 while ( *((_BYTE *)v5 + v3) == byte_40E0E4[v3] )
  {
    if ( ++v3 > strlen((const char *)v5) )
      goto LABEL_6;
  }

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第5张图片

这里对输入的flag进行了变换,跟进查看

 sub_401080((int)v8, strlen(v8), (int)v5);
int __cdecl sub_401080(int a1, int a2, int a3)
{
  int v3; // edi
  int v4; // esi
  int v5; // edx
  int v6; // eax
  int v7; // ecx
  int v8; // esi
  int v9; // esi
  int v10; // esi
  int v11; // esi
  _BYTE *v12; // ecx
  int v13; // esi
  int v15; // [esp+18h] [ebp+8h]

  v3 = 0;
  v4 = 0;
  sub_401000();
  v5 = a2 % 3;
  v6 = a1;
  v7 = a2 - a2 % 3;
  v15 = a2 % 3;
  if ( v7 > 0 )
  {
    do
    {
      LOBYTE(v5) = *(_BYTE *)(a1 + v3);
      v3 += 3;
      v8 = v4 + 1;
      *(_BYTE *)(v8 + a3 - 1) = byte_40E0A0[(v5 >> 2) & 0x3F];
      *(_BYTE *)(++v8 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(a1 + v3 - 3) & 3)
                                            + (((int)*(unsigned __int8 *)(a1 + v3 - 2) >> 4) & 0xF)];
      *(_BYTE *)(++v8 + a3 - 1) = byte_40E0A0[4 * (*(_BYTE *)(a1 + v3 - 2) & 0xF)
                                            + (((int)*(unsigned __int8 *)(a1 + v3 - 1) >> 6) & 3)];
      v5 = *(_BYTE *)(a1 + v3 - 1) & 0x3F;
      v4 = v8 + 1;
      *(_BYTE *)(v4 + a3 - 1) = byte_40E0A0[v5];
    }
    while ( v3 < v7 );
    v5 = v15;
  }
  if ( v5 == 1 )
  {
    LOBYTE(v7) = *(_BYTE *)(v3 + a1);
    v9 = v4 + 1;
    *(_BYTE *)(v9 + a3 - 1) = byte_40E0A0[(v7 >> 2) & 0x3F];
    v10 = v9 + 1;
    *(_BYTE *)(v10 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(v3 + a1) & 3)];
    *(_BYTE *)(v10 + a3) = 61;
LABEL_8:
    v13 = v10 + 1;
    *(_BYTE *)(v13 + a3) = 61;
    v4 = v13 + 1;
    goto LABEL_9;
  }
  if ( v5 == 2 )
  {
    v11 = v4 + 1;
    *(_BYTE *)(v11 + a3 - 1) = byte_40E0A0[((int)*(unsigned __int8 *)(v3 + a1) >> 2) & 0x3F];
    v12 = (_BYTE *)(v3 + a1 + 1);
    LOBYTE(v6) = *v12;
    v10 = v11 + 1;
    *(_BYTE *)(v10 + a3 - 1) = byte_40E0A0[16 * (*(_BYTE *)(v3 + a1) & 3) + ((v6 >> 4) & 0xF)];
    *(_BYTE *)(v10 + a3) = byte_40E0A0[4 * (*v12 & 0xF)];
    goto LABEL_8;
  }
LABEL_9:
  *(_BYTE *)(v4 + a3) = 0;
  return sub_401030(a3);
}

似曾相识的感觉,跟进byte_40E0A0

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第6张图片

看到这串字符,这不就是base64加密么。。。

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第7张图片

base64解码

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第8张图片

但是除了base64加密,还有两个函数对字符串作了变换

这个函数对加密表进行变换,将 下标为 6 到14 的值 与 16 到24 的值进行调换

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第9张图片

int sub_401000()
{
  int result; // eax
  char v1; // cl

  for ( result = 6; result < 15; ++result )
  {
    v1 = byte_40E0AA[result];
    byte_40E0AA[result] = byte_40E0A0[result];
    byte_40E0A0[result] = v1;
  }
  return result;
}

这个函数对加密后的base64编码进行大小写转换

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第10张图片

int __cdecl sub_401030(const char *a1)
{
  __int64 v1; // rax
  char v2; // al

  v1 = 0i64;
  if ( strlen(a1) )
  {
    do
    {
      v2 = a1[HIDWORD(v1)];
      if ( v2 < 97 || v2 > 122 )
      {
        if ( v2 < 65 || v2 > 90 )
          goto LABEL_9;
        LOBYTE(v1) = v2 + 32;
      }
      else
      {
        LOBYTE(v1) = v2 - 32;
      }
      a1[HIDWORD(v1)] = v1;
LABEL_9:
      LODWORD(v1) = 0;
      ++HIDWORD(v1);
    }
    while ( HIDWORD(v1) < strlen(a1) );
  }
  return v1;
}

那么根据这个解题步骤就是先将 zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9 中的大写字母转小写,小写字母转大写,然后将调换的字母调换回来,再进行base64解密

输出被调换前的表,发现这只交换了大写字母的部分

char b[] = "ABCDEFGHIJ"    
           "KLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    for(i = 6; i < 15; i++ )   //互换表
   {
       char t = b[i];
       b[i] = b[i + 10];
       b[i + 10] = t;
   }

在这里插入图片描述

写出脚本

#include 
#include 
#include 
int main()
{
    int i,j;
   char a[] = "zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9";
  char flag[30];
   char b[] = "ABCDEFGHIJ"
              "KLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
   for(i = 0 ; i < strlen(a) ; i++)    //大小写互换
   {
       if(a[i] >= 'a' && a[i] <= 'z')
       {
           a[i] -= 32;
       }
       else if(a[i] >= 'A' && a[i] <= 'Z')
       {
           a[i] += 32;
       }

   }
   for(i = 0 ; i < strlen(a) ;i++)
   {
       if(a[i] >= 'A' && a[i] <= 'Z')   //只交换了大写字符
       {
           for(j = 6; j < 25 ; j++)
           {
               if(b[j] == a[i])
               {
                   if(j >= 6 && j < 15)
                        a[i] = b[j + 10];
                   else if(j >= 16 && j < 25)
                        a[i] = b[j - 10];
                    break;
               }
           }
       }
   }
  printf("%s\n",a);
   return 0;

}

运行得到结果 ZmxhZ3tiQXNlNjRfaDJzX2FfU3VycHJpc2V9

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第11张图片

然后找个网站解密

BUUCTF Reverse/[ACTF新生赛2020]usualCrypt_第12张图片

flag: flag{bAse64_h2s_a_Surprise}

你可能感兴趣的:(#,BUUCTF,Reverse)