[Hgame CTF]a_cup of tea

考点一览

tea加密

//加密函数(了解就行)
void encrypt(uint32_t* v, uint32_t* k)
{  

    uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */  

    uint32_t delta=0x9e3779b9(可换);                     /* a key schedule constant */  

    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */  

    for (i=0; i < 32; i++)                         /* basic cycle start */

    {                      

        sum += delta;

        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);

        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);

    }                                              /* end cycle */
	v[0]=v0; 
	v[1]=v1;
}
//解密函数
//long long a2[4]={1,3,1,4};       /*可换*/
__int64 __fastcall sub_1400010B4(unsigned int *a1, long long *a2)
{
  
  int v2; // ebx
  long long v3; // r11d
  int v4; // edi
  int v5; // esi
  int v6; // ebp
  unsigned int v7; // r9d
  __int64 v8; // rdx
  unsigned int v9; // r10d
  __int64 result; // rax
  v2 = *a2;
  v3 = 0;
  v4 = a2[1];
  v5 = a2[2];
  v6 = a2[3];
  v7 = *a1;
  v8 = 32;
  v9 = a1[1];
  for(int i = 0 ; i < 32 ; i ++ )
  {
    v3-=0x61C98747;     /*可换*/
  }
  do
  {
    result = v3 + v7;
    v9 -= result ^ (v5 + 16 * v7) ^ (v6 + (v7 >> 5));
    v7 -= (v3 + v9) ^ (v2 + 16 * v9) ^ (v4 + (v9 >> 5));
    v3 += 0x61C98747;   /*可换*/
    --v8;
  }
  while ( v8 );
  *a1 = v7;
  a1[1] = v9;
  return result;
}

认真解题

查壳,反编译之后,将十进制数转化为十六进制,我们可以看到本题的主函数部分使用了小端序的排列方式。再看到下面这个赋值语句:
file
进入之后看到一串十六进制数‘45678901345678902345678912345678h’,我们再看到后面的调用函数:
file
file
调用了四次该函数。
(char※)Buf1+8==(int※)Buf1+2:两个字符放在一个字节,往后移8个字节的字符都放入第二个函数,再从首地址后移八个字节,将其后面的字符放入第二个函数==第一个函数放两个元素的数,再从首地址后移两个地址,将后面的元素放入第二个函数。
上段中我并没有说,后面的字符/元素是多少个,因为我们现在还不能确定,并且后面的v10的作用仍然不清楚。且输入函数‘sub_140001064(“%50s”);’也没有告诉我们输入的字符存到哪里。为此,我们可以动态调试来看看输入的字符去了哪里。
file
我们在此处下断点,进行输入字符,这里可以尽可能多输入一点。
file
我先输入了‘123456789012345678901234567890’,再点开此处的v10,它前面有16个数字,也就是说我们输入的数字一半进入了Buf1数组,一半进入了v10数组。
综上,也就是说两个Buf2元素一组是由Buf1数组,v10数组分别两次,共四次调用sub_1400010B4这个加密函数,得来的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tTRSB71T-1673956186008)(null)]
点开sub_1400010B4加密函数,我们知道这是一个Tea加密,并且通过定义变量,我们知道a2是一个包含四个元素的数组。因此联系到‘si128.m128i_i32’是一个包含四个元素的数组。由前面那一长串赋值字符串可以知道,si128.m128i_i32[4]= {0x12345678,0x23456789,0x34567890,0x45678901}。
现在我们已知加密后的结果,再将加密函数逆向得到解密函数即可,脚本如下:

__int64 __fastcall sub_1400010B4(unsigned int *a1, long long *a2)
{
  int v2; // ebx
  long long v3; // r11d
  int v4; // edi
  int v5; // esi
  int v6; // ebp
  unsigned int v7; // r9d
  __int64 v8; // rdx
  unsigned int v9; // r10d
  __int64 result; // rax

  v2 = *a2;
  v3 = 0;
  v4 = a2[1];
  v5 = a2[2];
  v6 = a2[3];
  v7 = *a1;
  v8 = 32;
  v9 = a1[1];
  for(int i = 0 ; i < 32 ; i ++ )
  {
  	v3-=0x543210DD;
  }
  do
  {
    result = v3 + v7;
	v9 -= result ^ (v5 + 16 * v7) ^ (v6 + (v7 >> 5));
    v7 -= (v3 + v9) ^ (v2 + 16 * v9) ^ (v4 + (v9 >> 5));
    v3 += 1412567261;
    --v8;
  }
  while ( v8 );
  *a1 = v7;
  a1[1] = v9;
  return result;
}

int main ()
{
	long long a2[4]={0x12345678,0x23456789,0x34567890,0x45678901};
	unsigned int Buf2[8]={0};
	Buf2[0] = 0x2E63829D;
	Buf2[1] = 0xC14E400F;
	Buf2[2] = 0x9B39BFB9;
	Buf2[3] = 0x5A1F8B14;
	Buf2[4] = 0x61886DDE;
	Buf2[5] = 0x6565C6CF;
	Buf2[6] = 0x9F064F64;
	Buf2[7] = 0x236A43F6;
	for(int i = 0 ; i < 8 ; i+=2 )
	{
		sub_1400010B4(Buf2+i,a2);
	}
	for(int i = 0 ; i < 8 ; i++ )
	{
		unsigned int tmp = Buf2[i];
		for(int j = 0 ; j< 4 ; j++ )
		{
			printf("%c",tmp%0x100);
			tmp/=0x100;
		}
	}
	printf("k}");
}

hgame{Tea_15_4_v3ry_h3a1thy_drlnk}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值