首页
社区
课程
招聘
[原创]KCTF2021 第二题 write up
发表于: 2021-5-12 01:05 5563

[原创]KCTF2021 第二题 write up

2021-5-12 01:05
5563

系统 : win10 64bit \ Windows xp
程序 : pzcrackme.exe
要求 : 求flag
使用工具 :ida pro \ ollydbg \ 微步云沙箱

这题有不少迷惑人的手段,所以需要尽可能把程序流程分析清楚,ida中main函数如下:

将程序上传到云沙箱里看下,发现有tls_callback存在,可能是有反调试机制;不过先将程序运行起在等候输入的时候od附加就可以正常调试。

程序需要将一个matrix填满:

可以看到使用switch语句选择方向:

手动填写一下:

接下来构造相应的输入了,这里要注意的一个坑点是一个输入控制两次行动而非一次:

做py如下:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Tmp_ch_in_input; // al
  int index_of_str; // esi
  int INDEX_01234567; // ecx
  int v7; // edx
  int sum_index; // eax
  unsigned int column; // ecx
  int choice; // eax
  signed int SIGNAL; // edx
  int T2; // eax
  char *a_pointer_of_matrix; // eax
  char *MATRIX; // eax
  int A_VALUE_SHOULD_BE_ZERO; // edx
  char *v16; // ecx
  int T1; // eax
  int T4; // eax
  int T3; // eax
  int v20; // [esp+1Ch] [ebp-60h]
  unsigned int row; // [esp+20h] [ebp-5Ch]
  unsigned int v22; // [esp+24h] [ebp-58h]
  char _0x30; // [esp+2Bh] [ebp-51h]
  int NUM_0x24; // [esp+2Ch] [ebp-50h]
  char STR[76]; // [esp+30h] [ebp-4Ch]
 
  sub_40AD70();
  sub_4AF840(&dword_4B8860, "Input your code: ");
  sub_4B0AB0(&dword_4B8680, STR);
  if ( strlen(STR) <= 0x30 )                    // len(str) <= 0x30
  {
    Tmp_ch_in_input = STR[0];
    if ( STR[0] )                               // str[0] != null
    {
      index_of_str = 0;
      row = 0;
      v22 = 0;
      NUM_0x24 = dword_4B7020;                  // 24 00 00 00
      _0x30 = a0123456789abcd[0];               // .data:004B7040 30 31 32 33 34 35+a0123456789abcd db '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',0
While_start:
      if ( NUM_0x24 > 0 )
      {
        INDEX_01234567 = 0;
        if ( _0x30 == Tmp_ch_in_input )         // assert str[0] == 0x30
        {
other_start:
          v7 = (index_of_str + INDEX_01234567 / 6) % 6;
          sum_index = INDEX_01234567 + index_of_str;
          column = v22;
          v20 = v7;
          choice = 5 - sum_index % 6;           // 5 - (sum_index % 6)
          SIGNAL = 0;
          while ( 1 )
          {
            switch ( choice )
            {
              case 1:
                ++column;                       // ++column
                break;
              case 2:
                T1 = (row++ & 1) == 0;          // row++
                column += T1;                   // column += (row%2?0:1)
                break;
              case 3:
                T2 = (row++ & 1) != 0;          // row++
                column -= T2;                   // column -= (row%2?1:0)
                break;
              case 4:
                --column;                       // --column
                break;
              case 5:
                T3 = (row-- & 1) != 0;          // row--
                column -= T3;                   // column -= (row%2?1:0)
                break;
              default:
                T4 = (row-- & 1) == 0;          // row--
                column += T4;                   // column += (row%2?0:1)
                break;
            }
            if ( column > 9 )                   // ten columns
              break;                            // try again
            if ( row > 8 )                      // 9 rows
              break;                            // try again
            a_pointer_of_matrix = &matrix[10 * row + column];
            if ( *a_pointer_of_matrix )
              break;                            // try again
            *a_pointer_of_matrix = 1;
            if ( SIGNAL == 1 )                  // skip this at frist time
            {
              ++index_of_str;
              v22 = column;
              Tmp_ch_in_input = STR[index_of_str];
              if ( Tmp_ch_in_input )
                goto While_start;               // back to start
              goto check;
            }
            SIGNAL = 1;
            choice = v20;
          }
        }
        else                                    // _0x30 != Tmp_ch_in_input
        {
          while ( NUM_0x24 != ++INDEX_01234567 )
          {
            if ( a0123456789abcd[INDEX_01234567] == Tmp_ch_in_input )// .data:004B7040 30 31 32 33 34 35+a0123456789abcd db '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',0
              goto other_start;
          }
        }
      }
    }
    else
    {
check:
      MATRIX = matrix;
      A_VALUE_SHOULD_BE_ZERO = 0;
      do                                        // check matrix
      {
        v16 = MATRIX + 10;
        do
          A_VALUE_SHOULD_BE_ZERO += *MATRIX++ < 1u;// all element in matrix have not to set as zero
        while ( v16 != MATRIX );
      }
      while ( &unk_4B70DA != v16 );
      if ( !A_VALUE_SHOULD_BE_ZERO )
      {
        printf_4ABF30(&dword_4B8860, "Good job!", 9);
        afterprintf_4AD980(&dword_4B8860);
        return 0;
      }
    }
  }
  printf_4ABF30(&dword_4B8860, "Try again...", 12);
  afterprintf_4AD980(&dword_4B8860);
  return 0;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Tmp_ch_in_input; // al
  int index_of_str; // esi
  int INDEX_01234567; // ecx
  int v7; // edx
  int sum_index; // eax
  unsigned int column; // ecx
  int choice; // eax
  signed int SIGNAL; // edx
  int T2; // eax
  char *a_pointer_of_matrix; // eax
  char *MATRIX; // eax
  int A_VALUE_SHOULD_BE_ZERO; // edx
  char *v16; // ecx
  int T1; // eax
  int T4; // eax
  int T3; // eax
  int v20; // [esp+1Ch] [ebp-60h]
  unsigned int row; // [esp+20h] [ebp-5Ch]
  unsigned int v22; // [esp+24h] [ebp-58h]
  char _0x30; // [esp+2Bh] [ebp-51h]
  int NUM_0x24; // [esp+2Ch] [ebp-50h]
  char STR[76]; // [esp+30h] [ebp-4Ch]
 
  sub_40AD70();
  sub_4AF840(&dword_4B8860, "Input your code: ");
  sub_4B0AB0(&dword_4B8680, STR);
  if ( strlen(STR) <= 0x30 )                    // len(str) <= 0x30
  {
    Tmp_ch_in_input = STR[0];
    if ( STR[0] )                               // str[0] != null
    {
      index_of_str = 0;
      row = 0;
      v22 = 0;
      NUM_0x24 = dword_4B7020;                  // 24 00 00 00
      _0x30 = a0123456789abcd[0];               // .data:004B7040 30 31 32 33 34 35+a0123456789abcd db '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',0
While_start:
      if ( NUM_0x24 > 0 )
      {
        INDEX_01234567 = 0;
        if ( _0x30 == Tmp_ch_in_input )         // assert str[0] == 0x30
        {
other_start:
          v7 = (index_of_str + INDEX_01234567 / 6) % 6;
          sum_index = INDEX_01234567 + index_of_str;
          column = v22;
          v20 = v7;
          choice = 5 - sum_index % 6;           // 5 - (sum_index % 6)
          SIGNAL = 0;
          while ( 1 )
          {
            switch ( choice )
            {
              case 1:
                ++column;                       // ++column
                break;
              case 2:
                T1 = (row++ & 1) == 0;          // row++
                column += T1;                   // column += (row%2?0:1)
                break;
              case 3:
                T2 = (row++ & 1) != 0;          // row++
                column -= T2;                   // column -= (row%2?1:0)
                break;
              case 4:
                --column;                       // --column
                break;
              case 5:
                T3 = (row-- & 1) != 0;          // row--
                column -= T3;                   // column -= (row%2?1:0)
                break;
              default:
                T4 = (row-- & 1) == 0;          // row--
                column += T4;                   // column += (row%2?0:1)
                break;
            }
            if ( column > 9 )                   // ten columns
              break;                            // try again
            if ( row > 8 )                      // 9 rows
              break;                            // try again
            a_pointer_of_matrix = &matrix[10 * row + column];
            if ( *a_pointer_of_matrix )
              break;                            // try again
            *a_pointer_of_matrix = 1;
            if ( SIGNAL == 1 )                  // skip this at frist time
            {
              ++index_of_str;
              v22 = column;
              Tmp_ch_in_input = STR[index_of_str];
              if ( Tmp_ch_in_input )
                goto While_start;               // back to start
              goto check;
            }
            SIGNAL = 1;
            choice = v20;
          }
        }
        else                                    // _0x30 != Tmp_ch_in_input
        {
          while ( NUM_0x24 != ++INDEX_01234567 )
          {
            if ( a0123456789abcd[INDEX_01234567] == Tmp_ch_in_input )// .data:004B7040 30 31 32 33 34 35+a0123456789abcd db '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',0
              goto other_start;
          }
        }
      }
    }
    else
    {
check:
      MATRIX = matrix;
      A_VALUE_SHOULD_BE_ZERO = 0;
      do                                        // check matrix
      {
        v16 = MATRIX + 10;
        do
          A_VALUE_SHOULD_BE_ZERO += *MATRIX++ < 1u;// all element in matrix have not to set as zero
        while ( v16 != MATRIX );
      }
      while ( &unk_4B70DA != v16 );
      if ( !A_VALUE_SHOULD_BE_ZERO )
      {
        printf_4ABF30(&dword_4B8860, "Good job!", 9);
        afterprintf_4AD980(&dword_4B8860);
        return 0;
      }
    }
  }
  printf_4ABF30(&dword_4B8860, "Try again...", 12);
  afterprintf_4AD980(&dword_4B8860);
  return 0;
}
 
