0%

2020 GXZYCTF 天津垓

有两层加密,第一次的正确作为smc解密的密钥
第一层考点:去反调试
64位的程序发现有反调试

1
2
3
4
5
6
7
8
9
_BOOL8 sub_10040162B()
{
_BOOL8 result; // rax

result = sub_100401195();
if ( (_DWORD)result )
exit(1);
return result;
}

发现有反调试直接nop掉
第二层考点:算法求解
找到关键算法后直接爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
int main()
{
char key[] = "Rising_Hopper!";
int result[] = { 17,8,6,10,15,20,42,59,47,3,47,4,16,72,62,0,7,16 };
char flag;
for (int i = 0; i <= 17;i++)
{
for (flag = 0x20; flag <= 0x7e; flag++)
{
if ((~(flag & key[i % 14]) & (flag | key[i % 14])) == result[i])
{
printf("%c",flag);
}
}
}

}

Caucasus@s_ability
第三层考点:smc

1
2
3
4
5
6
7
8
9
10
11
12
13
lpAddress = a1;
v7 = a2;
v8 = a3;
if ( strlen(Str) != 18 )
exit(1);
if ( !VirtualProtect(lpAddress, v7, 0x40u, &flOldProtect) )
exit(1);
for ( i = 0; i < v7; ++i )
*((_BYTE *)lpAddress + i) ^= *(_BYTE *)(i % 18 + v8);
result = VirtualProtect(lpAddress, v7, flOldProtect, &flOldProtect);
if ( !result )
exit(1);
return result;

这是利用第一层密文对代码进行加密,执行完后dump出内存,重新利用IDAf5便可找到关键算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
int main()
{
int result[]={0x1EA272,0x206FC4,0x1D2203,0x1EEF55,0x24F111,0x193A7C,0x1F3C38,0x21566D,0x2323BF,0x2289F9,0x1D2203,0x21098A,0x1E08AC,0x223D16,0x1F891B,0x2370A2,0x1E558F,0x223D16,0x1C883D,0x1F891B,0x2289F9,0x1C883D,0xEB773,0xE6A90,0xE6A90,0xE6A90,0xB1CCF,0x1C883D,0x2289F9,0x22D6DC,0x223D16,0x21566D,0x21098A,0x1EEF55,0x1E558F,0x223D16,0x1C883D,0x22D6DC,0x1F3C38,0x1D2203,0x21098A,0x1C883D,0x24A42E,0x1E558F,0x223D16,0x21566D,0xD83E7,0x21566D,0x21098A,0x1E558F,0x258AD7};
for (int i = 0; i <= 51;i++)
{
for (int j = 0x20; j <= 0x7e; j++)
{
if (0x4ce3 *j % (unsigned int)0x8000000B == result[i])
{
printf("%c",j);
}
}
}
}
flag{Thousandriver_is_1000%_stronger_than_zero-one}