首页
社区
课程
招聘
[原创]TEA、XTEA、XXTEA加解密过程及案例
2021-4-9 02:30 44132

[原创]TEA、XTEA、XXTEA加解密过程及案例

2021-4-9 02:30
44132

TEA、XTEA、XXTEA

更新原因: 那就回过头提升下文章质量吧,之前确实写的不好

一:TEA

简介:一种分组加密算法,TEA算法使用64位(也就是8字节一组)的明文分组和128位(16字节)的密钥,使用一个神秘常数作为倍数(也可更改)
关键加解密函数:
(可以看见加密和解密函数传入的v都是大小为2的四字节数组,uint32_t v0和v1,两个四字节加密迭代32轮直到最后)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdint.h>
 
void encrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0, i;
    uint32_t delta=0x9e3779b9;
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
    for (i=0; i < 32; i++) {
        sum += delta;
        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
    }
    v[0]=v0; v[1]=v1;
}
 
void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], i;
    uint32_t delta=0x9e3779b9;
    uint32_t sum = delta*32;
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
    for (i=0; i<32; i++) {
        v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        sum -= delta;
    }
    v[0]=v0; v[1]=v1;
}

下面这个脚本是2021mrctf逆向的Dynamic Debug题目的脚本
题目下载链接:
链接:https://pan.baidu.com/s/1mU70Z2-7tDToTBRbEU0NSA
提取码:0syj
评论有人在问这道题的解题wp,这题没啥好写wp的,调试到对应加密函数对拍就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <stdint.h>
 
void encrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0, i;
    uint32_t delta=0x9e3779b9;
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
    for (i=0; i < 32; i++) {
        sum += delta;
        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
    }
    v[0]=v0; v[1]=v1;
}
 
void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], i;
    uint32_t delta=0x9e3779b9;
    uint32_t sum = delta*32;
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
    for (i=0; i<32; i++) {
        v1 -= ((v0<<4) + k1) ^ (v0 + sum) ^ ((v0>>5) + k0);
        v0 -= ((v1<<4) + k3) ^ (v1 + sum) ^ ((v1>>5) + k2);
        sum -= delta;
    }
    v[0]=v0; v[1]=v1;
}
 
