Tea类型加密
        很早就想概括tea类型加密了,对于很多刚开始做逆向的新手来说,这个掌握好了解题确实快,不像之前的我找到了key,密文,算法,还是因为小错误,而解不出来。作为最基础,也是最常见的加密,确实需要好好总结一番的喵~!

Tea
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | void encrypt(unsigned int* v, unsigned int* key) {   unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;   for (int i = 0; i < 32; i++) {     sum += delta;     l += ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);     r += ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);   }   v[0] = l;   v[1] = r; }   void decrypt(unsigned int* v, unsigned int* key) {   unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;   sum = delta *32;   for (int i = 0; i < 32; i++) {     r -= ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);     l -= ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);     sum -= delta;   }   v[0] = l;   v[1] = r; }
  | 
 
其实是一个移位+错位+异或操作结合的算法,逆向解密也是十分容易,将flag以4个unsigned char为一组转为unsigned int加密,注意小端序。
给出一个我常用的解密脚本
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
   | #include<stdio.h> int main(){     int n; 	unsigned int pw[]={}; 	unsigned int v0; 	unsigned int v1; 	unsigned int sum;     unsigned int key[4]={1,2,3,4}; 	for(int i=0;i<n/2;i++) 	{ 		v0=pw[2*i]; 		v1=pw[2*i+1]; 		sum=-32*0x61C88647; 		for(int i=0;i<32;i++) 		{ 			v1 -= ((v0 >> 5) + key[3] )^ (16 * v0 + key[2]) ^ (sum + v0); 			v0 -= ((v1 >> 5) + key[1]) ^ (16 * v1 + key[0]) ^ (sum + v1); 			sum += 0x61C88647; 		} 		for (int j = 0; j<=3; j++) 		{ 			printf("%c", (v0 >> (j * 8)) & 0xFF); 		} 		for (int j = 0; j<=3; j++) 		{ 			printf("%c", (v1 >> (j * 8)) & 0xFF); 		} 	} }
   | 
 
大多数题目都是给出偶数个unsigned int(4个字节)的密文m,每两段为一组,每一段密文对应的都是4个字母的flag。
这里再给一个python的脚本(我不怎么常用)
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
   | from ctypes import *  from Crypto.Util.number import * def encrypt(v,k): 	v0=c_uint32(v[0]) 	v1=c_uint32(v[1]) 	sum1=c_uint32(0) 	delta=0x9e3779b9   	for i in range(32): 		sum1.value+=delta 		v0.value+=((v1.value<<4)+k[0])^(v1.value+sum1.value)^((v1.value>>5)+k[1]) 		v1.value+=((v0.value<<4)+k[2])^(v0.value+sum1.value)^((v0.value>>5)+k[3]) 	return v0.value,v1.value   def decrypt(v,k): 	v0=c_uint32(v[0]) 	v1=c_uint32(v[1]) 	delta=0x9e3779b9  	sum1=c_uint32(delta*40) 	for i in range(40): 		v1.value-=((v0.value<<5)+k[2])^(v0.value+sum1.value)^((v0.value>>5)+k[3]) 		v0.value-=((v1.value<<5)+k[0])^(v1.value+sum1.value)^((v1.value>>5)+k[1]) 		sum1.value-=delta 	return v0.value,v1.value   if __name__=='__main__':     k=[2,0,2,3]
      flag=b''     res=[0x76B9621A, 0xCCE4ADDE, 0x25C8BFC8, 0x16C2D472, 0xF317D53A, 0xF2A111A1, 0xDF89F0E6, 0xDCCDA623, 0x21C2F409, 0xDBD88D63]     for i in range(len(res)//2):          d = decrypt(res[2*i:2*(i+1)], k)          flag += long_to_bytes(d[0])[::-1]+long_to_bytes(d[1])[::-1]     flag += long_to_bytes(res[-1])[::-1]     print(flag)
   | 
 
xTea
其实跟tea差不多,只是加密方式变了一下
简单给出加密方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | unsigned int n; unsigned int flag[n]; unsigned int key[4]; unsigned int v0,v1; unsigned int delta = 0x9E3779B9; for (int j = 0; j < n; j=j+2) {     v0 = flag[j], v1 = flag[j+1]     unsigned sum = 0;      for (int i = 0; i < 32; i++) {         v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);         sum += delta;         v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);         } flag[j] = v0; flag[j+1] = v1; }     
   | 
 
