吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2238|回复: 1
收起左侧

[CTF] BUUCTF-[羊城杯 2020]easyre1

[复制链接]
骑着驴子追宝马 发表于 2021-11-13 16:54
BUUCTF-[羊城杯 2020]easyre1 首先下载好文件后查壳,无壳,直接用IDA打开int __cdecl main(int argc, const char **argv, const char **envp)
[Asm] 纯文本查看 复制代码
{
  int v3; // eax
  int v4; // eax
  int v5; // eax
  int result; // eax
  char Str[48]; // [rsp+20h] [rbp-60h] BYREF
  char Str1[64]; // [rsp+50h] [rbp-30h] BYREF
  char v9[64]; // [rsp+90h] [rbp+10h] BYREF
  char v10[64]; // [rsp+D0h] [rbp+50h] BYREF
  char Str2[60]; // [rsp+110h] [rbp+90h] BYREF
  int v12; // [rsp+14Ch] [rbp+CCh] 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)
[Asm] 纯文本查看 复制代码
{
  int v5; // esi
  int v6; // esi
  int v7; // esi
  int v8; // [rsp+34h] [rbp-1Ch]
  int v9; // [rsp+38h] [rbp-18h]
  int v11; // [rsp+48h] [rbp-8h]
  int i; // [rsp+4Ch] [rbp-4h]
  unsigned __int8 *v13; // [rsp+70h] [rbp+20h]
​
  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[1] = alphabet[v5 + cmove_bits(v13[1], 0, 4u)];
        a3[2] = alphabet[cmove_bits(v13[1], 4u, 2u)];
        a3[3] = '=';
      }
      else if ( v11 == 2 )
      {
        a3[1] = alphabet[cmove_bits(*v13, 6u, 2u)];
        a3[2] = '=';
        a3[3] = '=';
      }
    }
    else
    {
      v6 = cmove_bits(*v13, 6u, 2u);
      a3[1] = alphabet[v6 + cmove_bits(v13[1], 0, 4u)];
      v7 = cmove_bits(v13[1], 4u, 2u);
      a3[2] = alphabet[v7 + cmove_bits(v13[2], 0, 6u)];
      a3[3] = alphabet[v13[2] & 0x3F];
    }
    a3 += 4;
    v13 += 3;
  }
  if ( a4 )
    *a4 = v8;
  return 0i64;
}


跟进去发现是一个base64加密,alphabet跟进发现是码表


2.进入encode_two __int64 __fastcall encode_two(const char *a1, int a2, char *a3, int *a4)
[Asm] 纯文本查看 复制代码
{
  char *Source; // [rsp+40h] [rbp+10h]
  char *v6; // [rsp+50h] [rbp+20h]
&#8203;
  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位调换位置


3.进入encode_three_int64 __fastcall encode_three(const char *a1, int a2, char *a3, int *a4)
[Asm] 纯文本查看 复制代码
{
  char v5; // [rsp+Fh] [rbp-11h]
  int i; // [rsp+14h] [rbp-Ch]
  char *v7; // [rsp+18h] [rbp-8h]
  const char *v8; // [rsp+30h] [rbp+10h]
&#8203;
  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的解密 ,附上脚本
[Python] 纯文本查看 复制代码
import base64
data = "BjYjM2Mjk4NzMR1dIVHs2NzJjY0MTEzM2VhMn0=zQ3NzhhMzhlOD"
&#8203;
raw = ["0" for _ in range(38)]
&#8203;
raw[0: 13] = data[13: 26]
raw[13: 26] = data[39: 52]
raw[26: 39] = data[0: 13]
raw[39: 52] = data[26: 39]
&#8203;
print(base64.b64decode("".join(raw).encode()).decode())得到flagGWHT{672cc4778a38e80cb362987341133ea2}

免费评分

参与人数 2威望 +1 吾爱币 +21 热心值 +2 收起 理由
ctf101 + 1 + 1 谢谢@Thanks!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ctf101 发表于 2021-12-26 15:20
萌新,学习一下大佬的逆向思路
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-25 14:00

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表