zoukankan      html  css  js  c++  java
  • BUUCTF--SimpleRev

    测试文件:https://buuoj.cn/files/7458c5c0ce999ac491df13cf7a7ed9f1/SimpleRev?token=eyJ0ZWFtX2lkIjpudWxsLCJ1c2VyX2lkIjoxOTAzLCJmaWxlX2lkIjoyNDN9.XXnIgg.L-8ifBkOTka-7o-QXZDkKNm77x4

    1.准备

    获取信息

    1. 64位文件

    2.IDA打开

    将main函数反编译为C代码

     1 int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
     2 {
     3   int v3; // eax
     4   char v4; // [rsp+Fh] [rbp-1h]
     5 
     6   while ( 1 )
     7   {
     8     while ( 1 )
     9     {
    10       printf("Welcome to CTF game!
    Please input d/D to start or input q/Q to quit this program: ", argv, envp);
    11       v4 = getchar();
    12       if ( v4 != 'd' && v4 != 'D' )
    13         break;
    14       Decry();
    15     }
    16     if ( v4 == 'q' || v4 == 'Q' )
    17       Exit();
    18     puts("Input fault format!");
    19     v3 = getchar();
    20     putchar(v3);
    21   }
    22 }

    3.代码分析

    很明显,这道题的关键在于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 = 0LL;
    19   v8 = 0;
    20   v9 = 'wodah';
    21   v10 = 0LL;
    22   v11 = 0;
    23   text = join(key3, (const char *)&v9);         // text = 'killshadow'
    24   strcpy(key, key1);
    25   strcat(key, src);                             // key = 'ADSFKNDCLS'
    26   v2 = 0;
    27   v3 = 0;
    28   getchar();
    29   v5 = strlen(key);                             // v5 = 10
    30   for ( i = 0; i < v5; ++i )
    31   {
    32     if ( key[v3 % v5] > 64 && key[v3 % v5] <= 90 )// key = 'adsfkndcls'
    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 == 10 )
    41       break;
    42     if ( v1 == 32 )
    43     {
    44       ++v2;
    45     }
    46     else
    47     {
    48       if ( v1 <= 96 || v1 > 122 )
    49       {
    50         if ( v1 > 64 && v1 <= 90 )              // 大写字母
    51           str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
    52       }
    53       else                                      // 小写字母
    54       {
    55         str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
    56       }
    57       if ( !(v3 % v5) )
    58         putchar(' ');
    59       ++v2;
    60     }
    61   }
    62   if ( !strcmp(text, str2) )
    63     puts("Congratulation!
    ");
    64   else
    65     puts("Try again!
    ");
    66   return __readfsqword(0x28u) ^ v12;
    67 }

    转换成可以运行的C代码是

     1 #include <bits/stdc++.h>
     2 
     3 #pragma warning(disable:4996)
     4 
     5 int main(void)
     6 {
     7     int i, j, n = 0, v5 = 10, v3 = 0, v2 = 0;
     8     char v1;
     9     char flag[11] = { 0 };
    10     char str2[104] = { 0 };
    11     char key[] = "ADSFKNDCLS";
    12     char text[] = "killshadow";
    13 
    14 
    15     for (i = 0; i < v5; ++i)
    16     {
    17         if (key[v3 % v5] > 64 && key[v3 % v5] <= 90)
    18             key[i] = key[v3 % v5] + 32;
    19         ++v3;
    20     }
    21     printf("Please input your flag:");
    22     while (1)
    23     {
    24         v1 = getchar();
    25         printf("v1:%c
    v2:%d
    
    ", v1, v2);
    26         if (v1 == 10) {
    27             printf("进入1
    ");
    28             break;
    29         }
    30         if (v1 == 32)
    31         {
    32             printf("进入2
    ");
    33             ++v2;
    34         }
    35         else
    36         {
    37             if (v1 <= 96 || v1 > 122)
    38             {
    39                 if (v1 > 64 && v1 <= 90) {
    40                     str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
    41                     printf("计算1
    ");
    42                 }
    43             }
    44             else
    45             {
    46                 str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;
    47                 printf("计算1
    ");
    48             }
    49             if (!(v3 % v5))
    50                 putchar(' ');
    51             ++v2;
    52         }
    53     }
    54     if (!strcmp(text, str2))
    55         puts("Congratulation!
    ");
    56     else {
    57         printf("str2:%s
    ", str2);
    58         puts("Try again!
    ");
    59     }
    60 
    61     system("PAUSE");
    62     return 0;
    63 }
    View Code

    第30~35行代码的实际作用是将大写字母转换为小写。

    第37~61行代码实际上就是遍历输入的字符(flag),进行str2[v2] = (v1 - 39 - key[v3++ % v5] + 97) % 26 + 97;运算,最后与text比较。

    因此我们只要反向就能求出输入的v1

    4.程序获取flag

    #include <bits/stdc++.h>
    
    #pragma warning(disable:4996)
    
    int main(void)
    {
        int i, j, n = 0, v5 = 10, v3 = 0, v2 = 0;
        char v1;
        char flag[11] = { 0 };
        char str2[104] = { 0 };
        char key[] = "ADSFKNDCLS";
        char text[] = "killshadow";
    
    
        for (i = 0; i < v5; ++i)
        {
            if (key[v3 % v5] > 64 && key[v3 % v5] <= 90)
                key[i] = key[v3 % v5] + 32;
            ++v3;
        }
        for (j = 0; j < 10; ++j) {
            for (v2 = 0; v2 < 10; ++v2) {
                v1 = text[v2] - 97 + 26 * j - 97 + key[v3++ % v5] + 39;
                if ((v1 >= 65 && v1 <= 90) || (v1 >= 97 && v1 <= 122)) {
                    flag[v2] = v1;
                    if (++n == 10) {
                        printf("%s
    ", flag);
                        system("PAUSE");
                        return 0;
                    }
                }
            }
        }
    
        system("PAUSE");
        return 0;
    }

    5.get flag!

    flag{KLDQCUDFZO}

  • 相关阅读:
    Light oj 1082 Array Queries(区间最小值)
    Codeforces Round #179 (Div. 2)A、B、C、D
    poj 1976 A Mini Locomotive(01背包)
    Codeforces Round #178 (Div. 2)
    hackerrank challenges median
    poj 1961 Period(kmp最短循环节)
    poj 2182 Lost Cows(树状数组)
    ZOJ1117 POJ1521 HDU1053 Huffman编码
    poj 2352 Stars 树状数组
    这可能是最适合萌新入门Web安全的路线规划
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/11511292.html
Copyright © 2011-2022 走看看