TEA系列加密算法逆向

笔记

XXTEA_decrypt.py

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
from ctypes import *
def MX(z,y,sum1,k,p,e):
return c_uint32(((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))
def btea(v,k,n,delta):
if n>1:
sum1=c_uint32(0)
z=c_uint32(v[n-1])
rounds=6+52//n
e=c_uint32(0)
while rounds>0:
sum1.value+=delta
e.value=((sum1.value>>2)&3)
for p in range(n-1):
y=c_uint32(v[p+1])
v[p]=c_uint32(v[p]+MX(z,y,sum1,k,p,e).value).value
z.value=v[p]
y=c_uint32(v[0])
v[n-1]=c_uint32(v[n-1]+MX(z,y,sum1,k,n-1,e).value).value
z.value=v[n-1]
rounds-=1
else:
sum1=c_uint32(0)
n=-n
rounds=6+52//n
sum1.value=rounds*delta
y=c_uint32(v[0])
e=c_uint32(0)
while rounds>0:
e.value=((sum1.value>>2)&3)
for p in range(n-1,0,-1):
z=c_uint32(v[p-1])
v[p]=c_uint32(v[p]-MX(z,y,sum1,k,p,e).value).value
y.value=v[p]
z=c_uint32(v[n-1])
v[0]=c_uint32(v[0]-MX(z,y,sum1,k,0,e).value).value
y.value=v[0]
sum1.value-=delta
rounds-=1
return v

if __name__=='__main__':
a=[0x22A577C1,0x01C12C03,0xC74C3EBD,0xA9D03C85,0xADB8FFB3]
k=[55,66,77,88]
delta=0x9e3779b9
n=5
res=btea(a,k,-n,delta)
for i in range(len(res)):
for j in range(4):
print(chr((res[i]>>(j*8))&0x7f),end='')

TEA_decrypt.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
using namespace std;
const unsigned int key[4]={17477,16708,16965,17734},delta=0x9E3779B9;
unsigned int enc[6]={0x3e8947cb,0xcc944639,0x31358388,0x3b0b6893,0xda627361,0x3b2e6427};
void TEA_decrypt(unsigned int enc1,unsigned int enc2){
unsigned int v0=enc1,v1=enc2,sum=32*delta;
for(int i=0;i<32;i++){
v1-=((((v0<<4)+key[2])^(v0+sum)^((v0>>5)+key[3])));
v0-=((((v1<<4)+key[0])^(v1+sum)^((v1>>5)+key[1])));
sum-=delta;
};
printf("%8x%8x",v0,v1);
return;
};
int main(void){
for(int i=0;i<6;i+=2)
TEA_decrypt(enc[i],enc[i+1]);
return 0;
};

Python_TEA_en_de.py

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
from ctypes import *
from libnum import *
def encrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x9e3779b9
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(0)
for i in range(32):
total.value += delta
v0.value += ((v1.value << 4) + k0) ^ (v1.value + total.value) ^ ((v1.value >> 5) + k1)
v1.value += ((v0.value << 4) + k2) ^ (v0.value + total.value) ^ ((v0.value >> 5) + k3)
return v0.value, v1.value
def decrypt(v, k):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0xABCDEF23
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
total = c_uint32(delta * 32)
for i in range(32):
v1.value -= ((v0.value << 4) + k2) ^ (v0.value + total.value) ^ ((v0.value >> 5) + k3)
v0.value -= ((v1.value << 4) + k0) ^ (v1.value + total.value) ^ ((v1.value >> 5) + k1)
total.value -= delta
return v0.value, v1.value
# test
if __name__ == "__main__":
# 需要注意的是这里数据读取的顺序
va = [0xE4B36920, 0x936924D0,
0xA816D144, 0xAA82D5F5,
0x3679F0DA, 0x7F32FD06,
0x3460C0D3, 0xB7214939,
0xE57269A2, 0x836A51FA]
# 四个key,每个是32bit,即密钥长度为128bit
key = [22, 33, 44, 55]
flag=''
#res = encrypt(value, key)
#print("Encrypted data is : ", hex(res[0]), hex(res[1]))
for i in range(0,len(va),2):
res = decrypt([va[i],va[i+1]], key)
flag+=str((n2s(res[0])[::-1] + n2s(res[1])[::-1]))[2:10]
print(flag)

做题

[MoeCTF 2022]ezTea

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
#include <cstdio>
#include <stdint.h>
using namespace std;
unsigned int k[4]={1,2,3,4};
char input[32]={0x17,0x65,0x54,0x89,0xed,0x65,0x46,0x32,0x3d,0x58,0xa9,0xfd,0xe2,0x5e,
0x61,0x97,0xe4,0x60,0xf1,0x91,0x73,0xe9,0xe9,0xa2,0x59,0xcb,0x9a,0x99,
0xec,0xb1,0xe1,0x7d};
void decrypt(unsigned int* v,unsigned int* k){
unsigned int v0 = v[0], v1 = v[1], delta = 0xd33b470,sum = delta*32;
for (int i = 0; i < 32; i++) {
v1-=((v0<<4) + k[2]) ^ (v0 + sum) ^ ((v0>>5) + k[3]);
v0-=((v1<<4) + k[0]) ^ (v1 + sum) ^ ((v1>>5) + k[1]);
sum-=delta;
};
v[0] = v0;
v[1] = v1;
return;
};
int main(void){
for(register int j=0;j<32;j+=8){
unsigned int v[2]={*(unsigned int *)&input[j],*(unsigned int *)&input[j+4]};
decrypt(v,k);
for(register int i=0;i<4;i++){
printf("%c",v[0]&0xff);
v[0]>>=8;
};
for(register int i=0;i<4;i++){
printf("%c",v[1]&0xff);
v[1]>>=8;
};
};
return 0;
};

[HGAME 2023 week1]a_cup_of_tea

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <cstdio>
using namespace std;
unsigned int enc[8]={0x2E63829D,0xC14E400F,0x9B39BFB9,0x5A1F8B14,0x61886DDE,0x6565C6CF,0x9F064F64,0x236A43F6},key[4]={0x12345678,0x23456789,0x134567890,0x45678901},va[2];
void decrypt(unsigned int *v,unsigned int *key){
unsigned int delta=0xabcdef23,sum=32*delta;
for(register int i=0;i<32;i++)
v[1]-=((v[0]<<4)+key[2])^(v[0]+sum)^((v[0]>>5)+key[3]),
v[0]-=((v[1]<<4)+key[0])^(v[1]+sum)^((v[1]>>5)+key[1]),
sum-=delta;
return;
};
int main(void){
for(register int i=0;i<8;i+=2){
va[0]=enc[i],
va[1]=enc[i+1];
decrypt(va,key);
printf("%x\n%x\n",va[0],va[1]);
};
return 0;
};

[HNCTF 2022 WEEK3]What’s 1n DLL?

DLL装载:dll文件二进制打开,发现UPX壳字段变成了UFO,修复后脱壳,找到主程序中的ttt函数,分析发现为XXTEA加密,得:

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
from ctypes import *
def MX(z,y,sum1,k,p,e):
return c_uint32(((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))
def btea(v,k,n,delta):
if n>1:
sum1=c_uint32(0)
z=c_uint32(v[n-1])
rounds=6+52//n
e=c_uint32(0)
while rounds>0:
sum1.value+=delta
e.value=((sum1.value>>2)&3)
for p in range(n-1):
y=c_uint32(v[p+1])
v[p]=c_uint32(v[p]+MX(z,y,sum1,k,p,e).value).value
z.value=v[p]
y=c_uint32(v[0])
v[n-1]=c_uint32(v[n-1]+MX(z,y,sum1,k,n-1,e).value).value
z.value=v[n-1]
rounds-=1
else:
sum1=c_uint32(0)
n=-n
rounds=6+52//n
sum1.value=rounds*delta
y=c_uint32(v[0])
e=c_uint32(0)
while rounds>0:
e.value=((sum1.value>>2)&3)
for p in range(n-1,0,-1):
z=c_uint32(v[p-1])
v[p]=c_uint32(v[p]-MX(z,y,sum1,k,p,e).value).value
y.value=v[p]
z=c_uint32(v[n-1])
v[0]=c_uint32(v[0]-MX(z,y,sum1,k,0,e).value).value
y.value=v[0]
sum1.value-=delta
rounds-=1
return v

if __name__=='__main__':
a=[0x22A577C1,0x01C12C03,0xC74C3EBD,0xA9D03C85,0xADB8FFB3]
k=[55,66,77,88]
delta=0x9e3779b9
n=5
res=btea(a,k,-n,delta)
for i in range(len(res)):
for j in range(4):
print(chr((res[i]>>(j*8))&0x7f),end='')

[HNCTF 2022 WEEK3]Try2debugPlusPlus

XTEA加密,密钥反调试,但是把密钥直接告诉我了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <cstdio>
using namespace std;
unsigned int enc[12]={0xDAD5B6C5,0x0CE5F717,0x8BE8AF6B,0xD74C6EB4,0xEEB8B5A0,0xA07618E0,0x1B425FD0,0xC0B77641,0xA30FA9BE,0xCB4F5089,0xEBF9EC1D,0xF870EF3D},key[4]={0x91,0x71,0x11,0xBB};
void decrypt(const int k1,const int k2){
unsigned int v0=enc[k1],v1=enc[k2],delta=0x79B99E37,sum=delta*32;
for(register int i=0;i<32;i++)
v1-=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]),
sum-=delta,
v0-=(((v1<<4)^(v1>>5))+v1)^(sum+key[sum&3]);
enc[k1]=v0,
enc[k2]=v1;
return;
};
int main(void){
for(register int i=0;i<6;i++)
decrypt(i*2,i*2+1);
for(register int i=0;i<12;i++)
printf("%c",enc[i]);
return 0;
};

