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 116 117 118 119 120 121 122
| localhost:/$ cd opt cd opt localhost:/opt$ ls ls containerd server localhost:/opt$ cd server cd server localhost:/opt/server$ ls ls Dockerfile server.py localhost:/opt/server$ cat server.py cat server.py import socket import threading import json import hashlib
FLAG = "flag{superuser/f124cf868d5e3fa5a7de39f80a2f9a0e}"
def fake_sign(data): return hashlib.sha256(data.encode()).hexdigest()
blockchain = [ { "index": 1, "sender": "system", "recipient": "alice", "amount": 100, "signature": fake_sign("system->alice:100"), }, { "index": 2, "sender": "alice", "recipient": "bob", "amount": 50, "signature": fake_sign("alice->bob:50"), }, { "index": 3, "sender": "admin", "recipient": "you", "amount": 999, "signature": fake_sign("admin->you:999"), "note": f"congrats! here is your flag: {FLAG}" } ]
hints = [ "[Hint 1] Use 'view' to inspect part of the blockchain.", "[Hint 2] The signature is just sha256(sender->recipient:amount).", "[Hint 3] Try forging a valid signature with this knowledge.", "[Hint 4] What if admin sent you 999 coins?" ]
def handle_client(conn, addr): conn.sendall(b"Welcome to SignatureChain CTF over TCP!\nType 'view', 'submit', 'hint', or 'exit'\n> ") while True: try: data = conn.recv(4096) if not data: break cmd = data.decode().strip()
if cmd == "exit": conn.sendall(b"Goodbye!\n") break
elif cmd == "view": partial_chain = json.dumps(blockchain[:2], indent=2) conn.sendall(partial_chain.encode() + b"\n> ")
elif cmd == "hint": for h in hints: conn.sendall(h.encode() + b"\n") conn.sendall(b"> ")
elif cmd == "submit": conn.sendall(b"Paste your JSON chain (end with EOF or Ctrl+D):\n") user_input = b"" while True: part = conn.recv(4096) if not part: break user_input += part if b"\x04" in part: break
try: user_input = user_input.replace(b"\x04", b"") user_chain = json.loads(user_input.decode()) for block in user_chain: expected = fake_sign(f"{block['sender']}->{block['recipient']}:{block['amount']}") if block["signature"] != expected: conn.sendall(f"Invalid signature in block {block['index']}\n> ".encode()) break else: if any("flag" in str(b.get("note", "")) for b in user_chain): conn.sendall(f"Valid chain! Here is your flag: {FLAG}\n".encode()) else: conn.sendall(b"Valid chain, but no flag block found.\n") conn.sendall(b"> ") except Exception as e: conn.sendall(f"JSON parse error: {str(e)}\n> ".encode())
else: conn.sendall(b"Unknown command. Try 'view', 'hint', 'submit', or 'exit'\n> ")
except Exception: break conn.close()
def start_server(host="0.0.0.0", port=5000): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind((host, port)) server.listen(5) print(f"[+] Listening on {host}:{port}") while True: client, addr = server.accept() threading.Thread(target=handle_client, args=(client, addr)).start()
if __name__ == "__main__": start_server()
|