int main()
{
    uint32_t enflag[] = {0x5585A199, 0x7E825D68, 0x944D0039, 0x71726943, 0x6A514306, 0x4B14AD00, 0x64D20D3F, 0x9F37DB15};
    uint32_t key[4] = {0x67626463, 0x696D616E, 0x79645F65, 0x6B696C69};
    for(int i=0;i<8;i+=2)
    {
        uint32_t temp[2];        //定义来解密
        temp[0] = enflag[i];
        temp[1] = enflag[i+1];
        decrypt(temp, key);
        //printf("%X%X",temp[0],temp[1]);
        printf("%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));
    }
    return 0;
}

下面是某题flag2WP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
该题文件以及详细解题过程:
链接:https://pan.baidu.com/s/1TbGl2XOgqkDp60U8CliThQ
提取码:0syj
 
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
 
void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], i;
    uint32_t delta=0x6C7A6E62;
    uint32_t sum = delta*32;
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
    for (i=0; i<32; i++) {
        v1 ^= (31-i);
        v0 ^= (31-i);
        v1 -= ((v0<<2) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        v0 -= ((v1<<2) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        sum -= delta;
    }
    v[0]=v0; v[1]=v1;
}
 
int main()
{
    //异或后我们在内存中得到的数据dafbde108b5962f40e786cf1c994830d29bc0a29fea23e0bdc87ea0513c7350d
    uint32_t enflag[] = {0x10defbda,0xf462598b,0xf16c780e,0x0d8394c9,0x290abc29,0x0b3ea2fe,0x05ea87dc,0x0d35c713};
    uint32_t key[4] = {0x6C637953,0x76656C6F,0xD754C061,0x023BA78B};
    for(int i=0;i<8;i+=2)
    {
        uint32_t temp[2];        //定义来解密
        temp[0] = enflag[i];
        temp[1] = enflag[i+1];
        decrypt(temp, key);
        //printf("%X%X",temp[0],temp[1]);
        printf("%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));
    }
    return 0;
}

魔改tea的一些方法: 图片描述
这些都简单对拍下就行了
但是实际上还有一些加密模式的TEA,比如CBC模式的TEA
CBC模式(Cipher Block Chaining):其实主要就是将明文分组与前一个密文分组进行异或运算,然后再进行加密,对于第一组的话就设置一个初始值来和第一组明文异或
比如:(CBC模式循环加密64字节,每次循环加密8字节(v0和v1各4字节))
图片描述
每一轮是get_data取我们v0和v1,data1, data2和v0,v1异或,异或之后的data1和data2传入指针进行tea加密,之后再将加密之后的赋值回我们的v0和v1

 

在理解了CBC模式的TEA之后,我们该如何去逆向它呢,首先我们是有每轮加密后的v0和v1的,就是加密数据,TEA我们也是能够逆向的,那么就剩下逆向每轮的data1 ^= v0和data2 ^= v1了,而后面的轮数的data1和data2是会被我们的加密结果更新的,我们只有第一轮的data1和data2,那么我们就从这个地方下手,先解密第一轮,得到第一轮的v0和v1明文,再重新去加密更新data1和data2用于下一轮的解密
解题脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
 
uint32_t data1 = 0x5F797274;
uint32_t data2 = 0x64726168; //初始的data 值
 
void encrypt(uint32_t* v, uint32_t* k) {
    uint32_t v0 = v[0], v1 = v[1], sum = 0, i;
    data1 ^= v0;
    data2 ^= v1;
    v0 = data1;
    v1 = data2;
    uint32_t delta = 0x6e75316c;
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
    for (i = 0; i < 32; i++)
    {
        sum += delta;
        v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1) ^ (sum + i);
        v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3) ^ (sum + i);
    }
    data1 = v0;
    data2 = v1;
}
 
 
void decrypt(uint32_t* v, uint32_t* k)
{
    uint32_t delta = 0x6e75316c;
    uint32_t v0 = v[0], v1 = v[1], sum = (delta * 32) & 0xffffffff, i;
    uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
    for (i = 0; i < 32; i++)
    {
        v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3) ^ (sum + (31 - i));
        v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1) ^ (sum + (31 - i));
        sum -= delta;
    }
    v0 = v0 ^ data1;
    v1 = v1 ^ data2;
    v[0] = v0; v[1] = v1;
}
 
 
int main()
{
    uint32_t array[] = {0x9b28ed45, 0x145ec6e9, 0x5b27a6c3, 0xe59e75d5, 0xe82c2500, 0xa4211d92, 0xcd8a4b62, 0xa668f440};
    uint32_t key[4] = {0x65766967, 0x756F795F, 0x7075635F, 0x6165745F};
    for (int i = 0; i < 8; i += 2)
    {
        uint32_t temp[2];
        temp[0] = array[i];
        temp[1] = array[i + 1];
        decrypt(temp, key);
 
        printf("%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));
        //更新data
        encrypt(temp, key);
    }
    return 0;
}

二:XTEA

XTEA是TEA的升级版,增加了更多的密钥表,移位和异或操作等等,设计者是Roger Needham, David Wheeler
加密过程:

说白了,主要原因就是因为之前取key的时候是固定下标取的,现在通过计算来取
算法实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <stdint.h>
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4])
{
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
    for (i=0; i < num_rounds; i++) {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
    }
    v[0]=v0; v[1]=v1;
}
 
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    for (i=0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    }
    v[0]=v0; v[1]=v1;
}
 