[FSCTF 2023]Tea_apk

XXTEA+Base64。很遗憾不知道为啥exp写得不对,只好在线解密。

[SUSCTF 2022]DigitalCircuits

数电题,仔细推敲后代码大约长这样:

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
62
63
64
65
66
67
68
69
70
71
72
73
74
import time
def fand(a, b):
if a == '1':
if b == '1':
return '1'
return '0'
def f_or(a, b):
if a == '0':
if b == '0':
return '0'
return '1'
def frev(a):
if a == '1':
return '0'
if a == '0':
return '1'
def fxor(a, b):
return f_or(fand(a, frev(b)), fand(frev(a), b))
def f5(x, y, z):
s = fxor(fxor(x, y), z)
c = f_or(fand(x, y), fand(z, f_or(x, y)))
return (s, c)
def fadd(a, b):
ans = ''
z = '0'
a = a[::-1]
b = b[::-1]
for i in range(32):
ans += f5(a[i], b[i], z)[0]
z = f5(a[i], b[i], z)[1]
return ans[::-1]
def fshl(a, n):
return a[n:] + '0' * n
def fshr(a, n):
return n * '0' + a[:-n]
def fxor_int(a, b):
ans = ''
for i in range(32):
ans += fxor(a[i], b[i])
return ans
def TEA_encrypt(v0, v1, k0, k1, k2, k3):
s = '00000000000000000000000000000000'
d = '10011110001101110111100110111001' #0x9E3779B9
for i in range(32):
s = fadd(s, d)
v0 = fadd(v0, fxor_int(fxor_int(fadd(fshl(v1, 4), k0), fadd(v1, s)), fadd(fshr(v1, 5), k1)))
v1 = fadd(v1, fxor_int(fxor_int(fadd(fshl(v0, 4), k2), fadd(v0, s)), fadd(fshr(v0, 5), k3)))
return v0 + v1
k0 = '0100010001000101'.zfill(32) #17477
k1 = '0100000101000100'.zfill(32) #16708
k2 = '0100001001000101'.zfill(32) #16965
k3 = '0100010101000110'.zfill(32) #17734
flag = input('please input flag:')
if flag[0:7] != 'SUSCTF{' or flag[-1] != '}':
print('Error!!!The formate of flag is SUSCTF{XXX}')
time.sleep(5)
exit(0)
flagstr = flag[7:-1]
if len(flagstr) != 24:
print('Error!!!The length of flag 24')
time.sleep(5)
exit(0)
else:
res = ''
for i in range(0, len(flagstr), 8):
v0 = flagstr[i:i + 4]
v0 = bin(ord(flagstr[i]))[2:].zfill(8) + bin(ord(flagstr[i + 1]))[2:].zfill(8) + bin(ord(flagstr[i + 2]))[2:].zfill(8) + bin(ord(flagstr[i + 3]))[2:].zfill(8)
v1 = bin(ord(flagstr[i + 4]))[2:].zfill(8) + bin(ord(flagstr[i + 5]))[2:].zfill(8) + bin(ord(flagstr[i + 6]))[2:].zfill(8) + bin(ord(flagstr[i + 7]))[2:].zfill(8)
res += TEA_encrypt(v0, v1, k0, k1, k2, k3)
if res == '001111101000100101000111110010111100110010010100010001100011100100110001001101011000001110001000001110110000101101101000100100111101101001100010011100110110000100111011001011100110010000100111': #3e8947cb cc944639 31358388 3b0b6893 da627361 3b2e6427
print('True')
else:
print('False')
time.sleep(5)

