2023鹏城杯 Re——BabyRe

1.查找不到main函数 shift + f12 查找字符串交叉引用到主函数

2.主函数将输入的48字节数据,每次传参12字节数据到sub_7FF7F2C2107D里面进行加密

3.sub_7FF7F2C2107D函数分析 ,因为是v6,v7,v8都是 int 类型数据,每次循环都取出每一个字节,然后将这每一个字节加密(23 * x + 66) & 0xff,再赋值回去,再将这几个字节相加

4.继续分析下面加密虽然看着第一眼很混乱但是,简化一下(就是我的注释)其实发现就是一个TEA加密,只不过和普通的不一样而已原理一样,由于srand的seed种子是固定的0xDEADC0DE所以每次rand生成的值我们都知道其实就可以逆向了

5.解密源码(两个注意点: 1.爆破是时候范围是 0 - 255 而不是 32 -- 127   2.使用随机数解密时应该从最后生成的随机数开始从后往前逆向)

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
uint32_t rand_data[192] = { 0 };
void blast(uint32_t *data)
{
    uint32_t v0[3][4] = {0};
    int i = 0;
    int j = 0;
    uint32_t t = 0;

    //取出每个字节方便后面爆破
    for (i = 0; i < 3; i++)
    {
        if (i == 0)
        {
            v0[i][j + 0] = (unsigned char)(data[i]);
            v0[i][j + 1] = (unsigned char)(data[i] >> 8 );
            v0[i][j + 2] = (unsigned char)(data[i] >> 16) ;
            v0[i][j + 3] = (unsigned char)(data[i] >> 24) ;
            
        }
        if (i == 1)
        {
            v0[i][j + 0] = (unsigned char)(data[i]);
            v0[i][j + 1] = (unsigned char)(data[i] >> 8);
            v0[i][j + 2] = (unsigned char)(data[i] >> 16);
            v0[i][j + 3] = (unsigned char)(data[i] >> 24);
        }
        else
        {
            v0[i][j + 0] = (unsigned char)(data[i]);
            v0[i][j + 1] = (unsigned char)(data[i] >> 8);
            v0[i][j + 2] = (unsigned char)(data[i] >> 16);
            v0[i][j + 3] = (unsigned char)(data[i] >> 24);
        }    
    }

    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
        {
            for (t = 0; t < 256; t++)   //爆破,范围要对
            {
                if (((23 * t + 66) & 0xff) == v0[i][j])
                {
                    //printf("%u ", t);
                    v0[i][j] = t;
                    break;
                }
            }
        }
    }
    //每个字节相加
    j = 0;
    for (i = 0; i < 3; i++)
    {
        data[i] = v0[i][j + 3] << 24 | v0[i][j + 2] << 16 | v0[i][j + 1] << 8 | v0[i][j + 0];
    }
}

void TEA_dercypt(uint32_t* v)
{
    //data[0] 是 v6 data[1] 是 v7 data[2]是v8
    uint32_t data[3] = { 0 };
    data[0] = v[0];
    data[1] = v[1];
    data[2] = v[2];
    int index = 191;        //这个是随机数数组最后元素的下标,因为我们要从最后开始逆向,所以每次使用的随机数应该是从后往前
    int i = 0;
    for (i = 0; i < 32; i++)
    {


        data[2] -= (rand_data[index - 1] + (data[0] >> 7)) + (rand_data[index] ^ ((data[0] >> 15) ^ (data[0] << 10) | 3));
        index -= 2;
        data[1] -= (rand_data[index - 1] + (data[2] >> 7)) + (rand_data[index] ^ ((data[2] >> 15) ^ (data[2] << 10) | 3));
        index -= 2;
        data[0] -= (rand_data[index - 1] + (data[1] >> 7)) + (rand_data[index] ^ ((data[1] >> 15) ^ (data[1] << 10) | 3));
        index -= 2;
        blast(data);

    }

    v[0] = data[0];
    v[1] = data[1];
    v[2] = data[2];
}


int main()
{
    //生成随机数
    srand(0xDEADC0DE);
    int i = 0;
    for (i = 0; i < 32 * 6; i++)
    {
        rand_data[i] = rand();
    }

    
    uint32_t encode_data[12] = {2688240968, 1411920167, 891416941, 1282044696, 2562538353, 762796726, 2613783307, 2840365796, 4045098844, 1496333720, 2063340607, 721577204};
    uint32_t temp[3] = { 0 };
 
    for (i = 0; i < 12; i += 3)
    {
        temp[0] = encode_data[i + 0];
        temp[1] = encode_data[i + 1];
        temp[2] = encode_data[i + 2];
        //解密
        TEA_dercypt(temp);
        printf("%c%c%c%c%c%c%c%c%c%c%c%c", *((char*)&temp[0] + 0), *((char*)&temp[0] + 1), *((char*)&temp[0] + 2), *((char*)&temp[0] + 3), *((char*)&temp[1] + 0), *((char*)&temp[1] + 1), *((char*)&temp[1] + 2), *((char*)&temp[1] + 3), *((char*)&temp[2] + 0), *((char*)&temp[2] + 1), *((char*)&temp[2] + 2), *((char*)&temp[2] + 3));
    }
    
    return 0;
}

flag{1CpOVOIeB1d2FcYUvnN1k5PbfMzMNzUzUgV6mB7hXF}

        

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值