• BUUCTF-RE-SimpleRev


    一、查壳

    64位文件

    二、IDA分析

    int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
    {
      int v3; // eax
      char v4; // [rsp+Fh] [rbp-1h]
    
      while ( 1 )
      {
        while ( 1 )
        {
          printf("Welcome to CTF game!
    Please input d/D to start or input q/Q to quit this program: ", argv, envp);
          v4 = getchar();
          if ( v4 != 'd' && v4 != 'D' )
            break;
          Decry();
        }
        if ( v4 == 'q' || v4 == 'Q' )
          Exit();
        puts("Input fault format!");
        v3 = getchar();
        putchar(v3);
      }
    }

    Decry()为关键函数

     1 unsigned __int64 Decry()
     2 {
     3   char v1; // [rsp+Fh] [rbp-51h]
     4   int v2; // [rsp+10h] [rbp-50h]
     5   int v3; // [rsp+14h] [rbp-4Ch]
     6   int i; // [rsp+18h] [rbp-48h]
     7   int v5; // [rsp+1Ch] [rbp-44h]
     8   char src[8]; // [rsp+20h] [rbp-40h]
     9   __int64 v7; // [rsp+28h] [rbp-38h]
    10   int v8; // [rsp+30h] [rbp-30h]
    11   __int64 v9; // [rsp+40h] [rbp-20h]
    12   __int64 v10; // [rsp+48h] [rbp-18h]
    13   int v11; // [rsp+50h] [rbp-10h]
    14   unsigned __int64 v12; // [rsp+58h] [rbp-8h]
    15 
    16   v12 = __readfsqword(0x28u);
    17   *(_QWORD *)src = 'SLCDN';  //小端序标记
    18   v7 = '';
    19   v8 = 0;
    20   v9 = 'wodah';  //是小端序标记的
    21   v10 = '';
    22   v11 = 0;
    23   text = join(key3, (const char *)&v9);  //key3=kills v9=wodah  text=killshadow
    24   strcpy(key, key1);  //key1=ADSFK
    25   strcat(key, src);   //连接两个char类型  key=ADSFKNDCLS
    26   v2 = 0;
    27   v3 = 0;
    28   getchar();
    29   v5 = strlen(key); 
    30   for ( i = 0; i < v5; ++i )
    31   {
    32     if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )
    33       key[i] = key[v3 % v5] + 32;
    34     ++v3;
    35   }
    36   printf("Please input your flag:", src);
    37   while ( 1 )
    38   {
    39     v1 = getchar();
    40     if ( v1 == '
    ' ) //输入为换行符,退出
    41       break;
    42     if ( v1 == ' ' )  //输入为空格,则v2+1
    43     {
    44       ++v2;
    45     }
    46     else
    47     {
    48       if ( v1 <= 96 || v1 > 122 )  //如果v1不为小写
    49       {
    50         if ( v1 > 64 && v1 <= 90 )  //如果v1为大写
    51           str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;  //对str2[v2]进行处理
    52       }
    53       else   //如果v1为小写字母
    54       {
    55         str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
    56       }
    57       if ( !(v3 % v5) )  //如果不为大小写字母,则不进行处理
    58         putchar(32);
    59       ++v2;
    60     }
    61   }
    62   if ( !strcmp(text, str2) )  //如果text和str2储存的相同,则成功
    63     puts("Congratulation!
    ");
    64   else
    65     puts("Try again!
    ");
    66   return __readfsqword(0x28u) ^ v12;
    67 }

    对第30-35行分析后  发现 30-35是把key从大写转到小写 key="adsfkndcls"

    #include <iostream>
    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char key[]= "ADSFKSLCDN";
        int v5;
        v5 = 10;
        int i,v3 = 0;
        for (i = 0; i < v5; ++i) {
            if (key[v3 % v5] > 64 && key[v3 % v5] <= 90)
                key[i] = key[v3 % v5] + 32;
            ++v3;
        }
        printf_s("%s
    ",key);
    }
    View Code

    解法有二

    Ⅰ爆破

    key="ADSFKNDCLS"
    text="killshadow"
    s=""
    flag=""
    loop="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
    v2 = 0
    v3 = 0
    v5 = len(key)
    for i in range(0,v5):
        if ( ord(key[i]) > 64 and ord(key[i]) <= 90 ):
            s += chr(ord(key[i]) + 32)
        else:
            s +=key[i]
    print(s)
    #变小写
    for i in range(0,len(text)):
        for j in loop:
            if ord(text[i])==(ord(j)-39-ord(s[i])+97)%26+97:
                flag+=j
    
    print(flag)

    Ⅱ 逆推

    #include <stdio.h>
    #include <string.h>
    int main(void)
    {
        char text[] = "killshadow";
        char key[] = "adsfkndcls";
        int key_ = strlen(key), text_ = strlen(text), i, j;
        char str2[15] = { 0 };
        for (i = 0; i < text_; i++)
            for (j = 0;; j++)
            {
                str2[i] = text[i] - 97 + 26 * j + 39 - 97 + key[i];
                if (str2[i] > 64 && str2[i] < 91)
                    break;
            }
        printf("flag{%s}", str2);
        return 0;
    }

    三、flag

    flag{KLDQCUDFZO}

  • 相关阅读:
    kafka概念使用简介注意点
    spring boot整合log4j2
    postgresql和oracle数据库对比
    postgresql数据操作
    Django缓存序列化信号
    Django补充
    Git学习
    JavaScript语法和类型
    Django分页
    Vue:配置组件
  • 原文地址:https://www.cnblogs.com/Nickyl07/p/12657107.html
Copyright © 2020-2023  润新知