是个标准的TEA加密,解密即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
using namespace std;
const unsigned int key[4]={17477,16708,16965,17734},delta=0x9E3779B9;
unsigned int enc[6]={0x3e8947cb,0xcc944639,0x31358388,0x3b0b6893,0xda627361,0x3b2e6427};
void TEA_decrypt(unsigned int enc1,unsigned int enc2){
unsigned int v0=enc1,v1=enc2,sum=32*delta;
for(int i=0;i<32;i++){
v1-=((((v0<<4)+key[2])^(v0+sum)^((v0>>5)+key[3])));
v0-=((((v1<<4)+key[0])^(v1+sum)^((v1>>5)+key[1])));
sum-=delta;
};
printf("%8x%8x",v0,v1);
return;
};
int main(void){
for(int i=0;i<6;i+=2)
TEA_decrypt(enc[i],enc[i+1]);
return 0;
};

[HGAME 2023 week4]shellcode

太抽象了这题,Base64解码出的二进制反汇编得TEA加密。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
using namespace std;
const unsigned int key[4]={22,33,44,55},delta=0x543210DD;
unsigned int enc[10]={0xE4B36920,0x936924D0,0xA816D144,0xAA82D5F5,0x3679F0DA,0x7F32FD06,0x3460C0D3,0xB7214939,0xE57269A2,0x836A51FA};
void TEA_decrypt(unsigned int enc1,unsigned int enc2){
unsigned int v0=enc1,v1=enc2,sum=-32*delta;
for(int i=0;i<32;i++){
v1-=((((v0<<4)+key[2])^(v0+sum)^((v0>>5)+key[3])));
v0-=((((v1<<4)+key[0])^(v1+sum)^((v1>>5)+key[1])));
sum+=delta;
};
printf("%8x%8x",v0,v1);
return;
};
int main(void){
for(int i=0;i<10;i+=2)
TEA_decrypt(enc[i],enc[i+1]);
return 0;
};

