1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
| import socketserver import os, sys, signal import string, random, time, json from hashlib import sha256 from secret import flag from Crypto.Cipher import AES from Crypto.Util.Padding import pad,unpad from ast import literal_eval as eval
key = os.urandom(32)
def decrypt(ciphertext:str,iv): try: iv = bytes.fromhex(iv) ciphertext = bytes.fromhex(ciphertext) cipher = AES.new(key, AES.MODE_CBC, iv) decrypted = unpad(cipher.decrypt(ciphertext),16) if not b'Admin' in decrypted: return 'Permissino denied !'
except ValueError as e: return str(e)
return decrypted
def encrypt(plaintext:str,admin=False): try: iv = os.urandom(16) payload = {'permission':'Guest','Time':f'{time.time()}','data':plaintext} print(payload) payload = pad(json.dumps(payload).encode(),16) cipher = AES.new(key, AES.MODE_CBC, iv) encrypted = cipher.encrypt(payload) except ValueError as e: return str(e)
return iv.hex() + encrypted.hex()
class Task(socketserver.BaseRequestHandler): def _recvall(self): BUFF_SIZE = 2048 data = b'' while True: part = self.request.recv(BUFF_SIZE) data += part if len(part) < BUFF_SIZE: break return data.strip()
def send(self, msg, newline=True): if type(msg) is str: msg = msg.encode() try: if newline: msg += b'\n' self.request.sendall(msg) except: pass
def recv(self, prompt=b'> '): self.send(prompt, newline=False) return self._recvall()
def close(self): self.send(b"Bye~") self.request.close()
def proof_of_work(self): random.seed(os.urandom(8)) proof = ''.join([random.choice(string.ascii_letters+string.digits) for _ in range(20)]) _hexdigest = sha256(proof.encode()).hexdigest() self.send(f"sha256(XXXX+{proof[4:]}) == {_hexdigest}".encode()) x = self.recv(prompt=b'Give me XXXX: ') if len(x) != 4 or sha256(x+proof[4:].encode()).hexdigest() != _hexdigest: return False return True
def handle(self): if 0 and not self.proof_of_work(): return menu = '''1. Encrypt data\n2. Decrypt data\n3. Get encrypted flag\n'''
while 1: self.send('\n' + menu) try: r = int(self.recv()) except: continue if r == 3: self.send(b'Encrypted flag:\n') self.send(encrypt(flag.hex())) elif r == 2: iv,data = self.recv(prompt=b'Data to decrypt:').strip().split(b'||') self.send(decrypt(data.decode(),iv.decode())) elif r == 1: data = self.recv(prompt=b'Data to encrypt:').strip() self.send(encrypt(data.decode()))
self.close()
class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass
class ForkedServer(socketserver.ThreadingMixIn, socketserver.TCPServer): pass
if __name__ == "__main__": HOST, PORT = '0.0.0.0', 10000 server = ForkedServer((HOST, PORT), Task) server.allow_reuse_address = True server.serve_forever()
|