[GUET-CTF2019]encrypt 题解

文章描述了一种结合RC4加密和魔改Base64的加密方法,通过IDC脚本提取加密后的字节序列,并在Linux虚拟机中进行动态调试来获取每次RC4加密中的关键异或数据。利用这些数据与Base64解密后的密文异或,可以恢复原始明文。作者提供了一个C语言的解密脚本来实现这一过程。

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

本题是输入了一个字符串,进行了rc4加密,和魔改的base64加密

RC4算法初始化函数

RC4加密过程

魔改的base64加密

最后加密的字符串是byte_602080

我们可以将byte_602080提取出来,下面是提取数据的IDC脚本,得到了密文

#include<idc.idc>
static main(){
    Message("\nStart:-------------------------------------------------------------------\n");
    auto addr=0x602080;  
    auto i=0;
    auto length=51  ;
    for(i=addr;i<=addr+length;i++){
            Message("0x%02x,",Byte(i));
    }
    Message("End:-----------------------------------------------------------------------\n");
}

然后先进行base64解密

然后进行RC4解密

我们RC4解密时候,不编写整个RC4加密算法的解密脚本

我们知道RC4加密算法最后是要得到一个数据和明文进行异或

*(_BYTE *)(i + a2) ^= LOBYTE(v9[(unsigned __int8)(v7 + v8)]);

该数据 xor 明文=密文

密文 xor 该数据 =明文

我们如果能得到每次循环的这个数据,与base64解密得到结果(RC加密后的密文)依次异或就能得到明文

 这个需要远程动态调试,我们需要在88次循环中截取到每次最后进行异或的这个数据

观察这一句对应的汇编代码,xor edx,esi

发现此时edx存储的正是这个要和明文异或的数据

我们将这个文件放在Linux虚拟机中进行动态调试

编写脚本自动化调试提取每次edx的值

 这是使用脚本自动化动态调试得到的每次的数据

编写wp

#include <stdio.h>
#include <string.h>

int main() {
    char data[] = {0x5a, 0x60, 0x54, 0x7A, 0x7A, 0x54, 0x72, 0x44, 0x7C, 0x66, 0x51, 0x50, 0x5B, 0x5F, 0x56, 0x56, 0x4C, 0x7C, 0x79, 0x6E, 0x65, 0x55, 0x52, 0x79, 0x55, 0x6D, 0x46, 0x6B, 0x6C, 0x56, 0x4A, 0x67, 0x4C, 0x61, 0x73, 0x4A, 0x72, 0x6F, 0x5A, 0x70, 0x48, 0x52, 0x78, 0x49, 0x55, 0x6C, 0x48, 0x5C, 0x76, 0x5A, 0x45, 0x3D};
    char flag[255];
    memset(flag, 0, sizeof(flag));
    int j = 0;
    char l[] = {0x10, 0x59, 0x9C, 0x92, 0x06, 0x22, 0xCF, 0xA5, 0x72, 0x1E, 0x45, 0x6A, 0x06, 0xCB, 0x08, 0xC3, 0xE4, 0x49, 0x5A, 0x63, 0x0C, 0xDF, 0xF6, 0x5F, 0x08, 0x28, 0xBD, 0xE2, 0x10, 0x15, 0x1F, 0x6E, 0xAA, 0x5A, 0xCA, 0xEC, 0x80, 0xAF, 0x9B, 0x16, 0xBB, 0x3D, 0x13, 0x2F, 0x6A, 0xA4, 0xC7, 0x2E, 0xBC, 0x4B, 0x60, 0x9A, 0xAF, 0xE9, 0xCE, 0xDA, 0x67, 0x39, 0xBA, 0x3B, 0x85, 0xEB, 0xD2, 0x6B, 0xAB, 0x06, 0x6B, 0x10, 0x57, 0x2C, 0x88, 0x70, 0xF7, 0x4F, 0xAA, 0x7F, 0x12, 0x47, 0xD6, 0xDE, 0x74, 0xB2, 0x1D, 0xA4, 0xD7, 0x76, 0x9A, 0xE0};

    for (int i = 0; i < sizeof(data); i += 4) {
        flag[strlen(flag)] = (((data[i] - 0x3D) & 0x3F) << 2) | (((data[i + 1] - 0x3D) & 0x30) >> 4);
        flag[strlen(flag)] = (((data[i + 1] - 0x3D) & 0x0F) << 4) | (((data[i + 2] - 0x3D) & 0x3C) >> 2);
        flag[strlen(flag)] = ((data[i + 3] - 0x3D) & 0x3F) | ((data[i + 2] - 0x3D) & 0x03) << 6;
    }

    for (int i = 0; i < strlen((const char *)flag); i++) {
       flag[i] ^= l[j++];
    }
    printf("%s", flag);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烨鹰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值