流浪者-CTF

0x01

拿到题目后是一个exe程序,首先看一下运行结果,那么一共有两种结果,一种是若是密码为空,则提示从新输入,若是输入错误,则提示加油,以下图:python

输入错误后程序会退出数组

0x02

放进IDA进行静态分析,看下主要代码是如何运行app

进入之后首先字符串查找 shift+F12,结果如图:this

那么咱们看到了pass!,并且还有两串可疑的字符串,因此咱们去看看code

BOOL sub_401770()
{
  HANDLE hProcess; // ST5C_4

  MessageBoxA(0, "pass!", &Caption, 0);
  hProcess = GetCurrentProcess();
  return TerminateProcess(hProcess, 0);
}

这段代码就是返回pass的,因此咱们看看谁调用了这段代码blog

通过查找是我箭头处调用了这段代码,因此经过分析,咱们知道,经过字符串比较,而后决定是返回sub_401770()—>PASS!仍是sub_4017B0()—>错了,加油!v8

BOOL __cdecl sub_4017F0(int a1)
{
  BOOL result; // eax
  char Str1[28]; // [esp+D8h] [ebp-24h]
  int v3; // [esp+F4h] [ebp-8h]
  int v4; // [esp+F8h] [ebp-4h]

  v4 = 0;
  v3 = 0;
  while ( *(_DWORD *)(a1 + 4 * v4) < 62 && *(_DWORD *)(a1 + 4 * v4) >= 0 )
  {
    Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)];
    ++v4;
  }
  Str1[v4] = 0;
  if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") )
    result = sub_401770();
  else
    result = sub_4017B0();
  return result;
}

因此咱们知道它应该是将Str1和"KanXueCTF2019JustForhappy"做比较,因此咱们就逆着去看看这个Str1怎么来的,向上看是这段代码:字符串

while ( *(_DWORD *)(a1 + 4 * v4) < 62 && *(_DWORD *)(a1 + 4 * v4) >= 0 )
  {
    Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)];
    ++v4;
  }

很容易看出,是将aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)]赋值给了Str1io

那么知道复制的字符串数组了,接下来要解决的就是下标问题了,下标解决了,那么也就知道了Str1了class

下标怎么来的呢?

这段就是计算下标,而后进行赋值的关键代码

int __thiscall sub_401890(CWnd *this)
{
  struct CString *v1; // ST08_4
  CWnd *v2; // eax
  int v3; // eax
  int v5[26]; // [esp+4Ch] [ebp-74h]
  int i; // [esp+B4h] [ebp-Ch]
  char *Str; // [esp+B8h] [ebp-8h]
  CWnd *v8; // [esp+BCh] [ebp-4h]

  v8 = this;
  v1 = (CWnd *)((char *)this + 100);
  v2 = CWnd::GetDlgItem(this, 1002);
  CWnd::GetWindowTextA(v2, v1);
  v3 = sub_401A30((char *)v8 + 100);
  Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v3);
  if ( !strlen(Str) )
    return CWnd::MessageBoxA(v8, &byte_4035DC, 0, 0);
  for ( i = 0; Str[i]; ++i )
  {
    if ( Str[i] > '9' || Str[i] < '0' )
    {
      if ( Str[i] > 'z' || Str[i] < 'a' )
      {
        if ( Str[i] > 'Z' || Str[i] < 'A' )
          sub_4017B0();
        else
          v5[i] = Str[i] - 29;
      }
      else
      {
        v5[i] = Str[i] - 87;
      }
    }
    else
    {
      v5[i] = Str[i] - 48;
    }
  }
  return sub_4017F0((int)v5);
}

经过分析就是将咱们输入的字符串进行了减法运算,而后赋值给Str1,再将Str1与"KanXueCTF2019JustForhappy"做比较,因此咱们能够将"KanXueCTF2019JustForhappy"进行逆运算,获得Str1,就是得到flag

0x03

下面是我编写的脚本:

str1 = 'KanXueCTF2019JustForhappy'
str2 = 'abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ'
flag = ''
for i in range(int(len(str1))):
    for j in range(int(len(str2))):
        if str1[i] == str2[j]:
            if((j + 48 >= 48 ) and (j + 48 <= 57 )):
                flag += chr(j + 48)
            elif((j + 87 >= 97 ) and (j + 87 <= 122 )):
                flag += chr(j + 87)
            elif((j + 29 >= 65 ) and (j + 29 <= 90 )):
                flag += chr(j + 29)

print(flag)

运行结果:

拿到flag

相关文章
相关标签/搜索