解析 TEA 加密算法(C语言、python):_tea加密-CSDN博客
CTF-RE 从0到N: TEA_tea加密原理-CSDN博客
1 字节 = 8 位
牢记密文的64位和密钥的128位,最好可以自己独立的写出tea解密代码
相当于密文是传入8个字符类型数据或者是2个整型数据,
密钥是16个字符数据或者4个整型数据,
一.drink_tea
blob:https://ctf.xidian.edu.cn/7ae7c1a9-61a8-4343-be1f-a4ce1fafcf7e
int __fastcall main(int argc, const char **argv, const char **envp)
{__int64 v3; // rdx__int64 v4; // r8__int64 v6; // rdx__int64 v7; // r8int i; // [rsp+20h] [rbp-28h]__int64 v9; // [rsp+28h] [rbp-20h]sub_140001070(aPleaseInput, argv, envp);sub_140001120("%32s", byte_140004700);v9 = -1i64;do++v9;while ( byte_140004700[v9] );if ( v9 == dword_140004078 ){for ( i = 0; i < dword_140004078; i += 8 )sub_140001180(&byte_140004700[i], aWelcometonewst);if ( !memcmp(byte_140004700, &unk_140004080, dword_140004078) )sub_140001070(aRight, v6, v7);elsesub_140001070(aWrong_0, v6, v7);return 0;}else{sub_140001070(aWrong, v3, v4);return 0;}
}
int __fastcall main(int argc, const char **argv, const char **envp)
{__int64 v3; // rdx__int64 v4; // r8__int64 v6; // rdx__int64 v7; // r8int i; // [rsp+20h] [rbp-28h]__int64 v9; // [rsp+28h] [rbp-20h]printf(Format, argv, envp);scanf("%32s", falg);v9 = -1i64;do++v9;while ( falg[v9] );if ( v9 == len ){for ( i = 0; i < len; i += 8 )encrypt(&falg[i], aWelcometonewst);if ( !memcmp(falg, &miwen, len) )printf(aRight, v6, v7);elseprintf(aWrong_0, v6, v7);return 0;}else{printf(aWrong, v3, v4);return 0;}
}
分析了一下修改了函数名,查看密文和长度
查看加密函数
__int64 __fastcall encrypt(unsigned int *a1, _DWORD *a2)
{__int64 result; // raxunsigned int v3; // [rsp+0h] [rbp-38h]unsigned int v4; // [rsp+4h] [rbp-34h]int v5; // [rsp+8h] [rbp-30h]unsigned int i; // [rsp+Ch] [rbp-2Ch]v3 = *a1;v4 = a1[1];v5 = 0;for ( i = 0; i < 0x20; ++i ){v5 -= 1640531527;v3 += (a2[1] + (v4 >> 5)) ^ (v5 + v4) ^ (*a2 + 16 * v4);v4 += (a2[3] + (v3 >> 5)) ^ (v5 + v3) ^ (a2[2] + 16 * v3);}*a1 = v3;result = 4i64;a1[1] = v4;return result;
}
是tea加密,密文是32个字符类型数据,密钥是16个字符类型数据,让后学到了新的代码
uint32_t:32位无符号整数
uint32_t
是一个在 C 语言标准库<stdint.h>
中定义的类型,可以处理特定大小数据,就比如tea中的密文和密钥
写代码
#include<stdio.h>
#include<stdint.h>
void decrypt(uint32_t *a1,uint32_t *a2)
{uint32_t v3; // [rsp+0h] [rbp-38h]uint32_t v4; // [rsp+4h] [rbp-34h]int v5; // [rsp+8h] [rbp-30h]uint32_t i; // [rsp+Ch] [rbp-2Ch]v3 = a1[0];v4 = a1[1];v5 = -1640531527*32;for ( i = 0; i < 32; ++i ){v4 -= (a2[3] + (v3 >> 5)) ^ (v5 + v3) ^ (a2[2] + 16 * v3);v3 -= (a2[1] + (v4 >> 5)) ^ (v5 + v4) ^ (a2[0] + 16 * v4);v5 += 1640531527;}a1[0] = v3;a1[1] = v4;
}
int main()
{unsigned char a[]={120, 32, 247, 179, 197, 66, 206, 218, 133, 89, 33, 26, 38, 86, 90, 89, 41, 2, 13, 237, 7, 168, 185, 238, 54, 89, 17, 135, 253, 92, 35, 36};unsigned char key[]="WelcomeToNewStar";int i;uint32_t *v=(uint32_t*)a;uint32_t *k=(uint32_t*)key;for(i=0;i<8;i+=2){decrypt(v+i,k);}for(i=0;i<32;i++){printf("%c",a[i]);}
}
flag{There_R_TEA_XTEA_and_XXTEA}
二.xtea
int __fastcall main_0(int argc, const char **argv, const char **envp)
{char *v3; // rdi__int64 i; // rcx__int64 v5; // rax__int64 v6; // rax__int64 v7; // rax__int64 v8; // rax__int64 v10; // raxchar v11; // [rsp+20h] [rbp+0h] BYREFunsigned int v12; // [rsp+24h] [rbp+4h]char Str[48]; // [rsp+48h] [rbp+28h] BYREFint v14[12]; // [rsp+78h] [rbp+58h] BYREFchar Src[32]; // [rsp+A8h] [rbp+88h] BYREFchar v16[28]; // [rsp+C8h] [rbp+A8h] BYREFint j; // [rsp+E4h] [rbp+C4h]v3 = &v11;for ( i = 58i64; i; --i ){*v3 = -858993460;v3 += 4;}j___CheckForDebuggerJustMyCode(&unk_140028066, argv, envp);v12 = 32;memset(Str, 0, 0xDui64);v5 = sub_1400110AA(std::cout, "please input key:");std::ostream::operator<<(v5, sub_140011046);sub_14001153C(std::cin, Str);v14[0] = 2;v14[1] = 0;v14[2] = 2;v14[3] = 4;v6 = sub_1400110AA(std::cout, "let me check your key");std::ostream::operator<<(v6, sub_140011046);v7 = sub_1400110AA(std::cout, "emmm");std::ostream::operator<<(v7, sub_140011046);if ( j_strlen(Str) == 12 ){memset(v16, 0, 8ui64);j_memcpy(Src, Str, 8ui64);sub_14001119F(v12, Src, v14);j_memcpy(Str, Src, 8ui64);j_memcpy(v16, &Str[4], 8ui64);sub_14001119F(v12, v16, v14);j_memcpy(&Str[4], v16, 8ui64);for ( j = 0; j < 12; ++j ){if ( Str[j] != byte_140022000[j] )goto LABEL_5;}v10 = sub_1400110AA(std::cout, "Correct key! Your flag is moectf{your key}");std::ostream::operator<<(v10, sub_140011046);return 0;}else{
LABEL_5:v8 = sub_1400110AA(std::cout, "XD,wrong!");std::ostream::operator<<(v8, sub_140011046);return 0;}
}
是c++代码,猜测关键地方
进入sub_14001119F函数有xtea加密
__int64 __fastcall sub_1400148C0(unsigned int a1, unsigned int *a2, __int64 a3)
{__int64 result; // raxunsigned int i; // [rsp+24h] [rbp+4h]unsigned int v5; // [rsp+44h] [rbp+24h]unsigned int v6; // [rsp+64h] [rbp+44h]unsigned int v7; // [rsp+84h] [rbp+64h]j___CheckForDebuggerJustMyCode(&unk_140028066, a2, a3);v5 = *a2;v6 = a2[1];v7 = 0;for ( i = 0; i < a1; ++i ){v5 += (*(a3 + 4i64 * (v7 & 3)) + v7) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));v7 -= 855655493;v6 += (*(a3 + 4i64 * ((v7 >> 11) & 3)) + v7) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));}*a2 = v5;result = 4i64;a2[1] = v6;return result;
}
写注释来分析,其中
8ui64分析是对“8个无符号的64位整数”的非正式简写。这里的“ui64”通常指的是一个无符号的64位整数,而“8”表示数量。
由于一个无符号的64位整数占用8个字节(因为64位等于8字节),那么“8ui64”就意味着8个这样的64位整数。因此,计算总字节数是64字节
但是密文就只有12个字符是64字节,其中他还分了前后8位进行加密运算,所以合理猜测是表示有误,我们按照一般思路来解题目;
写代码
#include<stdio.h>
#include<stdint.h>
void decrypt( uint32_t *a2, int* a3)
{int i; // [rsp+24h] [rbp+4h]uint32_t v5; // [rsp+44h] [rbp+24h]uint32_t v6; // [rsp+64h] [rbp+44h]int v7; // [rsp+84h] [rbp+64h]v5 = *a2;v6 = a2[1];v7 = -855655493*32;for ( i = 0; i < 32; ++i ){v6 -= (a3[(v7 >> 11) & 3] + v7) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));v7 += 855655493;v5 -= (a3[v7 & 3] + v7) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));}*a2 = v5;a2[1] = v6;}
int main()
{unsigned char miwen[] ={163, 105, 150, 38, 189, 120, 11, 61, 157, 165, 40, 98, };int key[]={2,0,2,4};int i;uint32_t*v=(uint32_t*)miwen;decrypt(v+1,key);decrypt(v,key);for(i=0;i<12;i++){printf("%c",miwen[i]);}
}
moectf2024!!
让后结合输出的格式
moectf{moectf2024!!}
之后遇到了有价值的题目再总结于此吧