#!/usr/bin/env python3 import socketserver, sys from Crypto.Util.number import getPrime import gmpy2 import random, math from secret import flag def recvline(req): buf = b"" while not buf.endswith(b"\n"): buf += req.recv(1) return buf class RequestHandler(socketserver.BaseRequestHandler): def handle(self): rounds = 1 + int(2048 // math.log2(2020)) p = getPrime(1024) q = getPrime(1024) e = 65537 n = p * q phin = (p - 1) * (q - 1) d = int(gmpy2.invert(e, phin)) self.request.sendall(str(n).encode() + b"\n") secret_number = random.randint(0, n) c = pow(secret_number, e, n) self.request.sendall(str(c).encode() + b"\n") for _ in range(rounds): data = recvline(self.request).strip() c = int(data) resp = pow(c, d, n) % 2020 self.request.sendall(str(resp).encode() + b"\n") data = recvline(self.request).strip() m = int(data) if m == secret_number: self.request.sendall(flag) else: self.request.sendall(b"Oops...") class TCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass if __name__ == '__main__': HOST, PORT = "0.0.0.0", 9999 socketserver.TCPServer.allow_reuse_address = True server = TCPServer((HOST, PORT), RequestHandler) print("Server listening on port %d" % PORT) server.serve_forever()
mod2020のLSBLeakAttackだということを(ソースコードは与えられていなかったので)guessingする。あとは InCTF | waRSAwと同じなのでやるだけ
from Crypto.Util.number import * from socket import socket, AF_INET, SOCK_STREAM def read_data(): return int(file.readline().decode().strip()) def send_data(x): file.write(str(x).encode() + b'\n') file.flush() sock = socket(AF_INET, SOCK_STREAM) sock.connect(('34.87.174.144', 9999)) file = sock.makefile('rwb') n = read_data() e = 65537 c = read_data() M = 2020 def oracle(x): send_data(x) return read_data() i = 1 z = oracle(c) while True: inv = inverse(pow(M, i, n), n) c2 = (c * pow(inv, e, n)) % n ith_z = (oracle(c2) - (z * inv) % n) % M z = ith_z * (M ** i) + z i += 1 print(f"[+] {i}") if pow(z, e, n) == c: break while True: send_data(z) line = file.readline() print(line) if len(line) == 0: break