[2019红帽杯]xx 1

文件类型

64位无壳

分析

在这里插入图片描述
可以看到先判断输入字符长度是否为19,然后接下来的一段不知道在干嘛,我们倒着看
最后给了四个十六进制数作为结果比较,v19经过加密函数后,顺序打乱给了v20,然后进行异或操作得到最终结果
在这里插入图片描述
看以看出来两个移位计算式很像tea加密中的一种,百度后发现是xxtea,那么我们需要获取密钥值,加密迭代次数,密文,直接动态调试,可以发现密钥为前五位,即flag,迭代值为6,所以前面的运算是为了产生这两个值
在这里插入图片描述

v8 =a2 >>2 +1,动调可以知道a2为20,所以结果为6

wp

#include<stdio.h>
#include<stdint.h>
#define delta 0x9e3779b9
#define MX (((z>>5^y<<2) +(y>>3^z<<4)) ^((sum^y) +(key[(p&3)^e] ^z)))

void decode(uint32_t *v22,uint32_t *date);
void beta(uint32_t *v, int n,uint32_t key[4])
{
	uint32_t y,z,sum;
	unsigned p,rounds,e;
	if(n>1){        //判断加密还是解密
       rounds =6+52/n; //定义迭代次数,n=2即是32
	   sum =0;
	   z =v[n-1];
	   do{
		   sum +=delta;
		   e =(sum >>2)&3;
		   for(p=0;p<n-1;p++){   //p:0->n-1
			   y =v[p+1];
			   z =v[p] +=MX;
		   }
		   y =v[0];
		   z =v[n-1] +=MX;      //p=n-1
	   }
	   while(--rounds);
	}
	else if(n<-1)
	{
		n=-n;
		rounds =6 +52/n;
		sum =rounds*delta;
		y =v[0];
		do{
			e =(sum >>2)&3;
			for(p =n-1;p>0;p--){       //p:n-1->0
				z =v[p-1];
				y =v[p]-=MX;
			}
			z =v[n-1];
			y =v[0]-=MX;     //n=0
			sum -=delta;
		}
		while(--rounds);
	}
}
int main(){

	unsigned int v20[]={0xce,0xbc,0x40,0x6b,0x7c,0x3a,0x95,0xc0,0xef,0x9b,0x20,0x20,0x91,0xf7,0x02,0x35,0x23,0x18,0x2,0xc8,0xe7,0x56,0x56,0xfa};
	
	decode(&v20[23],v20);
	unsigned int v19[24];
	v19[2] = *v20;
	v19[0] = v20[1];
	v19[3] = v20[2];
	v19[1] = v20[3];
	v19[6] = v20[4];
	v19[4] = v20[5];
	v19[7] = v20[6];
	v19[5] = v20[7];
	v19[10] = v20[8];
	v19[8] = v20[9];
	v19[11] = v20[10];
	v19[9] = v20[11];
	v19[14] = v20[12];
	v19[12] = v20[13];
	v19[15] = v20[14];
	v19[13] = v20[15];
	v19[18] = v20[16];
	v19[16] = v20[17];
	v19[19] = v20[18];
	v19[17] = v20[19];
	v19[22] = v20[20];
	v19[20] = v20[21];
	v19[23] = v20[22];
	v19[21] = v20[23];

	
	uint32_t v[]={132784398,32899329,5038229,392203,43290,2304};
	uint32_t k[4]={0x67616c66,0,0,0};

	for(int i=0;i<24;i+=4){
	 v[i/4 ] =v19[i]+(v19[i+1]<<8)+(v19[i+2]<<16)+(v19[i+3]<<24);
		printf("%#x ",v[i/4]);
	}
	unsigned int n=6; //正加密,负解密
	//两个一组进行加密
	
	//for(int i=0;i<6;i+=2){
	//printf("\n加密前数据:%10d %10d",v[i],v[i+1]);
	//beta(&v[i],n,k);
	//printf("\n加密后数据:%10d %10d",v[i],v[i+1]);
	//beta(v,-n,k);
	//printf("\n解密后数据:%#x %#x",v[i],v[i+1]);
	//}
	beta(v,-n,k);
	//xxtea(v,-n,k);
	putchar('\n');
	for (int i = 0; i < 6; i++) {
		char tt = (char)v[i];
		char tt1 = (uint32_t)v[i] >> 8;
		char tt2 = (uint32_t)v[i] >> 16;
		char tt3 = (uint32_t)v[i] >> 24;
		printf("%c%c%c%c", tt, tt1, tt2, tt3);
 
	}
	

	fflush(stdin);
	getchar();
	return 0;
}
void decode(uint32_t *v22,uint32_t *date){
	int i_1=23;
	int j=0;
	uint32_t v24;
	
	uint32_t *v20 =v22;
	//v22传入末尾指针
	for ( ; i_1 >0; --v22 )   // 将结果异或加密,v22指向v20
  {
    j = i_1/3i64 -1;
    if ( i_1 / 3 > 0 )
    {
      v24 = *v22;
      do
      {
        v24 ^= (date[j--]&0xff);
        *v22 = v24;
      }
      while ( j >=0 );
    }
    --i_1;
  }


	//return 0;
}

flag{CXX_and_++tea}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值