第四届美团2021WP_复现

还是一样菜呜呜呜

RE

比赛中只做出了最简单的,其他的不会

Random

只需看主函数,逻辑挺简单的,已修改部分函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // esi
int v5; // edx
int v6; // ecx
int v7; // esi
int v8; // eax
char *v9; // eax
int result; // eax
int v11; // [esp-4h] [ebp-2Ch]
const char **v12; // [esp+0h] [ebp-28h]
const char **v13; // [esp+4h] [ebp-24h]

if ( !n )
scanf("%s", flag);
v3 = rand();
srand(v3);
v4 = n;
flag[v4] ^= rand();
if ( n == 43 )
{
n = 0;
v5 = 0;
v6 = 0;
v7 = 0;
v8 = 0;
do
{
if ( flag[v8] != a[v7] )
break;
v7 = ++v5;
v6 = v5;
n = v5;
v8 = v5;
}
while ( v5 < 42 );
v9 = "fake input..\n";
if ( v6 == 42 )
v9 = "congratulation!\n";
puts(v9);
result = 0;
}
else
{
++n;
main(v11, v12, v13);
result = 0;
}
return result;
}

然后就是获取rand的函数值,想自己写脚本跑出随机值,但失败了,不知道为什么,按理说应该是不变的,第1次的rand的种子是1,然后后面的都可以确定。

那我们通过动调来获取,输入42个1,f8直到运行完异或,得到异或的值,动调得到的值和49异或,得到随机值后与数组a异或即可得到flag


dongtiao = [0x69, 0x90, 0xFA, 0xD8, 0xDC, 0x1D, 0xDD, 0xCA, 0xD8, 0xF5, 0x27, 0xA6, 0xA8, 0x80, 0x95, 0xD8, 0xF2, 0xF7, 0xB1, 0x8E, 0x0F, 0x75, 0x29, 0x1F, 0x42, 0x67, 0x63, 0x89, 0x6A, 0x57, 0xDC, 0x8D, 0xBB, 0xE9, 0x07, 0xBE, 0xD7, 0xE2, 0x80, 0x60, 0x88, 0x68]
s = [88, 161, 203, 233, 237, 44, 236, 251, 233, 196, 22, 151, 153, 177, 164, 233, 195, 198, 128, 191, 62, 68, 24, 46, 115, 86, 82, 184, 91, 102, 237, 188, 138, 216, 54, 143, 230, 211, 177, 81, 185, 89]
for i in range(42):
print((dongtiao[i] ^ 49), end=",") # s数组

a = [0x3E, 0xCD, 0xAA, 0x8E, 0x96, 0x1F, 0x89, 0xCD, 0xDB, 0xF1,
0x70, 0xF2, 0xA9, 0x9C, 0xC2, 0x8B, 0xF2, 0xFE, 0xAD, 0x8B,
0x58, 0x7C, 0x2F, 0x03, 0x4A, 0x65, 0x31, 0x89, 0x76, 0x57,
0x88, 0xDF, 0xB8, 0xE9, 0x01, 0xE9, 0xDE, 0xE5, 0x86, 0x68,
0x8F, 0x24, 0xD3, 0x5A]
for i in range(42):
print(chr(a[i] ^ s[i]), end="")

wow

Superflat