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;
}

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

hadow

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

killshadow

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

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

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

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

如果是小写就执行

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

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

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

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

EXP

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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++;
    }
}

最终flag

flag{KLDQCUDFZO}

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

flag{efxkwoxzti}

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

其他解法

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值