更新原因: 那就回过头提升下文章质量吧,之前确实写的不好
简介:一种分组加密算法,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
下面这个解题脚本没按照上面的模板写,你们可以自己改写下,懒得去改了
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;
}
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;
}
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
;
}
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
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
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
;
}
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
;
}
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)
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-10-4 19:39
被SYJ-Re编辑
,原因: 内容更新