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); } } }
|