首页 > 其他分享 >[GDOUCTF 2023]Tea

[GDOUCTF 2023]Tea

时间:2023-06-20 15:23:31浏览次数:55  
标签:__ sub Tea sum a1 2023 v8 rsp GDOUCTF

[GDOUCTF 2023]Tea

  • 无壳,64位程序

程序执行回显如下:

我们要输入8个8字节的数据,经过校验后,即可获得flag。我们看一下输入的数据有点像Tea算法中的128位需要加密的数据格式.

IDA分析:

通过字符串窗口,我们可以找到字符串"you are right!\n".交叉引用(X键)到相关函数去.

字符串所在函数代码:

__int64 sub_140016230()
{
  char *v0; // rdi
  __int64 i; // rcx
  char v3[32]; // [rsp+0h] [rbp-20h] BYREF
  char v4; // [rsp+20h] [rbp+0h] BYREF
  int v5; // [rsp+24h] [rbp+4h]
  int v6; // [rsp+44h] [rbp+24h]
  int v7[12]; // [rsp+68h] [rbp+48h] BYREF
  _DWORD v8[16]; // [rsp+98h] [rbp+78h] BYREF
  int v9[31]; // [rsp+D8h] [rbp+B8h] BYREF
  int j; // [rsp+154h] [rbp+134h]
  int k; // [rsp+174h] [rbp+154h]
  int m; // [rsp+194h] [rbp+174h]

  v0 = &v4;
  for ( i = 102i64; i; --i )
  {
    *(_DWORD *)v0 = -858993460;
    v0 += 4;
  }
  sub_14001137F(&unk_140023009);
  v5 = 32;
  v6 = 0;
  v7[0] = 1234;
  v7[1] = 5678;
  v7[2] = 9012;
  v7[3] = 3456;
  memset(v8, 0, 0x28ui64);
  v9[15] = 0;
  v9[23] = 0;
  sub_1400113E8();
  for ( j = 0; j < 10; ++j )
    sub_1400111FE("%x", &v8[j]);
  sub_140011339(v7);
  sub_140011145(v8, v9);
  sub_1400112B7(v8, v7);
  v6 = sub_140011352(v8);
  if ( v6 )
  {
    sub_140011195("you are right\n");
    for ( k = 0; k < 10; ++k )
    {
      for ( m = 3; m >= 0; --m )
        sub_140011195("%c", (unsigned __int8)((unsigned int)v9[k] >> (8 * m)));
    }
  }
  else
  {
    sub_140011195("fault!\nYou can go online and learn the tea algorithm!");
  }
  sub_140011311(v3, &unk_14001AE90);
  return 0i64;
}

sub_1400113E8函数

__int64 sub_1400113E8(void)
{
  return sub_140011B00();
}

int sub_140011B00()
{
  sub_14001137F(&unk_140023009);
  printf("This is the input format for you geting of flag hex \n");
  printf("0x12345678 0x12345678 0x12345678 0x12345678 0x12345678 0x12345678 0x12345678\n");
  printf("The end of flag:\nHZCTF{This_is_the_fake_flag}\n");
  return printf("input your get the flag:\n");
}
  • 程序运行时,打印的东西
for ( j = 0; j < 10; ++j )
    scanf("%x", &v8[j]);
  • 对我们的v8数组输入十六进制字符串,因为在上一个函数中,指定了我们要输入字符串的格式为hex

sub_140011339函数

__int64 __fastcall sub_140011339(__int64 a1)
{
  return sub_1400117D0(a1);
}

__int64 __fastcall sub_1400117D0(_DWORD *a1)
{
  char *v1; // rdi
  __int64 i; // rcx
  char v4[32]; // [rsp+0h] [rbp-20h] BYREF
  char v5; // [rsp+20h] [rbp+0h] BYREF
  int v6; // [rsp+28h] [rbp+8h]
  int v7; // [rsp+2Ch] [rbp+Ch]
  int v8; // [rsp+30h] [rbp+10h]
  int v9; // [rsp+34h] [rbp+14h]

  v1 = &v5;
  for ( i = 14i64; i; --i )
  {
    *(_DWORD *)v1 = -858993460;
    v1 += 4;
  }
  sub_14001137F(&unk_140023009);
  v6 = 2233;
  v7 = 4455;
  v8 = 6677;
  v9 = 8899;
  *a1 = 2233;
  a1[1] = v7;
  a1[2] = v8;
  a1[3] = v9;
  return sub_140011311(v4, &unk_14001AD00);
}
  • 传入的参数为v7,但是在函数内部通过指针被改变了值
  • 原来的v7值为1234,5678,9012,3456
  • 改变后的v7值为2233,4455,6677,8899

