ASIS CTF Finals 2016: SRPP


SRPP is an abbreviation of

To solve this, let $A = 2N \equiv 0 \pmod N$. The server checks that $A \ne 0 \land A \ne N$, but this is not perfect. And $A \equiv 0$ makes things trivial.

#!/usr/bin/env python2
import hashlib
import string
import itertools
from pwn import * #
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('host', nargs='?', default='')
parser.add_argument('port', nargs='?', default=22778, type=int)
args = parser.parse_args()
context.log_level = 'debug'
p = remote(, args.port)

# proof of work
p.recvuntil('ASIS needs proof of work to start the SRPP challenge.\n')
_, salt, _, prefix, _ = p.recvline().split('"')
prefix = prefix.rstrip('.')'salt: %s', salt)'prefix: %s', prefix)
letters = string.digits + string.ascii_uppercase + string.ascii_lowercase
    for a in letters:
        for b in letters:
            for c in letters:
                for d in letters:
                    x = a + b + c + d
                    if hashlib.sha512(x + salt).hexdigest().startswith(prefix):
                        raise StopIteration
    log.error('Proof-of-Work Not Found')
except StopIteration:'result: %s', x)

def Hash(*args):
    a = ':'.join(str(a) for a in args)
    return int(hashlib.sha256(a).hexdigest(), 16)

p.recvuntil('(N, g, k) = ')
N, g, k = map(lambda s: int(s.strip('(L,)')), p.recvline().split())'N: %d', N)'g: %d', g)'k: %d', k)
assert k == Hash(N, g)

p.recvuntil('Send the email address and the public random positive value A seperated by "," as "email, A": ')
email = [email protected]'
A = 2*N'email: %d', email)'A: %d', A)
p.sendline('%s, %d' % (email, A))

p.recvuntil('(salt,  public_ephemeral) = ')
salt, B = p.recvline().split()
salt = salt.strip('(L,)').decode('base64')
B = int(B.strip('(L,)'))'salt: %s', repr(salt))'B: %d', B)

u = Hash(A, B)'u: %d', u)

p.recvuntil('Send the session key: \n')
S_s = 0
K_client = Hash(S_s)

p.recvuntil('Send a POC of session key: \n')
M_client = Hash(Hash(N) ^ Hash(g), Hash(email), salt, A, B, K_client)