• BUUCTF SimpleRev


    分析

    该文件为64位的ELF文件,运行在linux平台
    使用IDA64打开
    在这里插入图片描述
    进入Decry函数
    在这里插入图片描述
    输入flag和成功的提示
    看看如何才能成功拿到flag
    在这里插入图片描述

    这里比较text和str2,text是源代码就有的
    在这里插入图片描述

    那么str2应该就是我们输入的内容
    先分析text的内容是什么
    进入join函数
    该函数将两个输入字符串连接在一起,并返回一个新的字符串,表示连接后的结果。

    char *__fastcall join(const char *a1, const char *a2)
    {
      size_t v2; // 用于存储第一个输入字符串的长度
      size_t v3; // 用于存储第二个输入字符串的长度
      char *dest; // 用于存储连接后的字符串的指针
    
      // 计算第一个输入字符串的长度
      v2 = strlen(a1);
    
      // 计算第二个输入字符串的长度
      v3 = strlen(a2);
    
      // 分配足够的内存来存储连接后的字符串,加1是为了存储字符串结尾的空字符 '\0'
      dest = (char *)malloc(v2 + v3 + 1);
    
      // 检查内存分配是否成功
      if (!dest)
        exit(1); // 如果分配失败,则退出程序
    
      // 将第一个输入字符串复制到目标字符串
      strcpy(dest, a1);
    
      // 将第二个输入字符串连接到目标字符串末尾
      strcat(dest, a2);
    
      // 返回连接后的字符串
      return dest;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    我们不难得到text的值
    在这里插入图片描述
    点击一下0x776F646168LL然后按r
    因为是小端序,所以低位在前,高位在后,所以最后需要反过来

    hadow
    
    • 1

    在这里插入图片描述在这里插入图片描述

    killshadow
    
    • 1

    接下来就看要如何输入才能构造出这个字符串
    将所有字符显示出来,点击在数字上然后按r,这样看着更直观
    在这里插入图片描述

    这里贴上ascii码表链接作为对照: https://tool.oschina.net/commons?type=4

    在这里插入图片描述
    如果你输入的是大写字母,那么就执行下面的语句

    str2[v2] = (v1 - 39 - key[v3 % v5] + 'a') % 26 + 'a';
    ++v3;
    
    • 1
    • 2

    如果是小写就执行

    str2[v2] = (v1 - 39 - key[v3 % v5] + 'a') % 26 + 'a';
    ++v3;
    
    • 1
    • 2

    输入其他的字符就不进行处理

    你会发现这两条语句是一样的,也就是说只要输入的是英文,就执行这条语句,后面 %26说明最后运算出来的结果都不会大于26,最后加上a,也就是说最后计算出来的范围是小写字母

    这里我们还需要知道key是什么
    在这里插入图片描述
    这里将key1的值给了key,然后在key的末尾追加了src (这里的SLCDN同样要反过来,图上写错了)
    最后下面的for循环将key中所有的字母都小写了
    所以最后key的值为 adsfkndcls
    v3的值为10
    v5的值为10

    EXP

    #include 
    #include 
    #include 
    int main(int argc, char const *argv[])
    {
        int v3 = 10, v5 = 10, l, a;
        char key[] = "adsfkndcls";
        char str2[20];
        int  base = 65;		// 以大写为基数
        // str2[v2] = (v1 - 39 - key[v3 % v5] + 'a') % 26 + 'a';
        // str2[v2] = (v1  - key[v3 % v5] + 58) % 26 + 'a';
        // str2[v2] = (23  - key[v3 % v5] + 58) % 26 + 'a';
        char text[] = "killshadow";
        for (int i = 0; i < strlen(text); i++)
        {
            l = (base + 58  - key[v3 % v5]) % 26;     // 这里之所以多了个65是因为字母的最小ASCII码就是65
            a = text[i] - 'a';
            // 有两种情况,大于 answer 和小于 answer
            if (l > a)
                printf("%c", base + 26 - l + a);
            else
                printf("%c", base + a - l);
            v3++;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    最终flag

    flag{KLDQCUDFZO}
    
    • 1

    其实还有个答案,就是以小写为基数,将base改为97

    flag{efxkwoxzti}
    
    • 1

    但是flag就只有一个,那就是那个大写的falg

    其他解法

    还有一种解法就是直接进行暴力破解
    因为我们的输入也就是英文字母

    #include 
    #include 
    #include 
    int main(int argc, char const *argv[])
    {
        int v3 = 10, v5 = 10, l, a;
        char text[] = "killshadow";
        char key[] = "adsfkndcls";
        char str2[20];
        int base = 65;
        for (int n = 0; n < strlen(text); n++)
        {
            for (int i = base; i < 26 + base; i++)
            {
                // str2[v2] = (v1 - 39 - key[v3 % v5] + 'a') % 26 + 'a';
                if ((i - 39 - key[v3 % v5] + 'a') % 26 + 'a' == text[n]){
                    printf("%c", i);
                    v3++;
                    break;
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    2022年全国最新消防设施操作员(高级消防设施操作员)真题题库及答案
    如何使用Python进行数据分析?
    7-279 字符串输入输出练习7-284 倒立的杨辉三角形
    使用EasyExcel后端导出excel
    Java面试题(每天10题)-------连载(31)
    通过API接口进行商品价格监控,可以按照以下步骤进行操作
    基于STM32的智能小车--舵机云台设计
    聚名十周年线上庆典正式开启,发送祝福即有好礼相赠~
    CMake篇1: Windows上用CMake编译生成可执行程序
    【教程】Python科研数据可视化、MATLAB科研数据可视化
  • 原文地址:https://blog.csdn.net/qq_56313338/article/details/133748899