[GWCTF 2019]xxor

先解方程组:

1
2
3
4
5
6
7
8
9
10
from z3 import *
s=Solver()
a2,a3,a4=Ints('a2 a3 a4')
s.add(a2-a3==0x84A236FF)
s.add(a3+a4==0xFA6CB703)
s.add(a2-a4==0x42D731A8)
s.check()
print(s.model())
#[a2 = 3774025685, a3 = 1548802262, a4 = 2652626477]
#0xE0F30FD5 0x5C50D8D6 0x9E1BDE2D

然后TEA魔改解密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
using namespace std;
const unsigned int keys[4]={2,2,3,4},delta=0x458BCD42;
unsigned int enc[6]={0xDF48EF7E,0x20CAACF4,0xE0F30FD5,0x5C50D8D6,0x9E1BDE2D,0x84F30420};
void TEA_decrypt(unsigned int enc1,unsigned int enc2){
unsigned int v0=enc1,v1=enc2,sum=(0x3F+1)*delta;
for(int i=0;i<(0x3F+1);i++){
v1-=(v0+sum+20)^((v0<<6)+keys[2])^((v0>>9)+keys[3])^0x10;
v0-=(v1+sum+11)^((v1<<6)+keys[0])^((v1>>9)+keys[1])^0x20;
sum-=delta;
};
printf("%x%x",v0,v1);
return;
};
int main(void){
for(int i=0;i<6;i+=2)
TEA_decrypt(enc[i],enc[i+1]);
return 0;
};

[GDOUCTF 2023]Tea

魔改TEA。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <cstdio>
using namespace std;
const unsigned int key[4]={2233,4455,6677,8899},delta=0xF462900;
unsigned int enc[10]={0x1A800BDA,0xF7A6219B,0x491811D8,0xF2013328,0x156C365B,0x3C6EAAD8,0x84D4BF28,0xF11A7EE7,0x3313B252,0xDD9FE279},j,sum;
int main(void){
for(register int i=8;i>=0;i--){
sum=delta*(i+33),
j=i+1;
for(register int cnt=0;cnt<33;cnt++)
sum-=delta,
enc[j]-=(sum+key[(sum>>11)&3])^(enc[i]+((enc[i]>>5)^(enc[i]<<4))),
enc[i]-=sum^(enc[j]+((enc[j]>>5)^(enc[j]<<4))^(sum+key[sum&3]));
};
for(register int i=0;i<10;i++)
printf("%X",enc[i]);
return 0;
};

[HNCTF 2022 WEEK2]TTTTTTTTTea

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
using namespace std;
const unsigned int key[4]={0x10203,0x4050607,0x8090A0B,0x0C0D0E0F},delta=0x61C88647;
unsigned int enc[6]={0xC11EE75A,0xA4AD0973,0xF61C9018,0x32E37BCD,0x2DCC1F26,0x344380CC};
void TEA_decrypt(unsigned int enc1,unsigned int enc2){
unsigned int v0=enc1,v1=enc2,sum=-32*delta;
for(int i=0;i<32;i++){
v1-=(((v0>>5)^(v0<<4))+v0)^(key[(sum>>11)&3]+sum),
sum+=delta,
v0-=(((v1>>5)^(v1<<4))+v1)^(key[sum&3]+sum);
};
printf("%8x%8x",v0,v1);
return;
};
int main(void){
for(int i=0;i<6;i+=2)
TEA_decrypt(enc[i],enc[i+1]);
return 0;
};