下面是解密脚本
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
   | #include<stdio.h> int main() { 	unsigned int enc[] = {}; 	int n; 	unsigned int key[4] = {}; 	int i, j; 	long sum = 0, delta = 0x61C88647; 	for(i=0;i <n;i+=2) 	{ 		sum = (32 * delta); 		for(j = 0; j < 32; j++)  		{ 			sum -= delta; 			enc[i] -= (((enc[i+1] >> 5) ^ (16 * enc[i+1])) + enc[i+1]) ^ (key[(sum & 3)] + sum); 			enc[i+1] -= (((enc[i] >> 5) ^ (16 * enc[i])) + enc[i]) ^ (key[((sum >> 11) & 3)] + sum); 		} 	} 	 	for (i = 0; i <n; i++) 	{ 		for (j = 0; j<=3; j++) 		{ 			printf("%c", (enc[i] >> (j * 8)) & 0xFF); 		} 	} 	return 0; }
   | 
 
xxTea
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | void xxtea_encrypt(unsigned int *v, int n, unsigned int key[4]) {     unsigned int y, z, sum;     unsigned int delta=0x9e3779b9     unsigned int p, rounds, e;     rounds = 6 + 52 / n;     sum = 0;     z = v[n - 1];     do {         sum += delta;         e = (sum >> 2) & 3;         for (p = 0; p < n - 1; p++) {             y = v[p + 1];             z = v[p] += (y >> 5 ^ (z << 2)) + (y << 3 ^ (z >> 4)) ^ (sum ^ y) + (key[(p & 3) ^ e] ^ z);         }         y = v[0];         z = v[n - 1] += (y >> 5 ^ (z << 2)) + (y << 3 ^ (z >> 4)) ^ (sum ^ y) + (key[(p & 3) ^ e] ^ z);     } while (--rounds); }
  | 
 
脚本
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
   | #include <stdio.h> #include <stdlib.h> #define delta 0x9e3779b9   int main() {     unsigned int v[8] = {0x10BD3B47, 0x6155E0F9, 0x6AF7EBC5, 0x8D23435F, 0x1A091605, 0xD43D40EF, 0xB4B16A67, 0x6B3578A9};     unsigned int key[4] = {0x00001234, 0x00002345, 0x00004567, 0x00006789};     unsigned int sum = 0;     unsigned int y,z,p,rounds,e;     int n = 8;     int i = 0;     rounds = 6 + 52/n;     y = v[0];     sum = rounds*delta;      do      {         e = sum >> 2 & 3;         for(p=n-1;p>0;p--)         {             z = v[p-1];             v[p] -= ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p&3)^e]^z)+(y ^ sum)));             y = v[p];         }         z = v[n-1];         v[0] -= (((key[(p^e)&3]^z)+(y ^ sum)) ^ (((y<<2)^(z>>5))+((z<<4)^(y>>3))));         y = v[0];         sum = sum-delta;      }while(--rounds);     for(i=0;i<n;i++)     {         printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));              }     return 0; }
   | 
 
例题
2023极客大挑战myslef(tea)

SMC后明显一个tea,甚至密钥都写上去了
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
   | #include<stdio.h> int main(){ 	unsigned int pw[8]={0xBDBDF9F0, 0xE26194C4, 0x80799125, 0x1F0FC219, 0xEB6A1815, 0x84F572C5, 0x40CC3A85, 0xD2A32ABB}; 	unsigned int v0; 	unsigned int v1; 	unsigned int sum; 	unsigned int key[4]={2,2,3,4}; 	for(int i=0;i<4;i++) 	{ 		v0=pw[2*i]; 		v1=pw[2*i+1]; 		sum=-32*0x61C88647; 		for(int i=0;i<32;i++) 		{ 			v1 -= ((v0 >> 5) + key[3] )^ (16 * v0 + key[2]) ^ (sum + v0); 			v0 -= ((v1 >> 5) + key[1]) ^ (16 * v1 + key[0]) ^ (sum + v1); 			sum += 0x61C88647; 		} 		for (int j = 0; j<=3; j++) 		{ 			printf("%c", (v0 >> (j * 8)) & 0xFF); 		} 		for (int j = 0; j<=3; j++) 		{ 			printf("%c", (v1 >> (j * 8)) & 0xFF); 		} 	} }
 
   | 
 
