能力值:
( LV3,RANK:20 )
|
-
-
2 楼
wormfox
srand 随机种子固定的啊 这表示产生的随机序列是可预测的!
对啊 但是这个题 到底要干啥 很懵啊 key我也没有跑出来 。。。很难受
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
帮你整理了一下代码, 你对照着看吧 void __fastcall PCcheck(char *a1)
{
signed int k; // eax@10
signed int count; // [rsp+14h] [rbp-18Ch]@7
int i; // [rsp+18h] [rbp-188h]@7
signed int j; // [rsp+1Ch] [rbp-184h]@15
char cpuid[32]; // [rsp+20h] [rbp-180h]@1
char key[32]; // [rsp+40h] [rbp-160h]@7
char uuidMD5[48]; // [rsp+60h] [rbp-140h]@1
char cpuidMD5[48]; // [rsp+90h] [rbp-110h]@1
char tmpMD5[48]; // [rsp+C0h] [rbp-E0h]@1
char uuid[48]; // [rsp+F0h] [rbp-B0h]@1
char allAlpha[96]; // [rsp+120h] [rbp-80h]@7
/* 初始化 */
memset(uuid, 0, sizeof(uuid));
memset(cpuid, 0, sizeof(cpuid));
memset(uuidMD5, 0, sizeof(uuidMD5));
memset(cpuidMD5, 0, sizeof(cpuidMD5));
memset(tmpMD5, 0, sizeof(tmpMD5));
/* 取机器 的 UUID 然后做两次 MD5, 命令行为 */
getSystemUUID(uuid); /* dmidecode -t 1 | grep UUID | cut -c8-43 */
getMD5(uuid, tmpMD5);
getMD5(tmpMD5, uuidMD5);
/* 结果必须是 fa8480059051f6c10031ad134f360206 */
if ( strcmp(uuidMD5, "fa8480059051f6c10031ad134f360206") )
{
puts("Machine inspection fail! Please use an authorized machine.");
exit(-1); /* 检查点 1 */
}
/* 取机器的 CPUID 然后做两次 MD5, 命令行为 */
getCPUID(cpuid); /* dmidecode -t 4 | grep ID | tail -1 | cut -c6-28 | tr -d ' ' */
getMD5(cpuid, tmpMD5);
getMD5(tmpMD5, cpuidMD5);
/* 结果必须是 95962c6dfce78b57578a874640013ba2 */
if ( strcmp(cpuidMD5, "95962c6dfce78b57578a874640013ba2") )
{
puts("Machine inspection fail! Please use an authorized machine.");
exit(-1); /* 检查点 2 */
}
/* 把 uuid + cpuid 拼成一个串 */
strcpy(a1, uuid);
strcat(a1, cpuid);
/* 取出这个串中的所有的 A-F 填到一个新的串 allAlpha */
count = 0;
memset(allAlpha, 0, sizeof(allAlpha));
memset(key, 0, sizeof(key));
for ( i = 0; i < strlen(a1); ++i )
{
if ( a1[i] >= 'A' && a1[i] <= 'F' )
{
k = count++;
allAlpha[k] = a1[i];
}
}
/* allAlpha 的长度至少为 9 个字符 */
if ( count <= 9 )
exit(-1); /* 检查点 3 */
/* 把 allAlpha 乱序, 即用固定种子的随机序列把 allAlpha 中的值填到 key 中 */
srand(0x90u);
for ( j = 0; j <= 9; ++j )
key[j] = allAlpha[rand() % count];
/* 这就是最终的返回结果 */
strcpy(a1, key);
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rt1@1
int v4; // ST24_4@1
int str_len; // ST20_4@1
int result; // eax@13
__int64 v7; // rsi@13
int i; // [rsp+14h] [rbp-52Ch]@1
int j; // [rsp+14h] [rbp-52Ch]@4
signed int k; // [rsp+18h] [rbp-528h]@10
int des_block; // [rsp+1Ch] [rbp-524h]@1
FILE *stream; // [rsp+28h] [rbp-518h]@10
char ks1; // [rsp+30h] [rbp-510h]@1
char ks2; // [rsp+130h] [rbp-410h]@1
char ks3; // [rsp+230h] [rbp-310h]@1
char keystring[16]; // [rsp+330h] [rbp-210h]@1
char key[32]; // [rsp+340h] [rbp-200h]@1
char des[24]; // [rsp+360h] [rbp-1E0h]@1
char deskey[24]; // [rsp+380h] [rbp-1C0h]@1
char string[32]; // [rsp+3A0h] [rbp-1A0h]@1
char str[64]; // [rsp+3C0h] [rbp-180h]@1
char desin[64]; // [rsp+400h] [rbp-140h]@1
char desout[64]; // [rsp+440h] [rbp-100h]@1
char v24[64]; // [rsp+480h] [rbp-C0h]@1
char png[112]; // [rsp+4C0h] [rbp-80h]@1
__int64 v26; // [rsp+538h] [rbp-8h]@1
/* 生成 key */
memset(key, 0, sizeof(key));
PCcheck(key);
/* 实际 Key : KEY:FF + key */
*(_QWORD *)string = 'FF:YEK';
*(_QWORD *)&string[8] = 0LL;
*(_QWORD *)&string[16] = 0LL;
string[24] = 0;
strcat(string, key);
/* 待加密的固定串 */
strcpy(str, "Hint:The_key_is_the_key");
*(_QWORD *)&str[24] = 0LL;
*(_QWORD *)&str[32] = 0LL;
*(_QWORD *)&str[40] = 0LL;
*(_QWORD *)&str[48] = 0LL;
*(_DWORD *)&str[56] = 0;
/* 初始化 */
/* 相当于 png[111] = { 0x3C, ...., 0x18 }; */
png[0] = 0x3C;
...
png[110] = 0x18;
/* 相当于 des[24] = { 0xF4, ...., 0xA5 }; */
des[0] = 0xF4;
...
des[23] = 0xA5;
memset(desin, 0, sizeof(desin));
memset(desout, 0, sizeof(desout));
memset(v24, 0, sizeof(v24));
/* 初始化 des */
v4 = strlen(string);
memcpy(deskey, string, v4);
memset(&deskey[v4], 0, 24 - v4);
*(_QWORD *)keystring = *(_QWORD *)deskey;
DES_set_key_unchecked(keystring, &ks1);
*(_QWORD *)keystring = *(_QWORD *)&deskey[8];
DES_set_key_unchecked(keystring, &ks2);
*(_QWORD *)keystring = *(_QWORD *)&deskey[16];
DES_set_key_unchecked(keystring, &ks3);
/* 加密固定串 */
str_len = strlen(str);
memcpy(desin, str, str_len);
des_block = 8 * (str_len / 8 + 1);
memset(&desin[str_len], (char)(8 - (char)str_len % 8), 8 - str_len % 8);
for ( i = 0; i < des_block; i += 8 )
DES_ecb3_encrypt(&desin[i], &desout[i], &ks1, &ks2, &ks3, 1LL);
/* 比较加密结果 */
for ( j = 0; j < des_block; ++j )
{
if ( desout[j] != des[j] )
{
puts("Error!");
exit(0); /* 检查点 4 */
}
}
/* 成功, 输出 key */
puts("Congratulations, this is your key:");
puts(" aaaaa");
puts(" aaaaaaaaaa");
puts("aaaa aaaaaaaaaaaaaaaaaaa");
printf("aaa aaaaaaaaFF%s\n", key, argv);
puts("aaaa aaaaaaaaaaaaaaaaaaa");
puts(" aaaaaaaaaa");
puts(" aaaaa");
/* 解密成功标志文件 */
stream = fopen("flag.png", "wb");
for ( k = 0; k <= 110; ++k )
fputc((char)(PNG[k] ^ png[k]), stream);
fclose(stream);
result = 0;
return result;
}
这个程序有四个检查点, 三个在 PCcheck, 一个在 main, 不成功会直接退出, 成功后会输出正确的 key, 并且会解密 flag.png 文件. 所以你看看题目的要求是什么, 是爆破呢, 还是求真正的 key, 然后决定在哪下手吧
|
能力值:
( LV3,RANK:20 )
|
-
-
4 楼
arab
帮你整理了一下代码, 你对照着看吧void __fastcall PCcheck(char *a1)
{
&nbs ...
谢谢您! 我再好好看看。。
|