首页
社区
课程
招聘
[原创]BUUCTF逆向题:[ACTF新生赛2020]Oruga
2022-3-27 17:33 8828

[原创]BUUCTF逆向题:[ACTF新生赛2020]Oruga

2022-3-27 17:33
8828

1.基本信息探查:

1.EXEinfo:

2.运行一下:

2.IDA分析:

1.主函数分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
__int64 __fastcall main(int a1, char **a2, char **a3)
{
  __int64 result; // rax
  int i; // [rsp+0h] [rbp-40h]
  char s1[6]; // [rsp+4h] [rbp-3Ch] BYREF
  char s2[6]; // [rsp+Ah] [rbp-36h] BYREF
  char s[40]; // [rsp+10h] [rbp-30h] BYREF
  unsigned __int64 v8; // [rsp+38h] [rbp-8h]
 
  v8 = __readfsqword(0x28u);
  memset(s, 0, 0x19uLL);
  printf("Tell me the flag:");
  scanf("%s", s);
  strcpy(s2, "actf{");
  for ( i = 0; i <= 4; ++i )
    s1[i] = s[i];
  s1[5] = 0;
  if ( !strcmp(s1, s2) )
  {
    if ( (unsigned __int8)sub_78A(s) )
      printf("That's True Flag!");
    else
      printf("don't stop trying...");
    result = 0LL;
  }
  else
  {
    printf("Format false!");
    result = 0LL;
  }
  return result;
}

第一个for循环是将输入的字串的前5个字符拿出来和“actf{”进行比较,配对成功则调用sub_78A() 函数

2.sub_78A分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
_BOOL8 __fastcall sub_78A(__int64 a1)
{
  int v2; // [rsp+Ch] [rbp-Ch]
  int v3; // [rsp+10h] [rbp-8h]
  int v4; // [rsp+14h] [rbp-4h]
 
  v2 = 0;
  v3 = 5;
  v4 = 0;
  while ( byte_201020[v2] != 0x21 )
  {
    v2 -= v4;
    if ( *(_BYTE *)(v3 + a1) != 'W' || v4 == -16 )
    {
      if ( *(_BYTE *)(v3 + a1) != 'E' || v4 == 1 )
      {
        if ( *(_BYTE *)(v3 + a1) != 'M' || v4 == 16 )
        {
          if ( *(_BYTE *)(v3 + a1) != 'J' || v4 == -1 )
            return 0LL;
          v4 = -1;                              // J表示左移
        }
        else
        {
          v4 = 16;                              // M表示下移
        }
      }
      else
      {
        v4 = 1;                                 // E表示右移
      }
    }
    else
    {
      v4 = -16;                                 // W表示上移
    }
    ++v3;
    while ( !byte_201020[v2] )                  // 当前值为0则继续循环
    {
      if ( v4 == -1 && (v2 & 0xF) == 0 )        // 当前在最左边一列的时候,不能过左移
        return 0LL;
      if ( v4 == 1 && v2 % 16 == 15 )           // 当前在最右边一列的时候,不能够右移
        return 0LL;
      if ( v4 == 16 && (unsigned int)(v2 - 240) <= 0xF )// 在最后一行时,不能下移
        return 0LL;
      if ( v4 == -16 && (unsigned int)(v2 + 15) <= 0x1E )// 在第一行,不能上移
        return 0LL;
      v2 += v4;                  // 当值为0就一直移动,但要注意退出循环时一定已经处于不满
    }                            // 的状态所以对于走迷宫来说时多移动了一次,在12行做了一    
  }                              // 个往后退一步的处理
  return *(_BYTE *)(v3 + a1) == 125;
}

这里看到一个迷宫题的特征就是13到19行的四个字母,发现这个点后就去找地图,发现byte_201020里面的值:

 

 

通过v4要么加16,要么加1,和这个数组的大小为256可知,这是张16*16的地图,直接去Hex窗口里看:

 

 

大概是个这么个走法:

 

 

转换成字母就是:MEWEMEWJMEWJM
flag为:flag{MEWEMEWJMEWJM}


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞3
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回