Tags: rev 

Rating: 5.0

Decompile with Ghidra:

```
fgets(local_2014,0xfff,_stdin);
decode_str(local_2014,0x3f,&DAT_00012094,local_1014);
iVar1 = strncmp(local_1014,"CORRECT!!!!!",0xc);
if (iVar1 == 0) {
puts(local_1014);
}

void decode_str(int param_1,int param_2,int param_3,int param_4)
{
int local_10;
int local_c;

local_10 = 0;
local_c = 0;
while (local_c < param_2) {
*(byte *)(param_4 + local_c) = *(byte *)(param_3 + local_c) ^ *(byte *)(param_1 + local_10);
local_c = local_c + 1;
local_10 = local_10 + 1;
if (0xb < local_10) {
local_10 = 0;
}
}
*(undefined *)(param_4 + local_c) = 0;
return;
}
```

Let's analyze what this is doing.
So the decode_str function is looping 0x3f times, iterating through both param_4, the flag, and param_3, a variable we can find with Ghidra.
Meanwhile, local_10 is being incremented too, until it is greater than 0xb, at which point it is reset back to 0. This loops through param_1, our input.
param_4[local_c] is set to param_3[local_c] ^ param_1[local_10] with each iteration.
Finally, the function returns and checks if the first 0xc characters of the string are equal to "CORRECT!!!!!"

Hence, it suffices to write a simple python program to reverse the XOR:

```
from pwn import *

b = [0x08, 0x3d, 0x33, 0x3f, 0x15, 0x36, 0x32, 0x47, 0x52, 0x12, 0x1b, 0x65, 0x6b, 0x48, 0x41, 0x0b, 0x3c, 0x14, 0x01, 0x1d, 0x34, 0x41, 0x5b, 0x29, 0x1b, 0x13, 0x4c, 0x26, 0x02, 0x34, 0x2b, 0x16, 0x06, 0x40, 0x17, 0x0d, 0x38, 0x5f, 0x22, 0x02, 0x3d, 0x1c, 0x08, 0x4b, 0x35, 0x5c, 0x48, 0x69, 0x0f, 0x13, 0x4c, 0x2f, 0x31, 0x11, 0x4b, 0x2d, 0x1a, 0x57, 0x49, 0x65, 0x6a, 0x53, 0x1c, 0x00]

s = 'CORRECT!!!!!'

for i in range(len(s)):
print(chr(b[i] ^ ord(s[i])), end='')
```

This gives us our input

KramPuffs3:D

We get

flag{GramPa-KRAMpus-Is-Comin-For-Da-Bad-Kids!!!}