import os,random,sys,string from hashlib import sha256 import SocketServer import signal from Crypto.Util.number import * from flag import FLAG
Nbits = 768 Pbits = 512
class Task(SocketServer.BaseRequestHandler): def proof_of_work(self): random.seed(os.urandom(8)) proof = ''.join([random.choice(string.ascii_letters+string.digits) for _ in xrange(20)]) digest = sha256(proof).hexdigest() self.request.send("sha256(XXXX+%s) == %s\n" % (proof[4:],digest)) self.request.send('Give me XXXX:') x = self.request.recv(10) x = x.strip() if len(x) != 4 or sha256(x+proof[4:]).hexdigest() != digest: return False return True def recvnum(self, sz): try: r = sz res ="" while r>0: res += self.request.recv(r) if res.endswith('\n'): r = 0 else: r = sz - len(res) res = res.strip() t = int(res) except: res = '' t = 0 return t
def dosend(self, msg): try: self.request.sendall(msg + '\n') except: pass def f(self, k, m): r = 0 x = getRandomInteger(Nbits) for i in range(len(k)): r = (r + k[i] * pow (x, i, m)) % m self.dosend("f(%d)=%d" % (x, r)) return x, r
def handle(self): signal.alarm(300) if not self.proof_of_work(): return signal.alarm(300) M = getPrime(Nbits) self.dosend("M=%d" % M) check = getRandomInteger(Nbits) % M K = [check] for i in range(Pbits): K = K + [getRandomInteger(Nbits)] self.dosend("How many f(x) do you want?") num = self.recvnum(1024) if num > 1024: self.dosend("Nonono") else : for i in range(num): self.f(K, M) answer = self.recvnum(1024) if answer == check: self.dosend("%s" % FLAG) else: self.dosend("Nonono") self.request.close()
class ForkingServer(SocketServer.ForkingTCPServer, SocketServer.TCPServer): pass
if __name__ == "__main__": HOST, PORT = '0.0.0.0', 2333 print (HOST) print (PORT) server = ForkingServer((HOST, PORT), Task) server.allow_reuse_address = True server.serve_forever()