sub_140011145(v8, v9);

代码如下:

__int64 __fastcall sub_140011145(__int64 a1, __int64 a2)
{
  return sub_140012030(a1, a2);
}

__int64 __fastcall sub_140012030(__int64 a1, __int64 a2)
{
  __int64 result; // rax
  int i; // [rsp+24h] [rbp+4h]

  result = sub_14001137F(&unk_140023009);
  for ( i = 0; i < 10; ++i )
  {
    *(_DWORD *)(a2 + 4i64 * i) = *(_DWORD *)(a1 + 4i64 * i);
    result = (unsigned int)(i + 1);
  }
  return result;
}
  • 传入的是v8,v9数组,实际上只是把v8数组的每个值赋给了v9

sub_1400112B7(v8, v7);

代码如下:

__int64 __fastcall sub_1400112B7(__int64 a1, __int64 a2)
{
  return sub_140011900(a1, a2);
}

__int64 __fastcall sub_140011900(__int64 a1, __int64 key)
{
  __int64 result; // rax
  int v3; // [rsp+44h] [rbp+24h]
  int i; // [rsp+64h] [rbp+44h]
  unsigned int v5; // [rsp+84h] [rbp+64h]
  unsigned int sum; // [rsp+C4h] [rbp+A4h]

  result = sub_14001137F(&unk_140023009);
  for ( i = 0; i <= 8; ++i )
  {
    v5 = 0;
    sum = 0xF462900 * i;                        // sum = delta * i
    v3 = i + 1;
    do
    {
      ++v5;
      *(_DWORD *)(a1 + 4i64 * i) += sum ^ (*(_DWORD *)(a1 + 4i64 * v3)
                                         + ((*(_DWORD *)(a1 + 4i64 * v3) >> 5) ^ (16 * *(_DWORD *)(a1 + 4i64 * v3)))) ^ (sum + *(_DWORD *)(key + 4i64 * (sum & 3)));
      *(_DWORD *)(a1 + 4i64 * v3) += (sum + *(_DWORD *)(key + 4i64 * ((sum >> 11) & 3))) ^ (*(_DWORD *)(a1 + 4i64 * i)
                                                                                          + ((*(_DWORD *)(a1 + 4i64 * i) >> 5) ^ (16 * *(_DWORD *)(a1 + 4i64 * i))));
      sum += 0xF462900;                         // sum += delta
    }
    while ( v5 <= 32 );                         // 循环32次
    result = (unsigned int)(i + 1);
  }
  return result;
}
  • 存在一个变量与一个固定的常数做运算,且常数不受影响,常数为0xF462900
  • 存在移位+异或运算
  • 存在Feistal结构,即把运算后的值相加并且给新的变量
  • do...while循环33次
  • for循环8次

通过上述信息,可以初步判断这个题目是一个魔改的Xtea算法,xtea算法在另外一篇博客已经讲过:https://www.cnblogs.com/qsons/p/17493267.html.不过这个题设了一些坑,而且还是一道魔改的Xtea算法

正常的Xtea算法特征如下:

  • Delta为0x7E3779B9
  • v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3])
  • v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3])
 *(_DWORD *)(a1 + 4i64 * i) += sum ^ (*(_DWORD *)(a1 + 4i64 * v3)
                                         + ((*(_DWORD *)(a1 + 4i64 * v3) >> 5) ^ (16 * *(_DWORD *)(a1 + 4i64 * v3)))) ^ (sum + *(_DWORD *)(key + 4i64 * (sum & 3)));
      *(_DWORD *)(a1 + 4i64 * v3) += (sum + *(_DWORD *)(key + 4i64 * ((sum >> 11) & 3))) ^ (*(_DWORD *)(a1 + 4i64 * i)
                                                                                          + ((*(_DWORD *)(a1 + 4i64 * i) >> 5) ^ (16 * *(_DWORD *)(a1 + 4i64 * i))));

