Tags: hash 

Rating: 0

**Description**

> attachment: https://drive.google.com/open?id=15zha76BScH2HlpLz4lw15poN2kLZIcEX

**Solution**

There is a lot of useless code in this program, and it is unnecessary to reverse it. The only critical function is:

```c
int __cdecl sub_80488E0(char *s, __int64 c, int seed, int a5, int a6)
{
unsigned int v5; // ST4C_4
int i; // [esp+1Ch] [ebp-1Ch]

memset(s, 0, 0x20u);
scanf("%s", s);//get input
for ( i = 0; i <= 29; ++i )
{
v5 = critical_hash(s[i], c, seed, a6, a5);
printf("%lx\n", v5);
}
return i;
}
```

The second argument is a given constant; `s` is a buffer; the last 3 arguments are decided by debugging, which depends on seed that we input and the uninitialised local variable access (possibly UB?), and they can be differ based on input or separate program instances. However, what I did is to obtain these 3 arguments by gdb debugging with arbitrary input seed, and it works!

By the way, the first input in the main fuction is useless, it does not affect the result.

I did not reverse the `critical_hash` function, but did by bruteforce attack.

```c
#include <stdio.h>
#include <memory.h>

unsigned int keys[] =
{
0xB80C91FE,0x70573EFE,
0xBEED92AE,0x7F7A8193,
0x7390C17B,0x90347C6C,
0xAA7A15DF,0xAA7A15DF,
0x526BA076,0x153F1A32,
0x545C15AD,0x7D8AA463,
0x526BA076,0xFBCB7AA0,
0x7D8AA463,0x9C513266,
0x526BA076,0x6D7DF3E1,
0xAA7A15DF,0x9C513266,
0x1EDC3864,0x9323BC07,
0x7D8AA463,0xFBCB7AA0,
0x153F1A32,0x526BA076,
0xF5650025,0xAA7A15DF,
0x1EDC3864,0xB13AD888
};

unsigned int critical_hash(unsigned int a1, unsigned long long a2, int a3, int a4, int a5)
{
unsigned long long v5; // rax
unsigned int i; // [esp+1Ch] [ebp-ACh]
unsigned int v8; // [esp+20h] [ebp-A8h]
unsigned int j; // [esp+24h] [ebp-A4h]
int ub_hash; // [esp+28h] [ebp-A0h]
int s[32]; // [esp+2Ch] [ebp-9Ch]
unsigned int v12; // [esp+ACh] [ebp-1Ch]

memset(s, 0, 0x20u);
for ( i = 0; i <= 0x1D; ++i )
s[i] = (4 * a3 + ub_hash) ^ a5 ^ a4;
v8 = a1;
for ( j = 0; j <= 527; ++j )
{
v5 = a2 >> (j & 0x1F);
if ( j & 0x20 )
v5 = (v5 >> 32) | (v5 & 0xffffffff00000000LL) ;
v8 = (v8 >> 1) ^ (((unsigned int)v5 ^ v8 ^ (v8 >> 16) ^ (1551120942 >> (((v8 >> 1) & 1)
+ 2
* (2
* (((v8 >> 20) & 1)
+ 2
* (2 * ((v8 & 0x80000000) != 0)
+ ((v8 >> 26) & 1)))
+ ((v8 >> 9) & 1))))) << 31);
}
return v8;
}

int solve()
{
unsigned int v5; // ST4C_4
int i; // [esp+1Ch] [ebp-1Ch]
char flag[0x20];
memset(flag, 0, 0x20u);

for (i = 0; i <= 29; ++i )
{
for (int c = 0; c < 256; ++c)
{
v5 = critical_hash(c,
/*value obtained from gdb pwndbg*/0x1D082C23A72BE4C1LL, 0xffff9cc0, 0x6e00, 0x6e);
if (v5 == keys[i])
{
printf("%c", c);
}
}
}

return i;
}

int main(int argc, char const *argv[])
{
solve();
return 0;
}
```

`RCTF{Kee1o9_1s_a1ready_so1ved}`