CTF

嘉韦思杯

easy reverse

Posted by pic4xiu on April 1, 2019

Auth

An easy Windows re

Analysis

Run it and see what happened

直接运行后

            .
           _|_    ROBOTIC AUTHENTICATION SYSTEM
    /\/\  (. .)  /
    `||'   |#|
     ||__.-"-"-.___
     `---| . . |--.\
         | : : |  ,||,
         `..-..'  \/\/
          || ||
          || ||
         |__|__|

Please enter the first Password:

可知这是一个命令行的算法分析题,用peid查壳后没壳,我们直接拖到ida进行下一步分析,shift+F12后找到之前出现的关键字符串后查找引用找到

  if ( !strcmp(&Str1, Str2) )
  {
    puts("You passed level1!");
    sub_4015EA(0);
  }

在加上之前出现的strcpy(Str2, "r0b0RUlez!")我们直接输入r0b0RUlez!后出现

Please enter the second Password:

成功进入下一关,我们应该注意到这些字符串应该是程序在运行后生成的(在ida字符串中未找到,这题动态调试会更好一些,但鉴于本题不难,我们直接强行静态分析也不难)

这时候我很好奇之前函数为什么定义了那么多字符串,回去看看之前的puts(dword_40AD8C)就懂了,这串数已变,向上找找到了sub_401500(0)这函数。我们分析一下

int __cdecl sub_401500(signed int a1)
{
  int result; // eax@2
  _BYTE *i; // [sp+1Ch] [bp-Ch]@3

  if ( a1 > 9 )
  {
    for ( i = (_BYTE *)dword_40AD94; ; ++i )
    {
      result = dword_40ADA0;
      if ( (unsigned int)i >= dword_40ADA0 )
        break;
      *i ^= 1u;                                     //关键代码,将每位和1进行异或
    }
  }
  else
  {
    result = sub_401500(a1 + 1);
  }
  return result;
}

就是这个函数把我们的字符串进行了加工,我们接着sub_4015EA这个函数走,发现它在

    puts(dword_40AD90);
    dword_40ADA8 = 0x401619;
    __debugbreak();
    result = 0;

跳转之前改变了dword_40ADA8这个值,我们通过它跳到了sub_40157F

void __cdecl __noreturn sub_40157F(int a1)
{
  char v1; // [sp+18h] [bp-20h]@2
  int v2; // [sp+2Ch] [bp-Ch]@1

  v2 = *(_DWORD *)(*(_DWORD *)(a1 + 4) + 184);
  if ( v2 == dword_40ADA8 + 6 )
  {
    scanf("%20s", &v1);
    if ( !sub_401547(&v1, (_BYTE *)dword_40AD98) )
      puts(Str);
  }
  ExitProcess(0);
}

发现最后的函数为sub_401547

signed int __cdecl sub_401547(_BYTE *a1, _BYTE *a2)
{
  while ( *a2 != 2 )
  {
    if ( *a1 != (*a2 ^ 2) )
      return 1;
    ++a1;
    ++a2;
  }
  return 0;
}

输入字符串与u1nnf2lg和2的异或进行比对,最后两个字符串拼接即得flag:),本题不算难,找好跳转就能一步一步解决.