经过还原后,大致代码如下所示:
a1[i] += sum ^ (a1[v3] + ((a1[v3] >> 5) ^ (a1[v3] << 4)) ^ (sum + key[sum & 3])
a1[v3] += (sum + key[(sum >> 11) & 3] ) ^ (a1[i] + (a1[i] >> 5) ^ (a1[i] << 4))
这里的*16其实就相当于<<4,因为左移N位,相当于乘以2^N次方.

不同点

  • 在a1[i]进行移位+异或运算时,多了个sum进行异或,原型应该是(sum + v1) ^ a ^ c的.
  • delta被魔改为0xF462900
  • 密文一共有10个32位无符号整型数据
  • sum进行解密时,不再是sum << 5.这里在for循环里面,也对sum做了乘以i的处理。
  • 轮数为33轮。

实际上这里的XTEA算法,就是对密文一共10组,每二组进行一次加密。加密轮次为33轮,常数为0xF462900.

v6 = sub_140011352(v8);

__int64 __fastcall sub_140011352(__int64 a1)
{
  return sub_140011B60(a1);
}

__int64 __fastcall sub_140011B60(__int64 a1)
{
  char *v1; // rdi
  __int64 i; // rcx
  unsigned int v3; // edi
  char v5[32]; // [rsp+0h] [rbp-20h] BYREF
  char v6; // [rsp+20h] [rbp+0h] BYREF
  BOOL v7; // [rsp+24h] [rbp+4h]
  int v8[15]; // [rsp+48h] [rbp+28h]
  int j; // [rsp+84h] [rbp+64h]

  v1 = &v6;
  for ( i = 34i64; i; --i )
  {
    *(_DWORD *)v1 = -858993460;
    v1 += 4;
  }
  sub_14001137F(&unk_140023009);
  v7 = 0;
  v8[0] = 0x1A800BDA;
  v8[1] = 0xF7A6219B;
  v8[2] = 0x491811D8;
  v8[3] = 0xF2013328;
  v8[4] = 0x156C365B;
  v8[5] = 0x3C6EAAD8;
  v8[6] = 0x84D4BF28;
  v8[7] = 0xF11A7EE7;
  v8[8] = 0x3313B252;
  v8[9] = 0xDD9FE279;
  for ( j = 0; j < 10; ++j )
    v7 = *(_DWORD *)(a1 + 4i64 * j) == v8[j];
  v3 = v7;
  sub_140011311(v5, &unk_14001AD80);
  return v3;
}
  • 循环10次,v8[j] == a1[j]

密文如下:

v8[0] = 0x1A800BDA;
v8[1] = 0xF7A6219B;
v8[2] = 0x491811D8;
v8[3] = 0xF2013328;
v8[4] = 0x156C365B;
v8[5] = 0x3C6EAAD8;
v8[6] = 0x84D4BF28;
v8[7] = 0xF11A7EE7;
v8[8] = 0x3313B252;
v8[9] = 0xDD9FE279;

解密脚本如下:

C语言脚本:

#include <stdio.h>
#include <stdint.h>
#define delta 0xF462900

int main()
{
    uint32_t key[4] = {2233,4455,6677,8899};
    uint32_t Data[10] = { 0x1A800BDA ,0xF7A6219B ,0x491811D8,0xF2013328,0x156C365B, 0x3C6EAAD8,0x84D4BF28,0xF11A7EE7,0x3313B252,0xDD9FE279 };
    unsigned int j;
    int i;
    unsigned int sum;
    for (i = 8; i >= 0; i--)
    {
        j = 33;
        sum = delta * (i + j);
        while(j--)
        { 
            sum -= delta;
            Data[i + 1] -= (sum + key[(sum >> 11) & 3]) ^ ((Data[i] + ((Data[i] >> 5) ^ (Data[i] << 4))));
            Data[i] -= sum ^ (Data[i + 1] + ((Data[i + 1] >> 5) ^ (Data[i + 1] << 4))) ^ (sum + key[sum & 3]);
        }

    }

    for (int i = 0; i < 10; i++)
    {
        printf("%x", Data[i]);
    }




    return 0;
}
#485a4354467b687a4374665f39345f726536363666696e676372793536343171717d0
最后十六进制解码即可

注意点:

  • 对Sum进行处理时,是33+i轮次。33代表的是内部对数据的总加密轮次。外部是对每数据二二一组加密的轮次
  • for循环需要逆算法来,从8迭代到0.
  • while循环中,+=变-=即可,其他不变。
  • 加密时顺序sum+=delta要最先放上来

Python代码下:

def xtea_decrypt(data,key):
  for j in range(8,-1,-1):
    i = 0
    delta = 256256256
    sum = delta * (32 + j)
    n = j + 1
    while i <= 32:
        i += 1
        data[n] = (data[n] - (((key[(sum >> 11) & 3]) + sum) ^ (((data[j] << 4) ^ (data[j] >> 5)) + data[j]))) & 0xffffffff
        data[j] = (data[j] - (((key[sum & 3] + sum) ^ ((data[n] << 4) ^ (data[n] >> 5)) + data[n]) ^ sum)) & 0xffffffff
        sum -= delta
  return data

v8 = [0x1A800BDA,0xF7A6219B,0x491811D8,0xF2013328,0x156C365B,0x3C6EAAD8,0x84D4BF28,0xF11A7EE7,0x3313B252,0xDD9FE279]
key = [2233,4455,6677,8899]

flag = xtea_decrypt(v8,key)

for i in range(10):
    for j in range(3,-1,-1):
        print(chr((flag[i] >> (j * 8)) & 0xFF), end='')
#HZCTF{hzCtf_94_re666fingcry5641qq}

注意点:

  • 在C语言中是有无符号32整型这种内置函数的,python没有,所以需要约束0xFFFFFFFF,也就是保留其低32位。
  • 在最后取flag时,flag为单个字符,每个字符不可能超过0xFF,所以也要用与运算取其低8位的二进制数据。

Over~~~

标签:__,sub,Tea,sum,a1,2023,v8,rsp,GDOUCTF
From: https://www.cnblogs.com/qsons/p/17493712.html

相关文章

  • Adobe_Illustrator_2023_27.6.0新增功能_安装_下载
    AdobeIllustrator2023最新爱国版(简称Ai、一键式安装、永久使用)是一款由Adobe公司推出的矢量绘图软件,被广泛用于平面设计、插画、网页设计、多媒体等领域。该软件拥有高度精确的矢量绘图能力,可以输出各种清晰度的图像,因此备受设计师的喜爱和青睐。2023年5月版(版本27.6)桌面版......
  • Apache Superset 身份认证绕过漏洞(CVE-2023-27524)
    漏洞简介ApacheSuperset是一个开源的数据可视化和数据探测平台,它基于Python构建,使用了一些类似于Django和Flask的Pythonweb框架。提供了一个用户友好的界面,可以轻松地创建和共享仪表板、查询和可视化数据,也可以集成到其他应用程序中。由于用户在默认安装过程中,未对SECRET_KEY......
  • 电力配电板行业市场现状调研及发展趋势分析报告2023-2029
    2023-2029全球电力配电板行业调研及趋势分析报告2022年全球电力配电板市场规模约66亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近91亿元,未来六年CAGR为4.3%。从核心市场看,中国电力配电板市场占据全球约%的市场份额,为全球最主要......
  • 电池接触系统行业市场现状调研及发展趋势分析报告2023-2029
    2023-2029全球电池接触系统行业调研及趋势分析报告2022年全球电池接触系统市场规模约23亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近33亿元,未来六年CAGR为4.6%。从核心市场看,中国电池接触系统市场占据全球约%的市场份额,为全球......
  • 便携式室外取暖器行业市场现状调研及发展趋势分析报告2023-2029
    2023-2029全球便携式室外取暖器行业调研及趋势分析报告2022年全球便携式室外取暖器市场规模约21亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近30亿元,未来六年CAGR为4.1%。从核心市场看,中国便携式室外取暖器市场占据全球约%的市......
  • 球NTC二极管热敏电阻行业市场现状调研及发展趋势分析报告2023-2029
    2023-2029全球NTC二极管热敏电阻行业调研及趋势分析报告2022年全球NTC二极管热敏电阻市场规模约3.5亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近3.9亿元,未来六年CAGR为1.7%。从核心市场看,中国NTC二极管热敏电阻市场占据全球约......
  • 改性聚苯醚IC托盘行业市场现状调研及发展趋势分析报告2023-2029
    2023-2029全球改性聚苯醚IC托盘行业调研及趋势分析报告2022年全球改性聚苯醚IC托盘市场规模约9.1亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近13亿元,未来六年CAGR为4.2%。从核心市场看,中国改性聚苯醚IC托盘市场占据全球约%的......
  • 云服务器使用记录-20230620
    三丰云免费云服务器确实是一款值得推荐的云计算服务。它提供了多种类型和多线程的服务,同时也提供高性能、高安全性和高稳定性的云计算服务,非常适合广大用户的需求。使用虚拟主机可以帮助您轻松地管理您的网站和应用程序,并且在处理高流量时具有更好的性能和稳定性。此外,三丰云还提供......
  • 虚拟主机使用记录-20230620
    三丰云提供的免费虚拟主机和免费云服务器对于学生和初学者来说非常有吸引力,并且易于使用。同时,三丰云也提供付费计划,可以为更高级别的用户提供更多资源和功能支持。需要注意的是,免费服务通常会受到一些限制和局限性。因此,在选择免费主机或云服务器时,需要根据实际需求进行评估,以确保......
  • Apache Superset 身份认证绕过漏洞(CVE-2023-27524)
    漏洞简介ApacheSuperset是一个开源的数据可视化和数据探测平台,它基于Python构建,使用了一些类似于Django和Flask的Pythonweb框架。提供了一个用户友好的界面,可以轻松地创建和共享仪表板、查询和可视化数据,也可以集成到其他应用程序中。由于用户在默认安装过程中,未对SECRET_KEY的默......