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

BUUCTF - re - [ACTF新生赛2020]Oruga

BUUCTF - re - Oruga下载好后直接用ida就可以打开,找到main函数 _int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
__int64 result; // rax
__int64 v4; //
char v5; //
char s2; //
char s; //
unsigned __int64 v8; //

v8 = __readfsqword(0x28u);
memset(s, 0, 0x19uLL);
printf("Tell me the flag:", 0LL);
scanf("%s", s);
strcpy(s2, "actf{");
LODWORD(v4) = 0;
while ( (signed int)v4 <= 4 )               // v4为8字节,低4位存储索引,高四位存储值
{
    *((_BYTE *)&v4 + (signed int)v4 + 4) = s[(signed int)v4];
    LODWORD(v4) = v4 + 1;
}
v5 = 0;
if ( !strcmp((const char *)&v4 + 4, s2) )   // 比较flag头
{
    if ( (unsigned __int8)sub_78A((__int64)s) )
      printf("That's True Flag!", s2, v4);
    else
      printf("don't stop trying...", s2, v4);
    result = 0LL;
}

通过这些代码,我们知道flag的头为actf{进入到主要的函数分析sub_78Awhile ( byte_201020 !=0x21 )
{
    v2 -= v4;                                 // 当前坐标
                                                // 减去上次移动多移动的一次
    if ( *(_BYTE *)(v3 + a1) != 87 || v4 == -16 )
    {
      if ( *(_BYTE *)(v3 + a1) != 69 || v4 == 1 )
      {
      if ( *(_BYTE *)(v3 + a1) != 77 || v4 == 16 )
      {
          if ( *(_BYTE *)(v3 + a1) != 74 || v4 == -1 )
            return 0LL;                         // 判断最后一位是否为'}'
                                                //
          v4 = -1;                              // a1='J'向左移动
      }
      else
      {
          v4 = 16;                              // a1='M'向下
      }
      }
      else
      {
      v4 = 1;                                 // a1='E'向右
      }
    }
    else
    {
      v4 = -16;                                 // a1='W'向上移动
    }

这个函数其实就是一个迷宫,16*16,这个迷宫并不是很复杂可以直接手动写向下移动:M向左移动:J向上移动:E向右移动:W外层while循环,就是到0x21时停止,v2为当前位置,v3从输入的第六个字符开始遍历数组,v4实际是对v2位置的移动。第二处,用了个循环,if条件判断的是位置是否到达边界,越界退出整个迷宫就是用WEMJ控制移动,0可以移动(一直移动),到达非0位置停止,返回上一位置。左上角为起点,0x21为终点。手动解迷宫别人写的脚本:
#include <stdio.h>
char maze = {
    0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x23, 0x23, 0x23,
    0x00, 0x00, 0x00, 0x23, 0x23, 0x00, 0x00, 0x00, 0x4F, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x4F, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x4C, 0x00, 0x4F, 0x4F, 0x00, 0x4F, 0x4F, 0x00, 0x50, 0x50, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x4C, 0x00, 0x4F, 0x4F, 0x00, 0x4F, 0x4F, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x4C, 0x4C, 0x00, 0x4F, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x4F, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,
    0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x4D, 0x4D, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x4D, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x45, 0x45,
    0x00, 0x00, 0x00, 0x30, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x45,
    0x54, 0x54, 0x54, 0x49, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
    0x00, 0x54, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
    0x00, 0x54, 0x00, 0x49, 0x00, 0x4D, 0x00, 0x4D, 0x00, 0x4D, 0x21, 0x00, 0x00, 0x00, 0x45, 0x45
};
int main(void)
{
    int i, j;
    for (i = 0; i < 16; i++)
    {
      for (j = 0; j < 16; j++)
      {
            if (i == 0 && j == 0)
                printf("☆");//起点
            else if (maze == 0)
                printf("□");//路
            else if (maze == 0x21)
                printf("★");//终点
            else printf("■"); //障碍物
      }
      putchar('\n');
    }
} flag{MEWEMEWJMEWJM}

Hmily 发表于 2021-11-15 11:39

代码用代码框处理一下吧,或者用markdown写,这样会好看一些。

jsncy 发表于 2021-11-16 11:34

写的不错,下次继续

suxiaosu67 发表于 2021-11-18 16:14

向大佬学习
页: [1]
查看完整版本: BUUCTF - re - [ACTF新生赛2020]Oruga