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

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

2021-4-9 02:30
50832

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

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

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

下面是某题flag2WP:

魔改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用于下一轮的解密
解题脚本:

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

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

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

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

解题模板:

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

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

#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;
}
#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;
}
#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;
}
#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;
}
该题文件以及详细解题过程:
链接: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;
}
该题文件以及详细解题过程:
链接: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;
}
 
#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;
}
#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)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

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

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

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