76 lines
2.0 KiB
Python
Executable File
76 lines
2.0 KiB
Python
Executable File
#!python3
|
|
from sage.all import *
|
|
from sympy.utilities.iterables import multiset_partitions
|
|
from pwn import *
|
|
|
|
port = 62870
|
|
conn = remote("saturn.picoctf.net", port)
|
|
|
|
conn.recvuntil(b"anger = ")
|
|
c = Integer(int(conn.recvline()))
|
|
log.info("received c: {}".format(c))
|
|
conn.recvuntil(b"envy = ")
|
|
d = Integer(int(conn.recvline()))
|
|
log.info("received d: {}".format(d))
|
|
e = Integer(65537)
|
|
log.info("preknown e: {}".format(e))
|
|
|
|
kN = e*d - 1
|
|
log.info("kN: {}".format(kN))
|
|
kN_factors = factor(kN)
|
|
log.info("factorized kN: {}".format(kN_factors))
|
|
|
|
kN_multiset = []
|
|
for a, b in kN_factors:
|
|
for i in range(b):
|
|
kN_multiset.append(a)
|
|
log.info("generated multiset: {}".format(kN_multiset))
|
|
|
|
candidates = []
|
|
kN_multiparts = multiset_partitions(kN_multiset, 3)
|
|
iLogger = log.progress("checking multiset partitions")
|
|
for kN_multipart in kN_multiparts:
|
|
_x = kN_multipart[0]
|
|
_y = kN_multipart[1]
|
|
_z = kN_multipart[2]
|
|
S = [prod(_x), prod(_y), prod(_z)]
|
|
S.sort(reverse=True)
|
|
x, y, z = S
|
|
if y.nbits() == 128:
|
|
if x.nbits() == 128:
|
|
candidates.append((x, y, z))
|
|
elif z.nbits() == 128:
|
|
candidates.append((y, z, x))
|
|
iLogger.success("found {} candidates".format(len(candidates)))
|
|
solutions = []
|
|
|
|
for _p, _q, _k in candidates:
|
|
if (_p+1).is_prime() and (_q+1).is_prime():
|
|
p = _p+1
|
|
q = _q+1
|
|
N = p*q
|
|
k = _k
|
|
solutions.append((p, q, N, k))
|
|
log.info("found {} solutions".format(len(solutions)))
|
|
if len(solutions) != 1:
|
|
log.critical("Too many/little solutions")
|
|
exit(1)
|
|
|
|
p, q, N, k = solutions[0]
|
|
log.success("p: {}".format(p))
|
|
log.success("q: {}".format(q))
|
|
log.success("N: {}".format(N))
|
|
log.success("k: {}".format(k))
|
|
m = pow(c, d, N)
|
|
log.info("decoded message: {}".format(m))
|
|
m_string = pack(int(m), "all", "big", False)
|
|
log.info("literal message: {}".format(m_string))
|
|
|
|
conn.recvuntil(b"> ")
|
|
conn.sendline(m_string)
|
|
|
|
conn.recvuntil(b"Conquered!")
|
|
flag = conn.recvuntil(b'}').strip().decode()
|
|
log.success("flag: {}".format(flag))
|
|
|