53 01 01 00 00 01 00 00 01 01
01 01 01 00 01 00 00 01 00 00
01 01 01 00 01 01 01 01 01 00
00 01 01 00 01 00 00 01 00 00
00 00 01 00 00 01 00 00 01 01
01 01 00 01 01 01 00 01 00 01
00 00 01 01 01 01 00 01 00 01
00 01 01 00 00 01 00 01 00 01
00 00 00 01 00 00 01 01 00 00
53 01 01 00 00 01 00 00 01 01
01 01 01 00 01 00 00 01 00 00
01 01 01 00 01 01 01 01 01 00
00 01 01 00 01 00 00 01 00 00
00 00 01 00 00 01 00 00 01 01
01 01 00 01 01 01 00 01 00 01
00 00 01 01 01 01 00 01 00 01
00 01 01 00 00 01 00 01 00 01
00 00 00 01 00 00 01 01 00 00
while ( 1 )
{
  switch ( choice )
  {
    case 1:
      ++column;                       // ++column
      break;
    case 2:
      T1 = (row++ & 1) == 0;          // row++
      column += T1;                   // column += (row%2?0:1)
      break;
    case 3:
      T2 = (row++ & 1) != 0;          // row++
      column -= T2;                   // column -= (row%2?1:0)
      break;
    case 4:
      --column;                       // --column
      break;
    case 5:
      T3 = (row-- & 1) != 0;          // row--
      column -= T3;                   // column -= (row%2?1:0)
      break;
    default:
      T4 = (row-- & 1) == 0;          // row--
      column += T4;                   // column += (row%2?0:1)
      break;
  }
while ( 1 )
{
  switch ( choice )
  {
    case 1:
      ++column;                       // ++column
      break;
    case 2:
      T1 = (row++ & 1) == 0;          // row++
      column += T1;                   // column += (row%2?0:1)
      break;
    case 3:

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//