Created
October 9, 2019 10:02
-
-
Save wapiflapi/6c7f2620874ddc107ae989d1197ae5af to your computer and use it in GitHub Desktop.
@wapiflapi's solution for RektSA from https://qual.rtfm.re 2019
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
@wapiflapi's solution for RektSA from https://qual.rtfm.re 2019 | |
This simply uses z3 which takes about a second longer than the challenge | |
timeout: Keeping the connection alive is enough to circumvent the timeout. | |
~/Projects/ctf/rtfm$ time ./decrypt.py | |
Congratulations: sigsegv{th1s_1s_4_cr1m3...4_mult1cr1m3!!!} | |
real 0m2,741s | |
user 0m3,340s | |
sys 0m0,417s | |
""" | |
import socket | |
import multiprocessing | |
import multiprocessing.pool | |
import gmpy2 | |
import z3 | |
def solve(e, N, r, phimod): | |
"""Solve equations copied directly from the challenge.""" | |
s, p, q, phi = z3.Solver(), z3.Int("p"), z3.Int("q"), z3.Int("phi") | |
s.add( | |
(p > 2**1023), (p < 2**1024), | |
(q > 2**1023), (q < 2**1024), | |
(p * q * r == N), | |
(phimod == phi % 2**2050), | |
(phi == (p - 1) * (q - 1) * (r - 1)), | |
) | |
s.check() | |
return gmpy2.invert(e, s.model()[phi].as_long()) | |
def main(): | |
"""Keep-alive the connection while the result is computed.""" | |
s = socket.socket() | |
s.connect(("qual-challs.rtfm.re", 9001)) | |
lines = s.recv(4096).decode("utf8").split("\n") | |
defs = ([e.strip() for e in l.split(":")] for l in lines) | |
vmap = {l[0]: int(l[1]) for l in defs if len(l) == 2 and l[1]} | |
async_result = multiprocessing.pool.ThreadPool( | |
processes=1 | |
).apply_async(solve, args=( | |
0x10001, vmap["N"], vmap["r"], vmap["phi"], | |
)) | |
while True: | |
try: | |
s.send((b"%d\r\n" % async_result.get(timeout=0.5))) | |
except multiprocessing.context.TimeoutError: | |
# Keep the connection alive so we do not timeout. | |
s.send(b"0") # '0' as a prefix is valid for int() parser. | |
else: | |
break | |
print(s.recv(4096).decode("utf8")) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FTR, the original challenge by @SIben: