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

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; // r8
  int 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);
    else
      sub_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; // r8
  int 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);
    else
      printf(aWrong_0, v6, v7);
    return 0;
  }
  else
  {
    printf(aWrong, v3, v4);
    return 0;
  }
}

分析了一下修改了函数名,查看密文和长度

查看加密函数

__int64 __fastcall encrypt(unsigned int *a1, _DWORD *a2)
{
  __int64 result; // rax
  unsigned 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; // rax
  char v11; // [rsp+20h] [rbp+0h] BYREF
  unsigned int v12; // [rsp+24h] [rbp+4h]
  char Str[48]; // [rsp+48h] [rbp+28h] BYREF
  int v14[12]; // [rsp+78h] [rbp+58h] BYREF
  char Src[32]; // [rsp+A8h] [rbp+88h] BYREF
  char v16[28]; // [rsp+C8h] [rbp+A8h] BYREF
  int 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; // rax
  unsigned 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!!}

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


http://www.kler.cn/a/429492.html

相关文章:

  • 【CSS】HTML页面定位CSS - position 属性 relative 、absolute、fixed 、sticky
  • 本地部署项目管理工具 Leantime 并实现外部访问
  • MySQL 中删除重复数据 SQL 写法
  • WEB攻防-通用漏洞_XSS跨站_权限维持_捆绑钓鱼_浏览器漏洞
  • Android string.xml中特殊字符转义
  • 开源项目stable-diffusion-webui部署及生成照片
  • 开源轻量级文件分享服务Go File本地Docker部署与远程访问
  • 使用docker-compose安装Milvus向量数据库及Attu可视化连接工具
  • 物理学:什么是核聚变?
  • .Net学习
  • el-dialog修改其样式不生效加deep也没用
  • 从零用java实现 小红书 springboot vue uniapp (1)
  • 探索数据确权、隐私保护、安全共享等方面的挑战与解决方案
  • IDEA离线安装activit bpmn 插件
  • 获取淘宝商品评论数据的API应用:市场调研|产品更新|用户数据
  • ESP32开发 云调试
  • 基于最新的ApacheStreamPark搭建指南
  • springboot+Loki+Loki4j+Grafana搭建轻量级日志系统
  • 进入 Dystopia:第九周游戏指南
  • CCF编程能力等级认证GESP—C++8级—20241207
  • Blender中使用BlenderGIS插件快速生成城市建筑模型
  • 关于csgo的游戏作弊与封禁
  • 使用 Magic-PDF 工具进行 PDF 文档解析与内容提取
  • 2024 一带一路暨金砖国家技能发展与技术创新大赛【网络安全防护治理实战技能赛项】样题(中职组)
  • 第十四周:支持向量机(SVM)
  • Map 那些事儿