# Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os, secrets, string, time from flag import flag def main(): # It's a tiny server... blob = bytearray(2**16) files = {} used = 0 # Use deduplication to save space. def store(data): nonlocal used MINIMUM_BLOCK = 16 MAXIMUM_BLOCK = 1024 part_list = [] while data: prefix = data[:MINIMUM_BLOCK] ind = -1 bestlen, bestind = 0, -1 while True: ind = blob.find(prefix, ind+1) if ind == -1: break length = len(os.path.commonprefix([data, bytes(blob[ind:ind+MAXIMUM_BLOCK])])) if length > bestlen: bestlen, bestind = length, ind if bestind != -1: part, data = data[:bestlen], data[bestlen:] part_list.append((bestind, bestlen)) else: part, data = data[:MINIMUM_BLOCK], data[MINIMUM_BLOCK:] blob[used:used+len(part)] = part part_list.append((used, len(part))) used += len(part) assert used <= len(blob) fid = "".join(secrets.choice(string.ascii_letters+string.digits) for i in range(16)) files[fid] = part_list return fid def load(fid): data = [] for ind, length in files[fid]: data.append(blob[ind:ind+length]) return b"".join(data) print("Welcome to our file storage solution.") # Store the flag as one of the files. store(bytes(flag, "utf-8")) while True: print() print("Menu:") print("- load") print("- store") print("- status") print("- exit") choice = input().strip().lower() if choice == "load": print("Send me the file id...") fid = input().strip() data = load(fid) print(data.decode()) elif choice == "store": print("Send me a line of data...") data = input().strip() fid = store(bytes(data, "utf-8")) print("Stored! Here's your file id:") print(fid) elif choice == "status": print("User: ctfplayer") print("Time: %s" % time.asctime()) kb = used / 1024.0 kb_all = len(blob) / 1024.0 print("Quota: %0.3fkB/%0.3fkB" % (kb, kb_all)) print("Files: %d" % len(files)) elif choice == "exit": break else: print("Nope.") break try: main() except Exception: print("Nope.") time.sleep(1)