0%

2023柏鹭杯rev1-wp

可以看到要求的输入长度是64个字符,前面是简单的验证输入的字符是否合规,红框圈起来的函数是主加密函数,下面可以不用分析了。

动态调试F7步入函数。

加密部分可以划分为三块,每一块都是用AVX2汇编实现的,类似于进行了内联汇编。这是第一部分,将我们的输入与ebp-40处开始的32个字节进行异或操作并保存到ymm0处。

第二部分是使用vphufb根据ebp-60处的32字节对ymm0处存放的数据进行重排。

c语言代码表示vpshufb ymm0, ymm0 , index

1
2
3
4
for (int i = 0; i < 32; ++i)
{
ymm0[i] = ymm0[index[i]];
}

最后是比较部分,ebp-20处存放的是比较数据。

那么逆向过程就是:

  1. 提取比较数据
  2. 重排
  3. 异或
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<stdio.h>
int main()
{
//加密过程
unsigned char xordata[32] = { //异或数据,与input进行异或
0xCD, 0xEB, 0x5E, 0x76, 0x0F, 0x22, 0xAF, 0x31, 0x82, 0x92, 0x3C, 0xEF, 0xB8, 0xC1, 0x76, 0x06,
0x18, 0x2F, 0xB5, 0x7D, 0x7F, 0x0A, 0xEA, 0x85, 0x92, 0x00, 0x89, 0xA3, 0x2C, 0xE2, 0xE7, 0x32};

unsigned char changedata[32] = { //重排表
0x0A, 0x07, 0x06, 0x0E, 0x02, 0x0B, 0x03, 0x0D, 0x01, 0x09, 0x00, 0x05, 0x04, 0x0F, 0x08, 0x0C,
0x1B, 0x18, 0x17, 0x1F, 0x14, 0x1E, 0x12, 0x13, 0x15, 0x1D, 0x16, 0x1C, 0x11, 0x10, 0x19, 0x1A};

unsigned char cmpdata[32] = { //比较数据
0x5F, 0x91, 0x99, 0xE8, 0x4E, 0xD0, 0xB0, 0x92, 0xB1, 0x3C, 0x4F, 0xF4, 0x17, 0x76, 0xDA, 0x12,
0x2A, 0x35, 0x01, 0x15, 0xF9, 0x97, 0x5E, 0x19, 0x9D, 0xC2, 0x15, 0x99, 0x70, 0x7D, 0x9F, 0xCC};

int flag[32];
for(int i=0;i<32;i++)
{
flag[changedata[31-i]]=cmpdata[31-i];
}

for(int j=0;j<32;j++)
{
flag[j]=flag[j]^xordata[j];
printf("%X",flag[j]);
}
return 0;
}

//825A10C618D636A058AE633FAA539E70655FEB648697FF84A79F4589B5207027
//flag{ISEC-a49d6b847bdba62c5bfa0a43b69c8575}

逆向过程没啥障碍,写脚本的时候flag[changedata[31-i]]=cmpdata[31-i];31写成了32,造成了越界,但是非常的不明显

离谱的是vscode有时候能跑起来有时候跑不起来,这里记录一下,以后注意这个问题,可能需要安装一个检测这种小错误的插件。