NJCTF-easy_crypto writeup

本文介绍了一个CTF竞赛中的easy_crypto挑战,通过分析提供的加密算法和文件,成功解密出flag。文章详细展示了如何逆向工程找出密钥,并实现解密算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上个星期天和队友一起玩了一把CTF,虽然真正做出来的只有一道题。其他就是一起出主意。
下面的是easy_crypto的writeup。
easy_crypto的附件是一个压缩包。包中有四个文件,Cipher.txt encrypt.c flag.txt plain.txt。其中Cipher.txt是plain.txt加密后的文件。
加密算法是encrypt.c。而flag.txt是明文加密后的文件,只要我们解密出来这个文件即可得出flag。
下面给出加密算法:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) 
{
    if (argc != 3) 
    {
        printf("USAGE: %s input_file output_file\n", argv[0]);
        return 0;
    }
    FILE* input_file  = fopen(argv[1], "rb");
    FILE* output_file = fopen(argv[2], "wb");
    if (!input_file || !output_file) 
    {
        printf("Error\n");
        return 0;
    }
    char key[] = "XXXXXXXXXXXX";
    char p, t, c = 0;
    int i = 0;
    while ((p = fgetc(input_file)) != EOF) 
    {

        c = ((key[i % strlen(key)] ^ t) + (p-t) + i*i ) & 0xff;
        t = p;
        i++;
        fputc(c, output_file);
    }
    return 0;
}

但是观察得出key不知道是多少?这时候,题目给的Cipher.txt ,plain.txt就起到作用了,通过这两个文件来得出key。
下面给出代码。

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

int main()
 {
    FILE* input_file  = fopen("plain.txt", "rb");
    FILE* output_file = fopen("cipher.txt", "rb");
    char key[100];
    char p, t, c = 0;
    int i = 0;
    while ((p = fgetc(input_file)) != EOF&&(c = fgetc(output_file))!=EOF)
    {
        key[i]=(c -((p-t) + i*i ))^t;
        t = p;
        i++;
    }
    cout<<key<<endl;
    return 0;
}

这是解密的结果,后面的乱码不用管
字符串如下:
OKIWILLLETYOUKNOWWHATTHEKEYIS
OKIWILLLETYOUKNOWWHATTHEKEYIS
OKIWILLLETYOUKNOWWHATTHEKEYIS
OKIW
从这上面我们可以得出:
key数组就是OKIWILLLETYOUKNOWWHATTHEKEYIS。
得到key之后,我们就要解密密文,还要写出算法:

#pragma once
#pragma execution_character_set("utf-8")
#include <stdlib.h>
#include<ctype.h>
#include <stdio.h>
#include <cstring>
#include<iostream>
using namespace std;

int main()
{
    FILE* input_file = fopen("flag.txt", "rb");
    char key[] = "OKIWILLLETYOUKNOWWHATTHEKEYIS";
    char flag[100] = "";
    char p,t,c;
    p = t = c = 0;
    int i = 0;
    while ((c = fgetc(input_file)) != EOF)
    {
        p = c - i*i + t - (key[i % strlen(key)] ^ t);
        flag[i] = p;
        t = p;
        i++;
    }
    cout << flag << endl;
    return 0;
}

Flag图
于是Flag:NJCTF{N0w_You90t_Th1sC4s3}。
解题完毕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值