int main()
{
    uint32_t v[2]={1,2};
    uint32_t const k[4]={2,2,3,4};
    unsigned int r=32;//num_rounds建议取值为32// v为要加密的数据是两个32位无符号整数// k为加密解密密钥,为432位无符号整数,即密钥长度为128
    printf("加密前原始数据:%u %u\n",v[0],v[1]);
    encipher(r, v, k);
    printf("加密后的数据:%u %u\n",v[0],v[1]);
    decipher(r, v, k);
    printf("解密后的数据:%u %u\n",v[0],v[1]);
    return 0;
}

XTEA实例: 2021虎符Re-GoEncrypt(WriteUp by syj)
https://bbs.pediy.com/thread-266935.htm

三:XXTEA

XXTEA,又称Corrected Block TEA,是XTEA的升级版 ,设计者是Roger Needham, David Wheeler
特点归纳:
①:原字符串长度可以不是4的倍数了
加密过程:

解题模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <stdlib.h>
#define delta 0x9e3779b9
 
int main()
{
    unsigned int v[8] = {0x10BD3B47, 0x6155E0F9, 0x6AF7EBC5, 0x8D23435F, 0x1A091605, 0xD43D40EF, 0xB4B16A67, 0x6B3578A9};
    unsigned int key[4] = {0x00001234, 0x00002345, 0x00004567, 0x00006789};
    unsigned int sum = 0;
    unsigned int y,z,p,rounds,e;
    int n = 8;
    int i = 0;
    rounds = 6 + 52/n;
    y = v[0];
    sum = rounds*delta;
     do
     {
        e = sum >> 2 & 3;
        for(p=n-1;p>0;p--)
        {
            z = v[p-1];
            v[p] -= ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p&3)^e]^z)+(y ^ sum)));
            y = v[p];
        }
        z = v[n-1];
        v[0] -= (((key[(p^e)&3]^z)+(y ^ sum)) ^ (((y<<2)^(z>>5))+((z<<4)^(y>>3))));
        y = v[0];
        sum = sum-delta;
     }while(--rounds);
 
    for(i=0;i<n;i++)
    {
        printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));
        //printf("%c%c%c%c",*((char*)&v[i]+3),*((char*)&v[i]+2),*((char*)&v[i]+1),*((char*)&v[i]+0));
    }
    return 0;
}

XXTEA例题: 2021hgame-alpacha 链接:https://pan.baidu.com/s/1H9jq_VoynN5_2rS3Kh205A
提取码:0syj

 

下面这个解题脚本没按照上面的模板写,你们可以自己改写下,懒得去改了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <stdlib.h>
#define DELTA 0x9e3779b9//0x61C88647
int main()
{
    unsigned int v[] = {0xE74EB323,0xB7A72836,0x59CA6FE2,0X967CC5C1,0XE7802674,0X3D2D54E6,0X8A9D0356,0X99DCC39C,0X7026D8ED,0x6A33FDAD,0xF496550A,0x5C9C6F9E,0x1BE5D04C,0x6723AE17,0x5270A5C2,0xAC42130A,0x84BE67B2,0x705CC779,0x5C513D98,0xFB36DA2D,0x22179645,0x5CE3529D,0XD189E1FB,0XE85BD489,0X73C8D11F,0X54B5C196,0XB67CB490,0X2117E4CA,0X9DE3F994,0X2F5AA1AA,0XA7E801FD,0XC30D6EAB,0X1BADDC9C,0X3453B04A,0X92A406F9};
    unsigned int key[] = {1,2,3,4};
    unsigned int sum = 0;
    unsigned int y,z,p,rounds,e;
    int n = 35//
    int i = 0;
    rounds = 6 + 52/n;
    y = v[0];
    sum = (rounds*DELTA)&0xffffffff;
     do                 //0x9E3779B9*(52/35)-0x4AB325AA,测试来要循环7
     {
        e = sum >> 2 & 3;
        for(p=n-1;p>0;p--)    //34次循环
        {
            z = v[p-1];
            v[p] = (v[p] - ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p^e)&3]^z)+(y ^ sum)))) & 0xffffffff;
            y = v[p];
        }
        z = v[n-1];
        v[0] = (v[0] - (((key[(p^e)&3]^z)+(y ^ sum)) ^ (((y<<2)^(z>>5))+((z<<4)^(y>>3))))) & 0xffffffff;
        y = v[0];
        sum = (sum-DELTA)&0xffffffff;
     }while(--rounds);
    for(i=0;i<n;i++)
    {
        printf("%c",v[i]);
    }
    return 0;
}
//hgame{l00ks_1ike_y0u_f0Und_th3_t34}

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

