0x01 简介
TEA全称Tiny Encrypt Algorithm。在CTF逆向分析中经常会出现Tea或者魔改了DELTA的TEA算法。
0x02 算法原理
明文长度分组为64位(8字节),密钥长度为128位(16字节),明文和密钥进入32轮循环,得到最后的64位密文。其中magic number DELTA是由黄金分割点得到。
算法比较简单源码如下
#include<stdio.h>
#include<stdint.h>
#define DELTA 0x9981abcd
void tea_encrypt(unsigned int* v, unsigned int* key) {
unsigned int l = v[0], r = v[1], sum = 0;
for (size_t i = 0; i < 32; i++) { //进行32次迭代加密,Tea算法作者的建议迭代次数
l += (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
sum += DELTA; //累加Delta的值
r += (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]); //利用多次双位移和异或将明文与密钥扩散混乱,并将两个明文互相加密
}
v[0] = l;
v[1] = r;
}
void tea_decrypt(unsigned int* v, unsigned int* key) {
unsigned int l = v[0], r = v[1], sum = 0;
sum = DELTA * 32; //32次迭代累加后delta的值
for (size_t i = 0; i < 32; i++) {
r -= (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
sum -= DELTA;
l -= (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
}
v[0] = l;
v[1] = r;
}
int main(int argc, char const *argv[])
{
unsigned int key1[4]={0xa3eeb7be,0x50e7de9a,0x6dbcc2bc,0x78591fad};//key1
unsigned int key2[4]={0x78591fad,0x6dbcc2bc,0xa3eeb7be,0x50e7de9a};//key2
unsigned int v1[2] = {0x556E2853,0x4393DF16};
unsigned int v2[2] = {0x1989FB2B,0x83F5A243};
//encrypt(v1,key1);
//printf("tea_encrypt:%x %x\n",v1[0],v1[1]);
//encrypt(v2,key2);
//printf("tea_encrypt:%x %x\n",v2[0],v2[1]);
tea_decrypt(v1,key1);
printf("tea_decrypt:%x %x\n",v1[0],v1[1]);
tea_decrypt(v2,key2);
printf("tea_decrypt:%x %x\n",v2[0],v2[1]);
return 0;
}
//tea_decrypt:c0cacd59 38bb7623
//tea_decrypt:8757d16 a520cece
}
0x03 逆向分析识别tea算法
这次我在windows上用gcc tea.c -o tea.exe编译生成对应的程序。
利用PEiD的插件KANAL识别,能够识别出存在tea算法
下面用ida pro来识别一下tea算法。能够识别到tea中的常数,DELTA,
tea_encrypt
tea算法最关键的是要找到DELTA值和128位的key。
key明显是传进来的参数a2,当然程序的key不是参数传入,(4i64 * (v4 & 3) + a2) 可以知道a2是一个int数组,就是key
DELTA的识别,分析成的v4 -= 0x61C88647而不是我们源码中的sum += DELTA; ,通过简单计算可以得到v4 -= 0x61C88647和v4 += 0x9e3779b9 是等价的
0x04 逆向分析识别魔改tea算法
tea算法可以魔改的地方主要是DELTA值,很多时候都会将这个值修改,让很多加密算法识别软件失效。下面就将DELTA魔改为0x1234567。
利用PEiD的插件KANAL识别,因为DELTA被修改了所以无法识别
ida pro也没有识别出来
tea_encrypt
关键还是DELTA和key的识别。有对源码的了解可以很容易的识别出DELTA为0x1234567,key为a2
0x05 总结
如果tea没有魔改,通过插件就能识别到对应的。
如果tea被魔改过,可以通过算法的结构找到DELTA和key
参考
《加密与解密第四版》