We can control ECC pubkey. So we can modify both the message and the signature. With the server-side AES-CTR decrypt oracle, we just do not change the encrypted AES key and nonce. Each time we add one byte to the message. Let server decrypt all zero hex bytes to get the XOR key of AES-CTR. Because we add one byte a time. We can bruteforce each byte. Then with the XOR key, we get the flag.
```#!/usr/bin/env python3from Crypto.PublicKey import RSA, ECCimport jsonfrom hashlib import sha256from Crypto.Cipher import AES, PKCS1_OAEPimport base64from Crypto.Signature import DSSfrom Crypto.Hash import SHA256from pwn import *
def xor(a, b):    return bytearray([a[i] ^ b[i % len(b)] for i in range(len(a))])
def main():    message = {"aeskey": "nwmHkXTN/EjnoO5IzhpNwE3nXEUMHsNWFI7dcHnpxIIiXCO+dLCjR6TfqYfbL9Z6a7SNCKbeTFBLnipXcRoN6o56urZMWwCioVTsV7PHrlCU42cKX+c/ShcVFrA5aOTTjaO9rxTMxB1PxJqYyxlpNaUpRFslzj9LKH+g8hVEuP9lVMm7q4aniyOUgPrAxyn044mbuxPu6Kh+JHSt5dkmnPZGNfUDKCwvMKeilb5ZkLaW/EaoXXsJLh/wUinMROIqmD2dkiWnk10633sJIu1lEOUsiykYXtJcd3o/B2dfTx2/85C2J6IsIp3+jJne76AYryAONPSxuh+M0h1xCzNeQg==", "message": "6VCnnSOU1DBImyhlqt7SoEjRtmBxjmABFVmXYhlKDyc+NBlnZ3Hpj4EkLwydPGpHiAvr4R0zTXSyUnMk5N6fi0/BFZE=", "nonce": "Cems9uHF6mk=", "signature": "uhLCnBvGfdC1fVkGUKQ8zNp/fOXNnFxNuDEc7CDGEYSxnuZMoGqbEqMLguJqDdvHFSHoUrq2R9/+mfk8LHndhw==", "eccpubkey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGww+NA3xHj4kCyztekLhmJVB62Hhq/oGDWwo4fxgZCgbODqD3vrMFFTGCWfO8ZyHtstuW+Yztpq94CnSNpJoug=="}    ecckey = ECC.generate(curve='p256')    eccpubkey = ecckey.public_key()    message["eccpubkey"] = "".join(eccpubkey.export_key(format="PEM").split("\n")[1:-1])    ciphertext = base64.b64decode(message["message"])    aeskey = base64.b64decode(message["aeskey"])    nonce = base64.b64decode(message["nonce"])    l = len(ciphertext)    #print(l)    signer = DSS.new(ecckey, "fips-186-3")    keystream = b""    for i in range(l):        text = b"\x00" * (i + 1)        h = SHA256.new(aeskey + nonce + text)        signature = signer.sign(h)        message["signature"] = base64.b64encode(signature).decode()        message["message"] = base64.b64encode(text).decode()        to_send = json.dumps(message)        print(i, to_send)        r = remote("crypto1.ctf.nullcon.net", 5001)        print(r.recvuntil("Enter message in json format: "))        r.send(to_send + "\n")        print(r.recvuntil("Here is your read receipt:\n"))        hm = r.recvuntil("\n").strip().decode()        print(hm)        for j in range(256):            digest = sha256(keystream + bytes([j])).hexdigest()            # print(j, digest, hm)            if digest == hm:                keystream += bytes([j])                print("keystream: ", [keystream], i, j)                break        r.close()        #exit()    flag = xor(ciphertext, keystream)    print("flag: ", flag)
'''flag:  bytearray(b'hackim20{digital_singatures_does_not_always_imply_authenticitaaayyy}')'''
if __name__ == "__main__":    main()
```