Skip to content

Instantly share code, notes, and snippets.

@wapiflapi
Created October 9, 2019 10:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wapiflapi/6c7f2620874ddc107ae989d1197ae5af to your computer and use it in GitHub Desktop.
Save wapiflapi/6c7f2620874ddc107ae989d1197ae5af to your computer and use it in GitHub Desktop.
@wapiflapi's solution for RektSA from https://qual.rtfm.re 2019
"""
@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()
@wapiflapi
Copy link
Author

FTR, the original challenge by @SIben:

#!/usr/bin/python2.7

import sys
from secret import FLAG
from Crypto.Util.number import getPrime, bytes_to_long
from gmpy2 import invert

p = getPrime(1024)
q = getPrime(1024)
r = getPrime(1028)

e = 0x10001

N = p * q * r
phi = (p - 1) * (q - 1) * (r - 1)

print 'N:', N
print 'phi:', phi % 2**2050
print 'r:', r

print 'Give me d: '

sys.stdout.flush()

try:
    d = int(raw_input())
except:
    print 'Invalid input!'
    exit(1)

if d == invert(e, phi):
    print 'Congratulations: %s' % FLAG
else:
    print 'Nope!'
    exit(1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment