Tags: pwn 

Rating: 5.0

As mentioned in other writeups, it's possible to adjust 5,5,5,5,5 values for each stage. But I couldn't find the solution in time.
However, there's a ceasar-like quiz in 40192c. Since all `scanf("%s", &buf;;` had stack BOF vulns, the xor key for each function could be modified after giving the input to quiz.

```c
void __fastcall __noreturn quiz(const char *a1)
{
char v1; // [rsp+10h] [rbp-30h]
unsigned __int64 v2; // [rsp+38h] [rbp-8h]

v2 = __readfsqword(0x28u);
putstr("King : You have only 1 chance.");
__isoc99_scanf("%s", &v1;;
if ( sub_401793(&v1) )
{
xor_str(improvef3, dword_607114, a1);
improvef3(0, 1, 1, 2, 0);
}
endgame("King : Wrong! You don't have ability to solve the worries of the people!", 0);
}

signed __int64 __fastcall sub_401793(const char *input)
{
int v2; // [rsp+18h] [rbp-78h]
signed int i; // [rsp+1Ch] [rbp-74h]
char dest[16]; // [rsp+20h] [rbp-70h]
char A[26]; // [rsp+30h] [rbp-60h]
char key[26]; // [rsp+50h] [rbp-40h]
char v7; // [rsp+72h] [rbp-1Eh]
unsigned __int64 v8; // [rsp+78h] [rbp-18h]

v8 = __readfsqword(0x28u);
qmemcpy(A, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", sizeof(A));
strcpy(key, "ALICEAWTQJMJXTSPPZVCIDGQYRDINMCP");
v7 = 0;
v2 = 0;
strncpy(dest, input, 5uLL);
for ( i = 5; i < strlen(input); ++i )
{
if ( A[(input[i] - 65 + dest[v2] - 65) % 26] != key[i] )
return 0LL;
v2 = (v2 + 1) % 5;
}
return 1LL;
}
```

There is multiple solution for quiz, and I chose AAAAAAWTQJMJXTSPPZVCIDGQYRDINMCP. After the solution, you can append \x00 since scanf doesn't treat the character as delimeter, and the distance between &v1 and a1 in quiz() is 0xc0. You can overwrite xor key for xor_str, which decodes improvef3 (0x401bfa) with xor decoding, and we can get shell by giving (encrypted code) ^ (our shellcode).

Full exploit is [here](https://gist.github.com/Jinmo/ac77fa58ff7e61b239637850ac869d8b).