首页
论坛
专栏
课程

[分享]流浪者(kxctf2019cm1)wp

2019-3-14 11:59 408

[分享]流浪者(kxctf2019cm1)wp

2019-3-14 11:59
408

前话

作为逆向的真*萌新,感到吃不消。看雪CTF的题目质量都非常高,能够学习到很多东西。以前都只是默默关注,当我开始尝试后发现,只要尽心尽力了,就算解不出来,也会收获很多。看到这么多大佬蹭蹭蹭往上升,我躲在角落里瑟瑟发抖。

试探程序

先把程序运行起来,随便输入
图片描述

 

IDA载入,搜索字符串,发现关键字
图片描述
跟随字符串来到关键函数,部分函数名自定义了。

int __thiscall sub_401890(CWnd *this)
{
        ...
  CWnd::GetWindowTextA(v2, v1);                 // 获取用户输入
  v3 = sub_401A30(v8 + 100);
  Str = CString::GetBuffer((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 check(v5);                             // 关键校验函数
}

check函数:

int __cdecl check(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 ( *(a1 + 4 * v4) < 62 && *(a1 + 4 * v4) >= 0 )
  {
    Str1[v4] = aAbcdefghiabcde[*(a1 + 4 * v4)]; // a1数组中的元素作为aAbcdefghiabcde数组的索引
    ++v4;
  }
  Str1[v4] = 0;
  if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") )
    result = sub_401770();
  else
    result = sub_4017B0();
  return result;
}

程序流程

用户输入的字符中,如果一个字符处于0~9,就让这个字符减去48;如果处于a~z,就减去87;如果处于A~Z,就减去29,从而得到check函数里用到的索引数组。
进入check函数
依次将v5的元素作为aAbcdefghiabcde数组的索引,取出aAbcdefghiabcde的每个元素并赋给Str1形成新的字符串和“KanXueCTF2019JustForhappy”比较,相等就通过。
dump出来aAbcdefghiabcde的数据,枚举一下输入即可。编写脚本

EXP

#include<iostream>
#include<string.h>
using namespace std;

int main(){
    char aAbcdefghiabcde[]="abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ";
    char result[]="KanXueCTF2019JustForhappy";
    int v5;
    for(int i1=0;i1<strlen(result);i1++){
        for(int i2=0;i2<strlen(aAbcdefghiabcde);i2++){
            if ( aAbcdefghiabcde[i2] >=48 && aAbcdefghiabcde[i2] <= 57 )
                v5 = aAbcdefghiabcde[i2] - 48;
            if ( aAbcdefghiabcde[i2] >=97 && aAbcdefghiabcde[i2] <= 122 )
                v5 = aAbcdefghiabcde[i2] - 87;
            if ( aAbcdefghiabcde[i2] >=65 && aAbcdefghiabcde[i2] <= 90 )
                v5 = aAbcdefghiabcde[i2] - 29;
            if(aAbcdefghiabcde[v5]==result[i1])
            {
                cout<<aAbcdefghiabcde[i2];
                break;
            }
          }
    } 
return 0;
} 
//j0rXI4bTeustBiIGHeCF70DDM

疑惑

python我没有专门去学,我按照C++的写法,转为python脚本如下

tmpl=list("abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ")

result=list("KanXueCTF2019JustForhappy")

flag=''

for r in result:
    for ch in tmpl:
        if ord(ch)>=0 and ord(ch)<=9:
            index=ord(ch)-48
        if ord(ch)>=97 and ord(ch)<=122:
            index = ord(ch) - 87
        if ord(ch)>=65 and ord(ch)<=90:
            index=ord(ch)-29
        if tmpl[index]==r:
            flag+=ch
            break;

print "flag:",flag
#jrXIbTeustBiIGHeCFDDM

结果却不一样,显然C++是正确的,不解,拜托各位大神解释一下。



[公告][征集寄语] 看雪20周年年会(12.28上海) | 感恩有你,一路同行

最新回复 (0)
游客
登录 | 注册 方可回帖
返回