2024蓝桥杯CTF--逆向

蓝桥杯付费CT--逆向

题目:RC4

  1. 先查壳,无壳,并且是32位:

  2. 用32位的ida打开,直接定位到main函数:

  3. 重点关注sub_401005函数,这个应该就是加密函数无疑:

  4. 典型的RC4加密无疑,这里有两种方法进行逆向,第一种:可以在main函数中第52行打上断点,运行到这里后直接查看内存中的V5,即位flag。第二种:将需要的信息提取出来key=gamelab@,使用脚本进行解密:

  5. 第一种:

  6. 第二种:

    #RC4加密
    def rc4(key, ciphertext):
    # 初始化S盒
    sbox = list(range(256))
    j = 0
    for i in range(256):
    j = (j + sbox[i] + key[i % len(key)]) % 256
    sbox[i], sbox[j] = sbox[j], sbox[i]

     # 生成密钥流
     i = 0
     j = 0
     keystream = []
     for _ in range(len(ciphertext)):
         i = (i + 1) % 256
         j = (j + sbox[i]) % 256
         sbox[i], sbox[j] = sbox[j], sbox[i]
         k = sbox[(sbox[i] + sbox[j]) % 256]
         keystream.append(k)
     # print(keystream)
    
     # 解密密文
     plaintext = []
     for i in range(len(ciphertext)):
         m = ciphertext[i] ^ keystream[i]
         plaintext.append(m)
     print(plaintext)
    
     # 将明文转换为字符串
     return ''.join([chr(p) for p in plaintext])
    

    测试

    key = b"gamelab@"
    ciphertext =[0xB6,0x42,0xB7,0xFC,0xF0,0xA2,0x5E,0xA9,0x3D,0x29,0x36,0x1F,0x54,0x29,
    0x72,0xA8,0x63,0x32,0xF2,0x44,0x8B,0x85,0xEC,0xD,0xAD,0x3F,0x93,0xA3,0x92,
    0x74,0x81,0x65,0x69,0xEC,0xE4,0x39,0x85,0xA9,0xCA,0xAF,0xB2,0xC6]

    for i in ciphertext:

    print(chr(i),end="")

    plaintext = rc4(key, ciphertext)
    print(plaintext)
    #flag{12601b2b-2f1e-468a-ae43-92391ff76ef3}

  7. 两个flag一样,说明正确。

题目:happytime

  1. 同样的流程,查壳无,64位的.elf程序,使用ida打开,直接进入main函数:

  2. printf输出提示信息Let's have a drink,pay your answer(flag): ,read在键盘读取flag输入,重要的关键函数是cry加密函数,接受v5和输入的flag,这里的11应该是flag被分割成了11组,最后一个循环比较加密后的flag和V6,刚好和上面v6数组对应:

  3. 根据函数的特征,可以判定这是XXTEA加密无疑,找到其中的DELTA,密文(main函数中的v6),和key(前面main函数的V5),即可编写脚本解密(输出的时候注意大小端序):

    #include <stdbool.h>
    #include <stdio.h>
    #define MX (((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4)) ^ (sum ^ y) + (k[(p & 3) ^ e] ^ z))
    bool btea(unsigned int *v, int n, unsigned int k)
    {
    unsigned int z = v[n - 1], y = v[0], sum = 0, e, DELTA = 0x61C88647;
    unsigned int p, q;
    if (n > 1)
    { /
    enCoding Part */
    q = 415 / n + 114;
    while (q-- > 0)
    {
    sum += DELTA;
    e = (sum >> 2) & 3;
    for (p = 0; p < (n - 1); p++)
    {
    y = v[p + 1];
    z = v[p] += MX;
    }

             y = v[0];
             z = v[n - 1] += MX;
         }
         return 0;
     }
     else if (n < -1)
     { /* Decoding Part */
         n = -n;
         q = 415 / n + 114;
         sum = -q * DELTA;
         while (sum != 0)
         {
             e = (sum >> 2) & 3;
             for (p = n - 1; p > 0; p--)
             {
                 z = v[p - 1];
                 y = v[p] -= MX;
             }
    
             z = v[n - 1];
             y = v[0] -= MX;
             sum += DELTA;
         }
         return 0;
     }
     return 1;
    

    }

    int main()
    {
    unsigned int v[11] = {0x480AC20C, 0xCE9037F2, 0x8C212018, 0xE92A18D, 0xA4035274, 0x2473AAB1, 0xA9EFDB58, 0xA52CC5C8, 0xE432CB51, 0xD04E9223, 0x6FD07093}, key[4] = {0x79696755, 0x67346F6C, 0x69231231, 0x5F674231};
    int n = 11; // n为要加密的数据个数
    btea(v, -n, key); // 取正为加密,取负为解密
    char *p = (char *)v;
    for (int i = 0; i < 44; i++)
    {
    printf("%c", *p);
    p++;
    }
    return 0;
    }
    //flag{efccf8f0-0c97-12ec-82e0-0c9d9242e335}

  4. 最后输入验证flag成功!!!

总结:

  1. 蓝桥杯CTF(付费CTF),逆向题难度签到题难度,题目质量。。。。,也难怪圈。
相关推荐
贾saisai40 分钟前
Xilinx系FPGA学习笔记(九)DDR3学习
笔记·学习·fpga开发
北岛寒沫44 分钟前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习
烟雨666_java1 小时前
JDBC笔记
笔记
GEEKVIP1 小时前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑
铁匠匠匠2 小时前
从零开始学数据结构系列之第六章《排序简介》
c语言·数据结构·经验分享·笔记·学习·开源·课程设计
Moliay3 小时前
【资料分析】刷题日记2
笔记·公考·行测·常识·资料分析
小齿轮lsl4 小时前
PFC理论基础与Matlab仿真模型学习笔记(1)--PFC电路概述
笔记·学习·matlab
天玑y5 小时前
算法设计与分析(背包问题
c++·经验分享·笔记·学习·算法·leetcode·蓝桥杯
自陈5 小时前
蓝桥杯嵌入式客观题合集
蓝桥杯·蓝桥杯嵌入式客观题
web_learning_3216 小时前
source insight学习笔记
笔记·学习