Rating:

Connecting to the server, it requested me to give data that makes the last 32 bits of SHA-256 zero when added to the given prefix.
I created a program to solve this by brute-forcing. (this program looks taking upto 30 minutes to get the answer on my PC. Fortunately the server was patient enough to wait for the answer.)

Dividing g with small values, I found that g modulo 4 is 1.

Therefore, I calculated the 4th root of 1 modulo g. One of the roots is:

4689615487177589107664782585032558388794418913529425573939737788208931564987743250881967962324438559511711351322406

Putting this value as pubB will make shared (pubB to the privA-th power modulo g) be 1 because privA is a multiple of 40, which is a multiple of 4.

Then shared**3 and shared**5 are also 1. This means that the value of g is printed as verA and we can put the value as verB to pass the check.

Also knowing that g is the SHA-256 of password, we can obtain the value of password via hashcat.

Now it is easy to obtain the encryption key key, which is SHA-256 of a string created by concatenating password, "\0", and shared (1).

Finally it's time to decrypt AES. The encryption is done with AES.MODE_CTR and nonce=b''.
CyberChef asked a 16-byte IV to decrypt in CTR mode. 16 bytes of zero worked as IV.

Original writeup (https://mikecat.github.io/ctf-writeups/2021/20211218_hxp_CTF_2021/CRY/gipfel/#en).