首页
社区
课程
招聘
[原创]流浪者writeup
发表于: 2019-3-21 13:01 2981

[原创]流浪者writeup

2019-3-21 13:01
2981

搜索字符串shift+F12

搜索字符串.jpg

发现可疑字符串KanXueCTF2019JustForhappy,双击进入

选中字符串,按X找到这个字符串被交叉引用的地址
分析1.jpg
分析2.jpg

双击004035c0进入,F5查看伪代码

双击sub_4017F0进入a1的交叉引用地址
分析3.jpg

可以看到以下伪代码

这个算法比较简单,直接引用原代码编写解密脚本

  int __cdecl sub_4017F0(int a1)
  {
    int 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;
  }
  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] > 57 || Str[i] < 48 )
      {
        if ( Str[i] > 'z' || Str[i] < 'a' )        //h,r变化进制,编码
        {
          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);
  }
  content = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"
  flag="KanXueCTF2019JustForhappy"
  position =[]
  v5=0
  for i in flag:
          for j in range(0,len(content)):
              if i==content[j]:
                  position.append(j)

  print(position)

  for i in range(0,len(content)):
      num=ord(content[i])
      if num>57 or num <97:
          if num>122 or num <97:
              pass
          else:
              v5=num-29
      else:
          v5=num-48
      if v5==48:
          print(content[i])
  • 搜索字符串shift+F12

    搜索字符串.jpg

  • 发现可疑字符串KanXueCTF2019JustForhappy,双击进入

  • 选中字符串,按X找到这个字符串被交叉引用的地址
    分析1.jpg
    分析2.jpg

  • 双击004035c0进入,F5查看伪代码

      int __cdecl sub_4017F0(int a1)
      {
        int 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;
      }
    
    • 分析可知:我们输入的passwd字符串保存到a1指向的地址,经过转换得到KanXueCTF2019JustForhappy
    • 我们现在需要了解转换方式,然后逆向出解密算法
  • 双击sub_4017F0进入a1的交叉引用地址
    分析3.jpg

  • 可以看到以下伪代码

      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] > 57 || Str[i] < 48 )
          {
            if ( Str[i] > 'z' || Str[i] < 'a' )        //h,r变化进制,编码
            {
              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);
      }
    
  • 这个算法比较简单,直接引用原代码编写解密脚本

      content = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"
      flag="KanXueCTF2019JustForhappy"
      position =[]
      v5=0
      for i in flag:
              for j in range(0,len(content)):
                  if i==content[j]:
                      position.append(j)
    
      print(position)
    
      for i in range(0,len(content)):
          num=ord(content[i])
          if num>57 or num <97:
              if num>122 or num <97:
                  pass
              else:
                  v5=num-29
          else:
              v5=num-48
          if v5==48:
              print(content[i])
    
  • 解出flag : j0rXI4bTeustBiIGHeCF70DDM

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2019-3-26 17:20 被shavchen编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//