zoukankan      html  css  js  c++  java
  • 流浪者-CTF

    0x01

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

    输入错误后程序会退出

    0x02

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

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

    那么我们看到了pass!,而且还有两串可疑的字符串,所以我们去看看

    BOOL sub_401770()
    {
      HANDLE hProcess; // ST5C_4
    
      MessageBoxA(0, "pass!", &Caption, 0);
      hProcess = GetCurrentProcess();
      return TerminateProcess(hProcess, 0);
    }
    

    这段代码就是返回pass的,所以我们看看谁调用了这段代码

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

    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)]赋值给了Str1

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

    下标怎么来的呢?

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

    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

  • 相关阅读:
    细数ASP.NET MVC框架的7大顶级功能
    Ubuntu 10.10更新源列表
    使用iTunes将任意mp3文件转为iPhone铃声
    简单5步,在新浪微博上关联多个博客
    在windows 7 建立一个弹出光驱的快捷方式
    中国人民太伟大了!
    Ubuntu 10.10
    du 熊填数字
    WPF学习02——XAML编译
    Debugging WPF data bindings
  • 原文地址:https://www.cnblogs.com/Jleixin/p/13069837.html
Copyright © 2011-2022 走看看