def store_flags(self, team, round):
        from gameserver import cheapMethodFromRoundNumber, cheapMethods, GameServer, GameServerCrypto, SHA512_HEX_LEN, \
            methods

        flagsStored = 0
        method = cheapMethodFromRoundNumber(round)
        flagIndex = cheapMethods.index(method)
        flagId = self.get_flag_id(team, round, 0)
        flag = self.get_flag(team, round, flagIndex)
        msg = GameServer.generatePlaintext() % flag

        # Check if the flag is already stored
        # We could in theory just try to store the flag and check for an IntegrityException from sqlite.
        # However, this approach might not work if teams tinker with their DB layout.
        flagAlreadyStored = True
        try:
            GameServer.retrieveCipher(team.ip, PORT, flagId)
        except FlagMissingException:
            flagAlreadyStored = False

        if not flagAlreadyStored:
            cipher, params, msg = GameServerCrypto.encrypt(msg, method)
            paramHash = msg[-SHA512_HEX_LEN:]
            self.store(team, round, f"paramhash_{flagIndex}", paramHash)
            self.store(team, round, f"msg_{flagIndex}", msg)
            GameServer.storeCipher(team.ip, PORT, flagId, cipher, params)
            flagsStored += 1

        flagIndex = methods.index("schwenk")
        flagId = self.get_flag_id(team, round, 1)
        flag = self.get_flag(team, round, flagIndex)
        msg = GameServer.generatePlaintext() % flag

        flagAlreadyStored = True
        try:
            GameServer.retrieveCipher(team.ip, PORT, flagId)
        except FlagMissingException:
            flagAlreadyStored = False

        if not flagAlreadyStored:
            cipher, params, msg = GameServerCrypto.schwenkNew(
                msg, skipKeyAndIV=False)
            paramHash = GameServerCrypto.parameterHash(params)
            self.store(team, round, f"paramhash_{flagIndex}", paramHash)
            self.store(team, round, "schwenk_msg",
                       msg)  # Random key + IV are added.
            GameServer.storeCipher(team.ip, PORT, flagId, cipher, params)
            flagsStored += 1

        return flagsStored
Beispiel #2
0
                        # print(e)
                        continue
                    # No try here: At this point, we are very sure that we have decrypted correctly so far. Backtracking here would also be rather messy.
                    c_plain = c_elem.nthRoot(
                        k_b_out.toNumber() ^ xorParams[blockIndex]).toString()
                    if not isValidPlaintext(c_plain):
                        continue
                    plain = c_plain + plain
                    print("Found plaintext fragment:", c_plain)
                    bFound = True
                    break

                if not bFound:
                    raise Exception("Decryption failed.")
                remainingCipher = remainingCipher[:-bExpected - bOffset]
                k_next_out = k_b_out
                IV_next_out = IV_b_out

            return plain.decode("utf-8")


if __name__ == "__main__":
    assert len(sys.argv) >= 4, "Needs flag ids in fourth argument"
    target = sys.argv[1]
    flagIds = sys.argv[3].split(",")

    for flagId in flagIds:
        cipher, params = GameServer.retrieveCipher(target, PORT, flagId)
        if params["method"] == "schwenk":
            plain = exploit(cipher, params)
            print(plain)