diff --git a/hosts/bekkalokk/configuration.nix b/hosts/bekkalokk/configuration.nix index 795e0db..1c21b7b 100644 --- a/hosts/bekkalokk/configuration.nix +++ b/hosts/bekkalokk/configuration.nix @@ -5,6 +5,7 @@ ../../base.nix ../../misc/metrics-exporters.nix + ../../modules/wackattack-ctf-stockfish #./services/keycloak.nix diff --git a/modules/wackattack-ctf-stockfish/chess.py b/modules/wackattack-ctf-stockfish/chess.py new file mode 100644 index 0000000..37c870c --- /dev/null +++ b/modules/wackattack-ctf-stockfish/chess.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +from stockfish import * +from inputimeout import inputimeout +import time +from datetime import datetime +import random + +thinking_time = 1000 + +game = Stockfish(path="./stockfish", depth=15, parameters={"Threads": 1, "Minimum Thinking Time": thinking_time, "UCI_Chess960": True}) + +def create_random_position(): + pos = "/pppppppp/8/8/8/8/PPPPPPPP/" + rank8 = ["r","r","b","q","k","b","n","n"] + + while rank8.index("k") < [i for i, n in enumerate(rank8) if n == "r"][0] or rank8.index("k") > [i for i, n in enumerate(rank8) if n == "r"][1] or [i for i, n in enumerate(rank8) if n == "b"][0] % 2 == [i for i, n in enumerate(rank8) if n == "b"][1] % 2: + random.seed(datetime.now().microsecond) + random.shuffle(rank8) + + rank1 = [c.upper() for c in rank8] + pos = "".join(rank8) + pos + "".join(rank1) + " w KQkq - 0 1" + game.set_fen_position(pos) + +def player_won(): + with open("flag.txt") as file: + flag = file.read() + print(flag) + exit() + +def get_fast_player_move(): + try: + time_over = inputimeout(prompt='Your move: ', timeout=5) + except Exception: + time_over = 'Too slow, you lost!' + print(time_over) + exit() + return time_over + +def check_game_status(): + evaluation = game.get_evaluation() + turn = game.get_fen_position().split(" ")[1] + if evaluation["type"] == "mate" and evaluation["value"] == 0 and turn == "w": + print("Wow, you beat me!") + player_won() + elif evaluation["type"] == "mate" and evaluation["value"] == 0 and turn == "b": + print("Hah, I won again") + exit() + if evaluation["type"] == "draw": + print("It's a draw!") + print("Impressive, but I am still undefeated.") + exit() + +if __name__ == "__main__": + create_random_position() + print("Welcome to fischer chess.\nYou get 5 seconds per move. Good luck") + print(game.get_board_visual()) + print("Heres the position for this game, Ill give you a few seconds to look at it before we start.") + time.sleep(3) + while True: + server_move = game.get_best_move_time(thinking_time) + game.make_moves_from_current_position([server_move]) + check_game_status() + print(game.get_board_visual()) + print(f"My move: {server_move}") + player_move = get_fast_player_move() + if type(player_move) != str or len([player_move]) != 1: + print("Illegal input") + exit() + try: + game.make_moves_from_current_position([player_move]) + check_game_status() + except: + print("Couldn't comprehend that") + exit() diff --git a/modules/wackattack-ctf-stockfish/default.nix b/modules/wackattack-ctf-stockfish/default.nix new file mode 100644 index 0000000..821bd1c --- /dev/null +++ b/modules/wackattack-ctf-stockfish/default.nix @@ -0,0 +1,107 @@ +{ config, pkgs, lib, ... }: let + stockfish = with pkgs.python3Packages; buildPythonPackage rec { + pname = "stockfish"; + version = "3.28.0"; + disabled = pythonOlder "3.7"; + + src = pkgs.fetchFromGitHub { + owner = "zhelyabuzhsky"; + repo = pname; + rev = version; + hash = "sha256-XLgVjLV2QXeTYPjP/lwc0LH850LKJsymFlrAMkAn8HU="; + }; + + format = "setuptools"; + nativeBuildInputs = [ + setuptools + ]; + + propagatedBuildInputs = [ + pytest-runner + ]; + + doCheck = false; + }; + + inputimeout = with pkgs.python3Packages; buildPythonPackage rec { + pname = "inputimeout"; + version = "1.0.4"; + src = pkgs.fetchFromGitHub { + owner = "johejo"; + repo = pname; + rev = "v${version}"; + hash = "sha256-Fh1CaqJOK58nURt4imkhCmZKG2eJlP/Hi10SarUJ+Fs="; + }; + + format = "setuptools"; + nativeBuildInputs = [ setuptools ]; + + doCheck = false; + }; + + script = pkgs.writers.writePython3 "chess" { + libraries = [ + stockfish + inputimeout + ]; + + # Fy! + flakeIgnore = [ "F403" "F405" "E231" "E265" "E302" "E305" "E501" "E722" ]; + } (builtins.replaceStrings [''path="./stockfish"''] [''path="${pkgs.stockfish}/bin/stockfish"''] (builtins.readFile ./chess.py)); +in +{ + sops."keys/wackattack_ctf/flag" = { }; + + systemd.sockets."wackattack-ctf-stockfish" = { + description = "Save some azure credit for the rest of us"; + partOf = [ "wackattack-ctf-stockfish.service" ]; + wantedBy = [ "sockets.target" ]; + + socketConfig = { + ListenStream = "0.0.0.0:9999"; + Accept = true; + }; + }; + + systemd.services."wackattack-ctf-stockfish@" = { + description = "Save some azure credit for the rest of us"; + after = [ "network.target" ]; + requires = [ "wackattack-ctf-stockfish.socket" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "simple"; + DynamicUser = true; + WorkingDirectory = "%d"; + Restart = "always"; + StandardInput = "socket"; + LoadCredential = "flag.txt:${config.sops."keys/wackattack_ctf/flag".path}"; + + Exec = script; + + # systemd hardening go barr + ProcSubset = "pid"; + ProtectProc = "invisible"; + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + NoNewPrivileges = true; + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + LockPersonality = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + SystemCallArchitectures = "native"; + }; +} diff --git a/secrets/bekkalokk/bekkalokk.yaml b/secrets/bekkalokk/bekkalokk.yaml index ca9dc31..6b4293b 100644 --- a/secrets/bekkalokk/bekkalokk.yaml +++ b/secrets/bekkalokk/bekkalokk.yaml @@ -13,6 +13,9 @@ mediawiki: database: ENC[AES256_GCM,data:EvVK3Mo6cZiIZS+gTxixU4r9SXN41VqwaWOtortZRNH+WPJ4xcYvzYMJNg==,iv:JtFTRLn3fzKIfgAPRqRgQjct7EdkEHtiyQKPy8/sZ2Q=,tag:nqzseG6BC0X5UNI/3kZZ3A==,type:str] keycloak: database: ENC[AES256_GCM,data:76+AZnNR5EiturTP7BdOCKE90bFFkfGlRtviSP5NHxPbb3RfFPJEMlwtzA==,iv:nS7VTossHdlrHjPeethhX+Ysp9ukrb5JD7kjG28OFpY=,tag:OMpiEv9nQA7v6lWJfNxEEw==,type:str] +keys: + wackattack_ctf: + flag: ENC[AES256_GCM,data:cZCaGb/u/OZgAvXnuJPL3XqmnIa26Rl2IUpWpG/fpt/dJ7+/KssXVa6A5G6ObQhF7deCmTxuoVP8JU+DQzYRr0ftvKhLJ87rgzrE3j+UkA==,iv:3uFkNqXlVj94klU20yPIUd8tIeyUIfp0++2wkdIkiYM=,tag:OZMyEt118u10F5vSUFZE7A==,type:str] sops: kms: [] gcp_kms: [] @@ -46,8 +49,8 @@ sops: akVjeTNTeGorZjJQOVlMeCtPRUVYL3MK+VMvGxrbzGz4Q3sdaDDWjal+OiK+JYKX GHiMXVHQJZu/RrlxMjHKN6V3iaqxZpuvLAEJ2Lzy5EOHPtuiiRyeHQ== -----END AGE ENCRYPTED FILE----- - lastmodified: "2023-09-17T02:02:24Z" - mac: ENC[AES256_GCM,data:Lkvj9UOdE/WZtFReMs6n8ucFuJNPb76ZhPHFpYAEqYEe8d9FdMPMzq05DBAJe9IqpFS0jc9SWxJUPHfGgoMR8nPciZuR/mpJ+4s/cRkPbApwBPcLlvatE/qkbcxzoLlb1vN0gth5G/U7UEfk5Pp9gIz6Yo4sEIS3Za42tId1MpI=,iv:s3VELgU/RJ98/lbQV3vPtOLXtwFzB3KlY7bMKbAzp/g=,tag:D8s0XyGnd8UhbCseB/TyFg==,type:str] + lastmodified: "2023-10-26T19:59:04Z" + mac: ENC[AES256_GCM,data:uH0RfKBjjbYvxjl4XyoXWvwUpi+W7IQZjBdC5UoslotToTw0xnici2fKxPNZ9aFJsukLMPLC+tsT/shUqW373f/NyhsJt0Vb2YtuozFQyQstZQEpnm4WuVoFR/MEjAra/PaM4ATHSGgDuHa7qrpdKTLnrMOai5ZqxLfFbLws3dA=,iv:47hHzrnfZG5NtCN0HjziZdDBJTr451/kvY95GpB3G2M=,tag:3TCs7DSeWB6NujDUlQVGjA==,type:str] pgp: - created_at: "2023-05-21T00:28:40Z" enc: | @@ -70,4 +73,4 @@ sops: -----END PGP MESSAGE----- fp: F7D37890228A907440E1FD4846B9228E814A2AAC unencrypted_suffix: _unencrypted - version: 3.7.3 + version: 3.8.1