diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..883827c --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,17 @@ +# CTF Workflow & Python Learning Project + +This project serves as a centralized workspace for Capture The Flag (CTF) challenges and as a practical environment for learning Python. + +## Project Intent +The primary goal is to use the context of CTF challenges (forensics, crypto, web, etc.) to explore and explain Python concepts, automation, and tooling. + +## Core Mandates for Gemini CLI +1. **No Unsolicited Code:** Do NOT write or modify code unless explicitly issued a **Directive** to do so. +2. **Focus on Explanation:** Prioritize high-signal explanations of Python mechanics, libraries, and documentation. +3. **Summarization:** When directed, summarize documentation (local or web-based) to aid in understanding CTF tools and Python modules. +4. **Educational Context:** Use the existing scripts and tools in this repository (like `psk_crack.py`, `exploit.sh`, or the `tools/` directory) as examples when explaining technical concepts. + +## Python Learning Objectives +- Understanding standard library modules relevant to security (e.g., `os`, `sys`, `base64`, `hashlib`). +- Analyzing existing scripts to understand control flow, data structures, and error handling. +- Exploring how Python interacts with the shell and external tools. diff --git a/pyproject.toml b/pyproject.toml index 338822a..e606eff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ readme = "README.md" requires-python = ">=3.14" dependencies = [ "platformdirs>=4.9.4", + "toml>=0.10.2", ] [build-system] diff --git a/src/ctf/main.py b/src/ctf/main.py index 89953c3..3d3fb3b 100644 --- a/src/ctf/main.py +++ b/src/ctf/main.py @@ -2,7 +2,7 @@ # Parses and calls commands import argparse -from ctf.utils import state +import ctf.utils as util def setArguments(): parser = argparse.ArgumentParser( #type:ignore @@ -17,17 +17,7 @@ def setArguments(): def main(): - state.info = "me" - # Parse arguments - # Current Ctf - # Current Challenge - # Validate args - # Call library functiions - # Set Ctf - args = setArguments() - if args.action == set: - print(f"setting ctf to{args.ctf}") - + print(util.config["Competition"]["competition"]) if __name__ == "__main__": diff --git a/src/ctf/utils.py b/src/ctf/utils.py index 13bac11..7177c9a 100644 --- a/src/ctf/utils.py +++ b/src/ctf/utils.py @@ -9,34 +9,16 @@ from platformdirs import user_config_dir # Parse config file -class StateManager: - _path : Path - _data: dict - def __init__(self): - # Assume data directory exists on install and defined in config - # TODO check datadir valid - object.__setattr__(self, "_path", "user_config_dir/config.json") # set self._path to data_dir safely - object.__setattr__(self, "_data", self._load()) # load objects into self +def load_config(config = f"{user_config_dir()}/ctf-config.toml") -> dict: + p = Path(config) + if p.exists(): + return toml.load(p) + return{} - def _load(self): - if self._path.exists(): - with open(self._path, "r") as f: - return toml.load(f) - return{} - - def __getattr__(self, name): - # use state.challenge to return value for challenge from dictionary - return self._data.get(name) - - def __setattr__(self, name, value): - # use state.challenge = "run" to set challenge and run to dictionary - # writes the whole dict to disk - self._data[name] = value - with open(self._path, "w",) as f: - json.dump(self._data, f, indent=4) - def __repr__(self): - return f"StateManager({self.__dict__})" +def write_config(data: dict, config = f"{user_config_dir()}/ctf"): + with open(config, "w") as f: + toml.dump(data, f) -state = StateManager() +config = load_config("/home/venus/code/ctf/config.toml") diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..8d6600c --- /dev/null +++ b/uv.lock @@ -0,0 +1,36 @@ +version = 1 +revision = 3 +requires-python = ">=3.14" + +[[package]] +name = "ctf" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "platformdirs" }, + { name = "toml" }, +] + +[package.metadata] +requires-dist = [ + { name = "platformdirs", specifier = ">=4.9.4" }, + { name = "toml", specifier = ">=0.10.2" }, +] + +[[package]] +name = "platformdirs" +version = "4.9.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" }, +] + +[[package]] +name = "toml" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, +]