No captcha required for preview. Please, do not write just a link to original writeup here.
```python#!/usr/bin/env python
from pwn import *import re
from Crypto.Hash import SHA256from Crypto.Cipher import AES
# context.log_level = 'debug'
def enc(a):    f = {str: str.encode, int: int.__str__}.get(type(a))    return enc(f(a)) if f else a
def H(*args):    data = b'\0'.join(map(enc, args))    return SHA256.new(data).digest()
q = 0x3a05ce0b044dade60c9a52fb6a3035fc9117b307ca21ae1b6577fef7acd651c1f1c9c06a644fd82955694af6cd4e88f540010f2e8fdf037c769135dbe29bf16a154b62e614bb441f318a82ccd1e493ffa565e5ffd5a708251a50d145f3159a5
def brute_flag(fb):    for password in range(10**6):        key = H(password, 1)        aes = AES.new(key, AES.MODE_CTR, nonce=b'')        decrypt = aes.decrypt(fb)        if b'hxp{' in decrypt:            return decrypt        if password % 100000 == 0 and password > 0: log.info('{}%'.format((password / 10**6) * 100))
pow_re = re.compile(r'^please give S such that sha256\(unhex\("(\w+)" \+ S\)\) ends with (\d+) zero bits \(see pow-solver\.cpp\)\.$')
def solve_pow(p):    line = p.recvline().decode().strip()    m = pow_re.match(line)    prefix, bits = m.groups()
 log.info("Solving pow for prefix {} and {} bits.".format(prefix, bits))    solver = process(["./gipfel/pow-solver", bits, prefix])    suffix = solver.recvall().strip()    log.success("Got suffix: {}".format(suffix))    solver.close()    p.sendline(suffix)
def main():    # p = process(["python", "gipfel/vuln.py"])    p = remote("65.108.176.66", 1088)    solve_pow(p)
    pubA_line = p.recvline().decode() log.info(pubA_line)    p.sendline(hex(q - 1).encode())
    verA_line = p.recvline().decode()    verA = verA_line.split("=")[1].strip() log.info(verA_line)    p.sendline(verA.encode())
    flag_line = p.recvline().decode()    flag_bytes = bytes.fromhex(flag_line.split(":")[1].strip())    log.success(flag_line)
 log.info("Bruteforcing key...")    flag = brute_flag(flag_bytes)    log.success("Flag: {}".format(flag.decode()))
    p.close()
if __name__ == '__main__':    main()```
Running the exploit gives us the flag after awhile. The longest time bottlenecks were theproof-of-work computation and the search for the right key.
```consolevagrant@ubuntu-xenial:/vagrant/hxp/gipfel$ python exploit.py[+] Opening connection to 65.108.176.66 on port 1088: Done[*] Solving pow for prefix 37f3d460d77c3dd6 and 32 bits.[+] Starting local process './gipfel/pow-solver': pid 3117[+] Receiving all data: Done (17B)[*] Process './gipfel/pow-solver' stopped with exit code 0 (pid 3117)[+] Got suffix: b'0200000003f2a41a'[*] pubA = 0x74498994c446fb5673b5a941f0cda711ef22c8b228eeaec6c7a1c315c948aeebfd8cadd1c3352c05e751be139807389430649f1db4a3bc75edecb91706df5427719544344108ab2dbea513cf202fe70d8dae2636d4709b126aa727b4997d98[*] verA = 0x18eeaff89770d1771299a47e45562162f0ebb60a0297a1f3c3ce4eb431e3cb70[+] flag: 929bc92d8abb3528be57d2c237aab1ab241c91df6a48a65e79cc509fdabf771d3a07e9a48dacbfa5[*] Bruteforcing key...[+] Flag: hxp{ju5T_k1ddIn9_w3_aLl_kn0w_iT's_12345}[*] Closed connection to 65.108.176.66 port 1088vagrant@ubuntu-xenial:/vagrant/hxp/gipfel$```
**Flag:** `hxp{ju5T_k1ddIn9_w3_aLl_kn0w_iT's_12345}`
Full writeup with details here: [https://nandynarwhals.org/hxp-ctf-2021-gipfel/](https://nandynarwhals.org/hxp-ctf-2021-gipfel/)