RCTF babyre xxtea

xxtea

程序是一个64位ELF程序

在这里插入图片描述

发现里面包含了TEA相关的加密,调试程序可知输入的长度需要为16,且之后有3个关键的函数

在这里插入图片描述

三个函数处理之后的结果与0x17异或之后,需要输出Bingo!

第一个函数很简单是将我们输入的字符串变成HEX(测试字符1234567890123456)

在这里插入图片描述

进入第二个函数,找到了第XXTEA的黄金比例(0x9e3779b9)

在这里插入图片描述

首先排除TEA因为TEA加密没有拿黄金比例相乘的地方,而XTEA和TEA解密有 再看相乘的数据

一对比就可以知道为XXTEA解密,解密之后的数据

但是最后只效验了最后一位要求小于4,并且根据最后一位的数值进行截断。之后进行了

CRC16校验

v15 = __readfsqword(0x28u);
  v13 = 0;
  v14 = 0;
  if ( a2 )
  {
    v2 = a1;
    v3 = a1 + (unsigned int)(a2 - 1) + 1;
    do
    {
      while ( 1 )
      {
        v13 = *(_BYTE *)(++v2 - 1);
        sub_564C6D4B2270(&v13, &v13);
        v4 = v14 ^ (v13 << 8);
        if ( ((v14 ^ (v13 << 8)) & 0x8000u) != 0 )
          v5 = 2 * v4 ^ 0x1021;
        else
          v5 = 2 * v4;
        v6 = 2 * v5 ^ 0x1021;
        if ( v5 >= 0 )
          v6 = 2 * v5;
        v7 = 2 * v6 ^ 0x1021;
        if ( v6 >= 0 )
          v7 = 2 * v6;
        v8 = 2 * v7 ^ 0x1021;
        if ( v7 >= 0 )
          v8 = 2 * v7;
        v9 = 2 * v8 ^ 0x1021;
        if ( v8 >= 0 )
          v9 = 2 * v8;
        v10 = 2 * v9 ^ 0x1021;
        if ( v9 >= 0 )
          v10 = 2 * v9;
        v11 = 2 * v10 ^ 0x1021;
        if ( v10 >= 0 )
          v11 = 2 * v10;
        if ( v11 < 0 )
          break;
        v14 = 2 * v11;
        if ( v2 == v3 )
          goto LABEL_19;
      }
      v14 = 2 * v11 ^ 0x1021;
    }
    while ( v2 != v3 );
  }
LABEL_19:
  sub_564C6D4B22D0(&v14, &v14);
  return v14;
}

该算法不可逆,我们只好采用爆破的方法 我们根据XXTEA解密之后异或0x17之后要输出Bingo! 因此我们知道前6位 后最后一位进行截断的为2,只有第七位不知道 使用pwntools交互进行爆破。最后爆破和xxtea解题程序如下

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

void btea(uint32_t *v, int n, uint32_t const key[4])
{
	uint32_t y, z, sum;
	unsigned p, rounds, e;
	if (n > 1)            /* Coding Part */
	{
		rounds = 6 + 52 / n;
		sum = 0;
		z = v[n - 1];
		do
		{
			sum += DELTA;
			e = (sum >> 2) & 3;
			for (p = 0; p<n - 1; p++)
			{
				y = v[p + 1];
				z = v[p] += MX;
			}
			y = v[0];
			z = v[n - 1] += MX;
		} while (--rounds);
	}
	else if (n < -1)      /* Decoding Part */
	{
		n = -n;
		rounds = 6 + 52 / n;
		sum = rounds*DELTA;
		y = v[0];
		do
		{
			e = (sum >> 2) & 3;
			for (p = n - 1; p>0; p--)
			{
				z = v[p - 1];
				y = v[p] -= MX;
			}
			z = v[n - 1];
			y = v[0] -= MX;
			sum -= DELTA;
		} while (--rounds);
	}
}


int main()
{
	
		
		for (int i = 0; i <= 0xff; i++)
		{
			unsigned int b = 0x02003678;
			b = b + (i << 16);
			uint32_t v[2] = { (unsigned int)0x70797e55, b };
			uint32_t const k[4] = { (unsigned int)0xE0C7E0C7, (unsigned int)0XC6F1D3D7, (unsigned int)0xc6d3c6d3, (unsigned int)0xc4d0d2ce };
			int n = 2; //n的绝对值表示v的长度,取正表示加密,取负表示解密  
			// v为要加密的数据是两个32位无符号整数  
			// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位  
			//printf("加密前原始数据:%x %x\n", v[0], v[1]);
			btea(v, n, k);
			printf("%x\n%x\n", v[0], v[1]);
			//btea(v, -n, k);
			//printf("解密后的数据:%x %x\n", v[0], v[1]);
			
			
		}
		system("pause");
	
}
from pwn import *
fp=open("1.txt","r")
context.log_level='debug'
for i in range (0,0x100):   
    a=fp.readline()
    a=a[:-2]
    a=a[::-1]
    a=a.ljust(8,'0')
    b=fp.readline()
    b=b[:-2]
    b=b[::-1]
    b=b.ljust(8,'0')
    a+=b
    payload=''
    for j in range (0,15,2):
        payload+=a[j+1:j+2]
        payload+=a[j:j+1]
    p=process('./babyre')
    p.recvuntil('you can got \'Bingo!\' :')
    p.sendline(payload)
    sleep(1)
    result=p.recvline()
    if result=="Bingo!":
        print payload
    p.close()

发现都符合,因为最后CRC16校验时把第七位改成00带入校验,因此第七位不管是啥都为0。因此该题有多解
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值