From 6fef760cbe0b6cd5fa28271afd400fe8f20fd996 Mon Sep 17 00:00:00 2001 From: Maxime Vorwerk Date: Tue, 30 Jul 2024 18:31:11 +0200 Subject: [PATCH] sra --- sra/chal.py | 25 ++++++++++++++++++ sra/sol.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100755 sra/chal.py create mode 100755 sra/sol.py diff --git a/sra/chal.py b/sra/chal.py new file mode 100755 index 0000000..fc8ef0e --- /dev/null +++ b/sra/chal.py @@ -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!") diff --git a/sra/sol.py b/sra/sol.py new file mode 100755 index 0000000..ea639b9 --- /dev/null +++ b/sra/sol.py @@ -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)) +