BUUCTF Reverse/reverse3

BUUCTF Reverse/reverse3

在这里插入图片描述
在这里插入图片描述

查看文件属性,没有加壳,而且是32位程序

在这里插入图片描述

用IDA32位打开,找到main函数,然后分析代码

__int64 __usercall main_0@<edx:eax>(int a1@<ebx>, int a2@<edi>, int a3@<esi>)
{
  int v3; // eax
  const char *v4; // eax
  size_t v5; // eax
  int v6; // edx
  __int64 v7; // ST08_8
  signed int j; // [esp+DCh] [ebp-ACh]
  signed int i; // [esp+E8h] [ebp-A0h]
  signed int v11; // [esp+E8h] [ebp-A0h]
  char Dest[108]; // [esp+F4h] [ebp-94h]
  char Str; // [esp+160h] [ebp-28h]
  char v14; // [esp+17Ch] [ebp-Ch]

  for ( i = 0; i < 100; ++i )
  {
    if ( (unsigned int)i >= 0x64 )
      j____report_rangecheckfailure(a1, a2, a3);
    Dest[i] = 0;
  }
  sub_41132F("please enter the flag:");
  sub_411375("%20s", &Str);
  v3 = j_strlen(&Str);
  v4 = (const char *)sub_4110BE((int)&Str, v3, (int)&v14);
  strncpy(Dest, v4, 40u);
  v11 = j_strlen(Dest);
  for ( j = 0; j < v11; ++j )
    Dest[j] += j;
  v5 = j_strlen(Dest);
  if ( !strncmp(Dest, Str2, v5) )
    sub_41132F("rigth flag!\n");
  else
    sub_41132F("wrong flag!\n");
  HIDWORD(v7) = v6;
  LODWORD(v7) = 0;
  return v7;
}

来一点一点分析代码,这里输入flag然后通过 sub_4110BE() 函数进行变换

sub_41132F("please enter the flag:");
  sub_411375("%20s", &Str);
  v3 = j_strlen(&Str);
  v4 = (const char *)sub_4110BE((int)&Str, v3, (int)&v14);

然后经过for循环每一位依次减去 i 的值,最后与Str2比较

for ( j = 0; j < v11; ++j )
    Dest[j] += j;
  v5 = j_strlen(Dest);
  if ( !strncmp(Dest, Str2, v5) )
    sub_41132F("rigth flag!\n");
  else
    sub_41132F("wrong flag!\n");

跟进查看Str2的值

在这里插入图片描述

再跟进上面那个变换函数 sub_4110BE()

void *__cdecl sub_411AB0(char *a1, unsigned int a2, int *a3)
{
  int v4; // STE0_4
  int v5; // STE0_4
  int v6; // STE0_4
  int v7; // [esp+D4h] [ebp-38h]
  signed int i; // [esp+E0h] [ebp-2Ch]
  unsigned int v9; // [esp+ECh] [ebp-20h]
  int v10; // [esp+ECh] [ebp-20h]
  signed int v11; // [esp+ECh] [ebp-20h]
  void *Dst; // [esp+F8h] [ebp-14h]
  char *v13; // [esp+104h] [ebp-8h]

  if ( !a1 || !a2 )
    return 0;
  v9 = a2 / 3;
  if ( (signed int)(a2 / 3) % 3 )
    ++v9;
  v10 = 4 * v9;
  *a3 = v10;
  Dst = malloc(v10 + 1);
  if ( !Dst )
    return 0;
  j_memset(Dst, 0, v10 + 1);
  v13 = a1;
  v11 = a2;
  v7 = 0;
  while ( v11 > 0 )
  {
    byte_41A144[2] = 0;
    byte_41A144[1] = 0;
    byte_41A144[0] = 0;
    for ( i = 0; i < 3 && v11 >= 1; ++i )
    {
      byte_41A144[i] = *v13;
      --v11;
      ++v13;
    }
    if ( !i )
      break;
    switch ( i )
    {
      case 1:
        *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
        v4 = v7 + 1;
        *((_BYTE *)Dst + v4++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
        *((_BYTE *)Dst + v4++) = aAbcdefghijklmn[64];
        *((_BYTE *)Dst + v4) = aAbcdefghijklmn[64];
        v7 = v4 + 1;
        break;
      case 2:
        *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
        v5 = v7 + 1;
        *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
        *((_BYTE *)Dst + v5++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
        *((_BYTE *)Dst + v5) = aAbcdefghijklmn[64];
        v7 = v5 + 1;
        break;
      case 3:
        *((_BYTE *)Dst + v7) = aAbcdefghijklmn[(signed int)(unsigned __int8)byte_41A144[0] >> 2];
        v6 = v7 + 1;
        *((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[1] & 0xF0) >> 4) | 16 * (byte_41A144[0] & 3)];
        *((_BYTE *)Dst + v6++) = aAbcdefghijklmn[((byte_41A144[2] & 0xC0) >> 6) | 4 * (byte_41A144[1] & 0xF)];
        *((_BYTE *)Dst + v6) = aAbcdefghijklmn[byte_41A144[2] & 0x3F];
        v7 = v6 + 1;
        break;
    }
  }
  *((_BYTE *)Dst + v7) = 0;
  return Dst;
}

再看一下这个aAbcdefghijklmn[]数组里的值

在这里插入图片描述

根据base64编码的定义,再加上这个函数里面有分组填充而且最后有 = 号,推测这个是base64编码

在这里插入图片描述

下面写出脚本就好

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
    char flag[] = "e3nifIH9b_C@n@dH"; // 十六位
    for(int i = 0 ; i < strlen(flag) ; i ++)
    {
        flag[i] -= i;
    }
    printf("%s\n",flag);
    return 0;

}

先运行出结果

在这里插入图片描述

然后去找一个 base64解码

在这里插入图片描述

得到flag:flag{i_l0ve_you}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ofo300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值