This commit is contained in:
Maxime Vorwerk
2024-07-30 18:31:11 +02:00
parent 3d2bc97bb7
commit 6fef760cbe
2 changed files with 100 additions and 0 deletions

25
sra/chal.py Executable file
View File

@@ -0,0 +1,25 @@
from Crypto.Util.number import getPrime, inverse, bytes_to_long
from string import ascii_letters, digits
from random import choice
pride = "".join(choice(ascii_letters + digits) for _ in range(16))
gluttony = getPrime(128)
greed = getPrime(128)
lust = gluttony * greed
sloth = 65537
envy = inverse(sloth, (gluttony - 1) * (greed - 1))
anger = pow(bytes_to_long(pride.encode()), sloth, lust)
print(f"{anger = }")
print(f"{envy = }")
print("vainglory?")
vainglory = input("> ").strip()
if vainglory == pride:
print("Conquered!")
with open("/challenge/flag.txt") as f:
print(f.read())
else:
print("Hubris!")

75
sra/sol.py Executable file
View File

@@ -0,0 +1,75 @@
#!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))