I opened the binary in IDA, and looked at the import table. I looked at the XRef of CryptDecrypt.The function calling it didn't seem to have much of a verification, so I jump to the XRef of this function.
The interesting part of the function is```cv35 = GetDlgItem(hWndParent, 4);sub_406920(&v58, 0, 50);GetWindowTextA(v35, (LPSTR)&Paint, 32);v36 = strlen((const char *)&Paint);if ( v36 >= 6 ){  v37 = SLOBYTE(Paint.fErase) % 7;  v38 = 1;  for ( i = 2; i < v37; ++i )    v38 *= (_BYTE)i;  v40 = 0;  if ( (unsigned int)v36 >= 0x40 )  {    v41 = _mm_cvtsi32_si128(v38);    v42 = _mm_unpacklo_epi8(v41, v41);    v43 = _mm_shuffle_epi32(_mm_unpacklo_epi16(v42, v42), 0);    do    {      *(__int128 *)((char *)&v58 + v40) = (__int128)_mm_xor_si128(*(__m128i *)((char *)&Paint.hdc + v40), v43);      *(__int128 *)((char *)&v59 + v40) = (__int128)_mm_xor_si128(                                                      *(__m128i *)((char *)&Paint.rcPaint.right + v40),                                                      v43);      *(__int128 *)((char *)&v60 + v40) = (__int128)_mm_xor_si128(*(__m128i *)&Paint.rgbReserved[v40], v43);      *(__m128i *)((char *)&v61 + v40) = _mm_xor_si128(*(__m128i *)&Paint.rgbReserved[v40 + 16], v43);      v40 += 64;    }    while ( v40 < v36 - v36 % 64 );  }  for ( ; v40 < v36; ++v40 )    *((_BYTE *)&v58 + v40) = v38 ^ *((_BYTE *)&Paint.hdc + v40);  *((_BYTE *)&v58 + v40) = 0;  v44 = 0;  do  {    *((_BYTE *)&v58 + v44) = __ROL1__(*((_BYTE *)&v58 + v44) ^ byte_420AE0[v44], v44);    ++v44;  }  while ( v44 < v36 );  v45 = &v5;;  v46 = (char *)&unk_4278D8;  v47 = 27;  while ( *(_DWORD *)v45 == *(_DWORD *)v46 )  {    v45 = (__int128 *)((char *)v45 + 4);    v46 += 4;    v48 = v47 < 4;    v47 -= 4;    if ( v48 )    {      if ( *(_WORD *)v45 == *(_WORD *)v46 && *((_BYTE *)v45 + 2) == v46[2] )      {        MessageBoxA(hWndParent, "orz", "orz", 0);        function_calling_decrypt((BYTE *)&Paint);      }      return 0;    }  }}```
There still is much to look at. `v58` is the user input, and `v36` is its length.By trying some things here and there, I found out that the user input can't be more than 0x40.Reducing the code to```cv35 = GetDlgItem(hWndParent, 4);sub_406920(&v58, 0, 50);GetWindowTextA(v35, (LPSTR)&Paint, 32);v36 = strlen((const char *)&Paint);if ( v36 >= 6 ){  v37 = SLOBYTE(Paint.fErase) % 7;  v38 = 1;  for ( i = 2; i < v37; ++i )    v38 *= (_BYTE)i;  v40 = 0;  for ( ; v40 < v36; ++v40 )    *((_BYTE *)&v58 + v40) = v38 ^ *((_BYTE *)&Paint.hdc + v40);  *((_BYTE *)&v58 + v40) = 0;  v44 = 0;  do  {    *((_BYTE *)&v58 + v44) = __ROL1__(*((_BYTE *)&v58 + v44) ^ byte_420AE0[v44], v44);    ++v44;  }  while ( v44 < v36 );  v45 = &v5;;  v46 = (char *)&unk_4278D8;  v47 = 27;  while ( *(_DWORD *)v45 == *(_DWORD *)v46 )  {    v45 = (__int128 *)((char *)v45 + 4);    v46 += 4;    v48 = v47 < 4;    v47 -= 4;    if ( v48 )    {      if ( *(_WORD *)v45 == *(_WORD *)v46 && *((_BYTE *)v45 + 2) == v46[2] )      {        MessageBoxA(hWndParent, "orz", "orz", 0);        function_calling_decrypt((BYTE *)&Paint);      }      return 0;    }  }}```
`SLOBYTE(Paint.fErase)` is the 7th character of the user input.`v38` value depends then on this character value modulo 7.The whole user input is then xored with `v38`.Then it is xored again, with `ANNAWGALFYBKVIAHMXTFCAACLAAAAYK`.
The result is then compared with a fixed value.
I made the following script from these observations```c#include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <limits.h>
uint8_t rotr32 (uint8_t value, unsigned int count) {    // From wikipedia    const unsigned int mask = CHAR_BIT * sizeof(value) - 1;    count &= mask;    return (value >> count) | (value << (-count & mask));}
const unsigned char correct[] = {0x4E, 0xAE, 0x61, 0x0BA, 0x0E4, 0x2B, 0x55, 0x0AA, 0x59, 0x0FC, 0x4D, 0x2, 0x17, 0x6B, 0x13, 0x0A1, 0x41, 0x0FE, 0x35, 0x0B, 0x0B4, 0x0B, 0x52, 0x2F, 0x46, 0x0CC, 0x35, 0x82, 0x0E5, 0x88, 0x50};const unsigned char modif[] = "ANNAWGALFYBKVIAHMXTFCAACLAAAAYK";
int main() {  char final[32] = {0};  for (unsigned char i = 0; i < 32; i++) {    unsigned char tmp = rotr32(correct[i], i) ^ 0x78 ^ modif[i]; // After a few attemps v38 was 0x78    final[i] = tmp;  }  printf("%s\n", final);  return 0;}```
which output `wannaflag_is_just_a_paper_tigerx`Entering this into the binary give you the flag```GACTF{WannaFlag_is_just_a_easy_re_with_a_beautiful_appearance}```