2019红帽杯ctf-reverse-xx

一道xxtea加密的题

主要过程分五步

1、读入数据

2、构造key数组

3、xxtea加密

4、打乱数据

5、二次加密

先查壳,64位无壳

直接拖入ida分析

 

 读入数据并计算长度

判断输入的字符串数据是否都在Code中

一开始没有看出来这里是干什么的,直接去分析后面了,后来看了其他师傅的wp才知道,这里是构造xxtea加密的key数组

 这里就是xxtea加密的部分

 在这里打乱了加密后数组的顺序

 在这里又对数组进行了二次加密

 进行最后的校验

以上就是整体流程,所有的过程都是可逆的,只是比较麻烦,直接给出解密脚本 

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define xxtea_DELTA 0x9e3779b9
#define xxtea_MX (((xxtea_z>>5^xxtea_y<<2) + (xxtea_y>>3^xxtea_z<<4)) ^ ((xxtea_sum^xxtea_y) + (xxtea_key[(xxtea_p&3)^xxtea_e] ^ xxtea_z)))
void xxtea(uint32_t* xxtea_origin, int xxtea_n, uint32_t const xxtea_key[4])
{
    uint32_t xxtea_y, xxtea_z, xxtea_sum;
    unsigned xxtea_p, xxtea_rounds, xxtea_e;
    if (xxtea_n > 1)            /* Coding Part */
    {
        xxtea_rounds = 6 + 52 / xxtea_n;
        xxtea_sum = 0;
        xxtea_z = xxtea_origin[xxtea_n - 1];
        do
        {
            xxtea_sum += xxtea_DELTA;
            xxtea_e = (xxtea_sum >> 2) & 3;
            for (xxtea_p = 0; xxtea_p < xxtea_n - 1; xxtea_p++)
            {
                xxtea_y = xxtea_origin[xxtea_p + 1];
                xxtea_z = xxtea_origin[xxtea_p] += xxtea_MX;
            }
            xxtea_y = xxtea_origin[0];
            xxtea_z = xxtea_origin[xxtea_n - 1] += xxtea_MX;
        } while (--xxtea_rounds);
    }
    else if (xxtea_n < -1)      /* Decoding Part */
    {
        xxtea_n = -xxtea_n;
        xxtea_rounds = 6 + 52 / xxtea_n;
        xxtea_sum = xxtea_rounds * xxtea_DELTA;
        xxtea_y = xxtea_origin[0];
        do
        {
            xxtea_e = (xxtea_sum >> 2) & 3;
            for (xxtea_p = xxtea_n - 1; xxtea_p > 0; xxtea_p--)
            {
                xxtea_z = xxtea_origin[xxtea_p - 1];
                xxtea_y = xxtea_origin[xxtea_p] -= xxtea_MX;
            }
            xxtea_z = xxtea_origin[xxtea_n - 1];
            xxtea_y = xxtea_origin[0] -= xxtea_MX;
            xxtea_sum -= xxtea_DELTA;
        } while (--xxtea_rounds);
    }
}

  
int main()
{
    unsigned char v30[] = {0xce,0xbc,0x40,0x6b,0x7c,0x3a,0x95,0xc0,0xef,0x9b,0x20,0x20,0x91,0xf7,0x2,0x35,0x23,0x18,0x2,0xc8,0xe7,0x56,0x56,0xfa};

    __int64 v23; // rcx
    char v24; // al
    unsigned char *v22; // r8
    int v21 = 1;
    int v18 = 24;
    //第二处加密 
    v22 = v30 + 24;
    v21 = v18;
    for (;v21 > 1;--v22)
    {
        v23 = 0;
        if (v21 / 3 > 0)
        {
            v24 = *v22;
            do
            {
                v24 ^= v30[v23++];
                *v22 = v24;
            }
            while ( v23 < v21 / 3 );
        }
        --v21;
    }
    //恢复打乱的顺序 
    unsigned char *v19;
    v19 = v30;
    *v19   = v30[1]; 
    v19[2] = *v30; 
    v19[3] = v30[2]; 
    v19[1] = v30[3]; 
    v19[6] = v30[4]; 
    v19[4] = v30[5]; 
    v19[7] = v30[6]; 
    v19[5] = v30[7]; 
    v19[10] =v30[8];  
    v19[8] = v30[9]; 
    v19[11] =v30[10];
    v19[9] =v30[11];
    v19[14] =v30[12];
    v19[12] =v30[13];
    v19[15] =v30[14];
    v19[13] =v30[15];
    v19[18] =v30[16];
    v19[16] =v30[17];
    v19[19] =v30[18];
    v19[17] =v30[19];
    v19[22] =v30[20];
    v19[20] =v30[21];
    v19[23] =v30[22];
    v19[21] =v30[23];
/*    for(int i = 0;i < 6;i++)
    {
        printf("0x");
        for(int j = 3;j >= 0;j--)
        {
            printf("%x",v19[i*4+j]);
        }
        printf(",");
    } 
*/    
    unsigned int v11[6] = {0x40cea5bc,0xe7b2b2f4,0x129d12a9,0x5bc810ae,0x1d06d73d,0xdcf870dc};
    uint32_t const key1[4] = { (unsigned int)0x67616c66,(unsigned int)0x0,(unsigned int)0x0,(unsigned int)0x0 };
    
    int n = -6;
    xxtea(v11, n, key1);
    //67616c665858437b646e615f742b2b5f7d616513
/*    for (int i = 0; i < 6; i++)
    {
        printf("%x", v11[i]);
    }
*/    
    int flag[] = {0x67,0x61,0x6c,0x66,0x58,0x58,0x43,0x7b,0x64,0x6e,0x61,0x5f,0x74,0x2b,0x2b,0x5f,0x7d,0x61,0x65};
    for(int i = 0;i < 19;i++)
    {
        printf("%c",flag[i]);
    } 
}

 

posted @ 2022-11-26 23:17  写在风中的信  阅读(300)  评论(0编辑  收藏  举报