def check_injects(self): for title, inject in self.injects.items(): if db.get_current_time() > db.format_time(inject["time"]) and "ran" not in inject: print("[INFO] Checking data for inject", title) config = db.read_running_config() self.injects[title] = inject if inject["type"] == "service" and "services" in inject: if db.get_current_time() > db.format_time(inject["enact_time"]): print("[INFO] Adding service into running-config for", title) config["injects"][title]["ran"] = 1 for system, checks in inject["services"].items(): if system in config["systems"]: for index, check in enumerate(checks["checks"]): if check in config["systems"][system]["checks"] and "modify" in check: print("[INFO] Modifying check", check, "for", system) del config["systems"][system]["checks"][check] elif check in config["systems"][system]["checks"]: print("[ERROR] Duplicate check", check, "for", system, "without modify option") del checks["checks"][index] new_checks = config["systems"][system]["checks"] + checks["checks"] for propertyName, propertyValue in checks.items(): if propertyName != "checks": config["systems"][system][propertyName] = propertyValue config["systems"][system]["checks"] = new_checks else: config["systems"][system] = checks del config["injects"][title]["services"] else: config["injects"][title]["ran"] = 1 db.write_running_config(config)
def start(): config = db.read_running_config() if not config or "reset" in config["settings"] and config["settings"]["reset"] == 1: db.reset_engine() config = db.read_running_config() if "css_mode" in config["settings"] and config["settings"]["css_mode"]: print("[INFO] Scoring checks not running, engine is in CCS mode.") else: em = EngineModel() while True: em.load() if "running" in em.settings: running = em.settings['running'] else: running = 1 if "interval" in em.settings: interval = em.settings['interval'] else: interval = 150 if "jitter" in em.settings: jitter = em.settings['jitter'] else: jitter = 30 em.wait = 1 if running == 1: check_round = db.get_check_round() db.update_check_round(check_round + 1) em.check(check_round) em.wait = random.randint(-jitter, jitter) + interval elif running == 0: print("[INFO] Scoring is paused.") elif running == -1: print("[INFO] Scoring has been stopped.") return else: print("[ERROR] Unsure what 'running' is set to.") print("[WAIT]", str(em.wait), "seconds") time.sleep(em.wait)
def css_update(): em.load() try: team = request.form["team"].rstrip().strip() image = request.form["image"] score = int(request.form["score"]) challenge = request.form["challenge"] vulns = request.form["vulns"] # id must be unqiue for each VM to tell dupes (todo) id = request.form["id"] except: print( "[ERROR] Score update from image did not have all required fields, or had malformed fields." ) return ("FAIL") if not db.validate_alphanum(team) or not db.validate_alphanum(image): print("[ERROR] Team or image contained illegal characters. team", image) return ("FAIL") if "teams" in em.remote: if team not in em.remote["teams"]: print("[ERROR] Score update had invalid team name.") return ("FAIL") if "images" in em.remote: if image not in em.remote["images"]: print("[ERROR] Score update had invalid image name.") return ("FAIL") config = db.read_running_config() if "remote" in config and "password" in config["remote"]: config_password = config["remote"]["password"] if em.verify_challenge(challenge, password=config_password): vulns, success = em.decrypt_vulns(vulns, password=config_password) else: print( "[ERROR] Score update from image did not pass (password-protected) challenge verification." ) return ("FAIL") else: if em.verify_challenge(challenge): vulns, success = em.decrypt_vulns(vulns) else: print( "[ERROR] Score update from image did not pass (passwordless) challenge verification." ) return ("FAIL") if success: vulns = db.printAsHex("|".join(vulns).encode()) db.insert_css_score(team, image, score, vulns) return ("OK") else: print("[ERROR] Vuln data decryption failed.") return ("FAIL") return ("FAIL")
def css_update(): em.load() config = db.read_running_config() try: password = config["remote"]["password"] except: password = remote_backup_key try: update = request.form["update"].rstrip().strip() update_data, result = em.parse_update(update, password) if not result: print("[ERROR] Failure parsing update field.") return ("FAIL") team = update_data["team"] image = update_data["image"] score = update_data["score"] challenge = update_data["challenge"] vulns = update_data["vulns"] time = update_data["time"] except Exception as e: print("[ERROR] Score update from image did not have all required fields, or had malformed fields:", e) return("FAIL") if not db.validate_alphanum(team) or not db.validate_alphanum(image): print("[ERROR] Team or image contained illegal characters.") return("FAIL") if "teams" in em.remote: if team not in em.remote["teams"]: print("[ERROR] Score update had invalid team name:", team) return("FAIL") if "images" in em.remote: if image not in em.remote["images"]: print("[ERROR] Score update had invalid image name:", image) return("FAIL") if em.verify_challenge(challenge, password): vulns, success = em.decrypt_vulns(vulns, password, score) else: print("[ERROR] Score update from image did not pass (password-protected) challenge verification.") return("FAIL") if success: vulns = db.printAsHex("|-|".join(vulns).encode()) db.insert_css_score(team, image, score, vulns) print("Found IP", request.remote_addr, "for team", team) ips[team] = request.remote_addr return("OK") else: print("[ERROR] Vuln data decryption failed.") return("FAIL") return("FAIL")
def css_new_team(): em.load() request_ip = request.remote_addr if request_ip != permitted_new_css_ip: print("[ERROR] New team ID request wasn't from the authorized IP.") return("FAIL") try: id = request.form["teamid"].rstrip().strip() alias = request.form["alias"].rstrip() if "email" in request.form: email = request.form["email"] else: email = None except: print("[ERROR] New team ID request did not have all required fields (teamid, alias).") return("FAIL") if not db.validate_alphanum(alias) or not db.validate_alphanum(id): print("[ERROR] New team or id contained illegal characters.") return("FAIL") config = db.read_running_config() try: if alias in config["remote"]["team_aliases"]: print("[ERROR] Duplicate team alias (team)") return("FAIL") except: pass try: if id in config["remote"]["teams"]: print("[ERROR] Duplicate team id (id)") return("FAIL") except: pass try: if email in config["remote"]["team_emails"]: print("[ERROR] Duplicate team email (email)") return("FAIL") except: pass if not "remote" in config: config["remote"] = {} if email and not db.validate_alphanum(email): print("[ERROR] Email was not null and contained illegal characters.") return("FAIL") else: if "team_emails" in config["remote"]: config["remote"]["team_emails"].append(email) else: config["remote"]["team_emails"] = [email] if "teams" in config["remote"]: lenTeams = 0 else: lenTeams = len(config["remote"]["teams"]) if len(config["remote"]["team_emails"]) <= lenTeams: for x in range(lenTeams - len(config["remote"]["team_emails"]) + 1): config["remote"]["team_emails"].insert(0, "N/A") if "teams" in config["remote"]: config["remote"]["teams"].append(id) else: config["remote"]["teams"] = [id] if "team_aliases" in config["remote"]: config["remote"]["team_aliases"].append(alias) else: config["remote"]["team_aliases"] = [team] print(config) db.write_running_config(config) return("OK")