最后于 2022-10-4 19:39 被SYJ-Re编辑 ,原因: 内容更新
收藏
点赞4
打赏
分享
最新回复 (12)
雪    币: 144
活跃值: (335)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
人在塔在 2021-4-9 10:33
2
0
谢谢分享
雪    币: 493
活跃值: (860)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
_air 2021-4-9 11:31
3
0
开头的代码裂了,另外,没有题目的逆向分析过程吗?这wp一搜就有,放别人的wp有什么意思。。。图也是别人的
雪    币: 493
活跃值: (860)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
_air 2021-4-9 11:35
4
0
哦,不是wp一样,是加解密代码一样,都没改,那也过于糊弄敷衍看雪用户了吧。。。
雪    币: 493
活跃值: (860)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
_air 2021-4-9 11:41
5
0
syc的?麻烦提高下文章质量,至少不要copy别人的东西,不然你的学长学姐们会觉得丢人的。。。
雪    币: 3656
活跃值: (9205)
能力值: ( LV9,RANK:319 )
在线值:
发帖
回帖
粉丝
SYJ-Re 3 2021-4-9 13:34
6
0

题目的逆向分析过程我之后会放上去的,感谢提醒,至于你说的wp,是指第一个TEA的解密脚本吗,那你看见的极有可能是我们实验室一起学习逆向的同志的,我们经常一起讨论技术,至于你说的加解密代码一样,基本上网上用于加解密TEA的C语言代码都如出一辙,去理解它的过程即可,达到看见伪代码或汇编能一眼看出是TEA便足矣(实在不行可以安装ida插件findcrypt,不过我不喜欢,我喜欢理解本质的过程)。在此我只是将自己整理得到我的笔记上传,如果你看见了一样的文章,请仔细看一下是否是我以前的csdn。感谢提醒。

最后于 2021-4-9 13:39 被SYJ-Re编辑 ,原因:
雪    币: 72
活跃值: (245)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
A_Niucw 2022-9-27 17:57
7
0
师傅请问有没有tea第一个题目的具体分析啊,复现的时候发现动态调试到不了关键代码,或者说前面那部分的花指令怎么处理啊
雪    币: 3656
活跃值: (9205)
能力值: ( LV9,RANK:319 )
在线值:
发帖
回帖
粉丝
SYJ-Re 3 2022-10-4 18:36
8
0
我记不太清了,我发你一份我以前的idb, 链接:https://pan.baidu.com/s/1KTEm10D-HNxB7VgSKlU_dQ 
提取码:aaaa
雪    币: 3656
活跃值: (9205)
能力值: ( LV9,RANK:319 )
在线值:
发帖
回帖
粉丝
SYJ-Re 3 2022-10-4 19:40
9
0
_air syc的?麻烦提高下文章质量,至少不要copy别人的东西,不然你的学长学姐们会觉得丢人的。。。
提升了,自己看
雪    币: 999
活跃值: (1518)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
WMBa0 2023-1-26 16:26
10
0
0x61c88647  也是 tea系列的特征码,它和0x9e3779b9本质相同
雪    币: 493
活跃值: (860)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
_air 2023-7-23 13:51
11
0
SYJ-Re 提升了,自己看
雪    币: 62
活跃值: (572)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
万里星河 2023-9-21 17:07
12
0
mark
雪    币: 9
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
helphelpme 2024-3-13 14:47
13
0
xxtea的没有key能解出来吗,很想知道,谢谢大佬
游客
登录 | 注册 方可回帖
返回