当前位置: 首页 > news >正文

TEA系列例题

解析 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!!}

三.[GWCTF 2019]xxor1

https://files.buuoj.cn/files/baba20fce498e7b1d5ad774fcb5bc89e/attachment

一般查壳,ida分析

__int64 __fastcall main(int a1, char **a2, char **a3)
{int i; // [rsp+8h] [rbp-68h]int j; // [rsp+Ch] [rbp-64h]__int64 v6[6]; // [rsp+10h] [rbp-60h] BYREF__int64 v7[6]; // [rsp+40h] [rbp-30h] BYREFv7[5] = __readfsqword(0x28u);puts("Let us play a game?");puts("you have six chances to input");puts("Come on!");memset(v6, 0, 40);for ( i = 0; i <= 5; ++i ){printf("%s", "input: ");a2 = (v6 + 4 * i);__isoc99_scanf("%d", a2);}memset(v7, 0, 40);for ( j = 0; j <= 2; ++j ){dword_601078 = v6[j];dword_60107C = HIDWORD(v6[j]);a2 = &unk_601060;sub_400686(&dword_601078, &unk_601060);LODWORD(v7[j]) = dword_601078;HIDWORD(v7[j]) = dword_60107C;}if ( sub_400770(v7, a2) != 1 ){puts("NO NO NO~ ");exit(0);}puts("Congratulation!\n");puts("You seccess half\n");puts("Do not forget to change input to hex and combine~\n");puts("ByeBye");return 0LL;
}

定义a2为字符数组指针,让后a2指向整型v6,相当于输入v6,循环6次

__int64 __fastcall sub_400770(_DWORD *a1)
{if ( a1[2] - a1[3] == 2225223423LL&& a1[3] + a1[4] == 4201428739LL&& a1[2] - a1[4] == 1121399208LL&& *a1 == -548868226&& a1[5] == -2064448480&& a1[1] == 550153460 ){puts("good!");return 1LL;}else{puts("Wrong!");return 0LL;}
}

寻找密文,用z3解决,

from z3 import *s = Solver()
a1 = [Int(f'a1[{i}]') for i in range(6)]# 添加约束
s.add(a1[2] - a1[3] == 2225223423)
s.add(a1[3] + a1[4] == 4201428739)
s.add(a1[2] - a1[4] == 1121399208)
s.add(a1[0] == -548868226)
s.add(a1[5] == -2064448480)
s.add(a1[1] == 550153460)# 检查是否有解
if s.check() == sat:print(s.model())
else:print("No solution found.")

密钥

__int64 __fastcall sub_400686(unsigned int *a1, _DWORD *a2)
{__int64 result; // raxunsigned int v3; // [rsp+1Ch] [rbp-24h]unsigned int v4; // [rsp+20h] [rbp-20h]int v5; // [rsp+24h] [rbp-1Ch]unsigned int i; // [rsp+28h] [rbp-18h]v3 = *a1;v4 = a1[1];v5 = 0;for ( i = 0; i <= 0x3F; ++i ){v5 += 1166789954;v3 += (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;v4 += (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;}*a1 = v3;result = v4;a1[1] = v4;return result;
}

加密函数是tea,写代码实现,是整数密文和整数密钥

#include <stdio.h>
#include<stdint.h>
void decrypt(int *a1,int *a2){unsigned int v3; // [rsp+1Ch] [rbp-24h]unsigned int v4; // [rsp+20h] [rbp-20h]int v5; // [rsp+24h] [rbp-1Ch]unsigned int i; // [rsp+28h] [rbp-18h]v3 = *a1;v4 = a1[1];v5 = 1166789954*64;for ( i = 0; i <= 63; ++i ){   v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;v5 -= 1166789954;}*a1 = v3;a1[1] = v4;
}
int main()
{int a1[6];a1[4] = 2652626477;a1[1] = 550153460;a1[3] = 1548802262;a1[5] = -2064448480;a1[2] = 3774025685;a1[0] = -548868226;int key[]={2,2,3,4};int i;for(i=0;i<6;i+=2){decrypt(a1+i,key);}for(i=0;i<6;i++){printf("%x\n",a1[i]);}return 0;
}

因为是数字加密,所以之后转换成字符

flag{re_is_great!}

之后遇到了有价值的题目再总结于此吧


http://www.mrgr.cn/news/79632.html

相关文章:

  • 红日靶场vulnstack 5靶机的测试报告
  • Simdroid-EC:液冷仿真新星,助力新能源汽车电机控制器高效散热
  • 设计模式——Singleton(单例)设计模式
  • C# AES
  • 相机测距原理
  • http网络服务-swift-Alamofire
  • 如何高效的向AI大模型提问? - 提示工程Prompt Engineering
  • 【考前预习】1.计算机网络概述
  • 深度学习实验十四 循环神经网络(1)——测试简单循环网络的记忆能力和梯度爆炸实验
  • 深入了解架构中常见的4种缓存模式及其实现
  • 在VMWare上安装openEuler 22.03-LTS
  • Mysql索引原理及优化——岁月云实战笔记
  • 嵌入式开发 - 工具记录
  • 【mysql】数据库存量数据双主实现
  • 北京大学《操作系统原理》课堂笔记(一)
  • LLM - 多模态大模型的开源评估工具 VLMEvalKit 部署与测试 教程
  • leetcode-54.螺旋矩阵-day1
  • Adobe Premiere Pro 2024 [24.6.1]
  • 2022 年“泰迪杯”数据分析技能赛A 题竞赛作品的自动评判
  • MySQL-DML之数据表操作
  • 递归算法题(1)
  • C++小小复习一下
  • SpringBoot3整合MyBatis
  • 2020 年“泰迪杯”数据分析职业技能大赛A 题教育平台的线上课程智能推荐策略
  • NanoLog起步笔记-4-Server端的两个线程
  • BottomNavigation