Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "hackingtool notebook",
"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bookworm",
"remoteUser": "root",
"containerUser": "root",
"updateRemoteUserUID": false,
"postCreateCommand": "python -m pip install --disable-pip-version-check -e . -r .devcontainer/requirements.txt",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-toolsai.jupyter"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"jupyter.notebookFileRoot": "${workspaceFolder}"
}
}
},
"forwardPorts": [
8888
],
"portsAttributes": {
"8888": {
"label": "JupyterLab",
"onAutoForward": "silent",
"visibility": "private"
}
},
"hostRequirements": {
"cpus": 2,
"memory": "4gb",
"storage": "16gb"
}
}
2 changes: 2 additions & 0 deletions .devcontainer/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ipykernel>=6.29
jupyterlab>=4.2
124 changes: 124 additions & 0 deletions Interactive-1.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interactive hackingtool workspace\n",
"\n",
"This notebook is ready for **Run All** in the repository's GitHub Codespace. Commands run as `root` inside the isolated container, not on the Codespaces host.\n",
"\n",
"The notebook prepares a non-blocking launcher and a safe argument-based command helper. Run security tools only against systems you own or are explicitly authorized to test."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import importlib.util\n",
"import os\n",
"import shutil\n",
"import subprocess\n",
"from pathlib import Path\n",
"from typing import Sequence\n",
"\n",
"\n",
"def find_repo_root(start: Path | None = None) -> Path:\n",
" \"\"\"Find the src-layout repository without depending on notebook launch directory.\"\"\"\n",
" current = (start or Path.cwd()).resolve()\n",
" for candidate in (current, *current.parents):\n",
" if (candidate / \"pyproject.toml\").is_file() and (candidate / \"src\" / \"hackingtool\").is_dir():\n",
" return candidate\n",
" raise FileNotFoundError(\"Could not find pyproject.toml and src/hackingtool from the current directory\")\n",
"\n",
"\n",
"REPO_ROOT = find_repo_root()\n",
"IS_ROOT = (os.geteuid() == 0) if hasattr(os, \"geteuid\") else False\n",
"IS_ISOLATED_CONTAINER = Path(\"/.dockerenv\").exists() or bool(\n",
" os.environ.get(\"CODESPACES\") or os.environ.get(\"REMOTE_CONTAINERS\")\n",
")\n",
"\n",
"\n",
"def run_command(\n",
" arguments: Sequence[str | os.PathLike[str]],\n",
" *,\n",
" cwd: Path = REPO_ROOT,\n",
" check: bool = True,\n",
") -> subprocess.CompletedProcess[str]:\n",
" \"\"\"Run an explicit argument list without shell interpolation.\"\"\"\n",
" if not arguments:\n",
" raise ValueError(\"At least one command argument is required\")\n",
" command = [os.fspath(argument) for argument in arguments]\n",
" print(\"Running:\", subprocess.list2cmdline(command))\n",
" return subprocess.run(command, cwd=cwd, check=check, text=True)\n",
"\n",
"\n",
"def launch_hackingtool() -> subprocess.CompletedProcess[str]:\n",
" \"\"\"Launch the installed interactive CLI on demand; this is not called by Run All.\"\"\"\n",
" executable = shutil.which(\"hackingtool\")\n",
" if executable is None:\n",
" raise RuntimeError(\"hackingtool CLI is not installed; rebuild the Codespace or run: python -m pip install -e .\")\n",
" return run_command([executable], check=False)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Run-All readiness check.\n",
"required_paths = [\n",
" REPO_ROOT / \"pyproject.toml\",\n",
" REPO_ROOT / \"src\" / \"hackingtool\" / \"cli.py\",\n",
" REPO_ROOT / \"src\" / \"hackingtool\" / \"constants.py\",\n",
"]\n",
"missing_paths = [str(path.relative_to(REPO_ROOT)) for path in required_paths if not path.exists()]\n",
"if missing_paths:\n",
" raise FileNotFoundError(f\"Missing required project paths: {missing_paths}\")\n",
"\n",
"if importlib.util.find_spec(\"hackingtool\") is None:\n",
" raise RuntimeError(\"hackingtool package is not installed in this kernel; rebuild the Codespace or run: python -m pip install -e .\")\n",
"\n",
"if shutil.which(\"hackingtool\") is None:\n",
" raise RuntimeError(\"hackingtool console script is not on PATH\")\n",
"\n",
"write_probe = REPO_ROOT / \".interactive-notebook-write-check\"\n",
"try:\n",
" write_probe.write_text(\"ok\", encoding=\"utf-8\")\n",
"finally:\n",
" write_probe.unlink(missing_ok=True)\n",
"\n",
"print(f\"Repository: {REPO_ROOT}\")\n",
"print(f\"Python package: {importlib.util.find_spec('hackingtool').origin}\")\n",
"print(f\"CLI: {shutil.which('hackingtool')}\")\n",
"print(f\"Root in container: {IS_ROOT}\")\n",
"print(f\"Container detected: {IS_ISOLATED_CONTAINER}\")\n",
"print(\"\\nRun All is complete. Call launch_hackingtool() when you want the interactive CLI.\")\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
47 changes: 47 additions & 0 deletions ONLINE_NOTEBOOK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Run the notebook online

The repository includes a GitHub Codespaces configuration for both
`contents for hackertools.ipynb` and `Interactive-1.ipynb`. The Codespace runs
as `root` inside its isolated container. Root access applies only to the
container; it does not grant access to the Codespaces host.

## Start in GitHub Codespaces

1. Push this branch to a GitHub repository you control.
2. Open the repository on GitHub and select **Code → Codespaces → Create
codespace on this branch**.
3. Wait for the container setup to finish.
4. Open either notebook:
- `contents for hackertools.ipynb` for environment detection and explicit
system-package installation.
- `Interactive-1.ipynb` for the project-aware command helper and interactive
CLI launcher.
5. Select the **Python 3** kernel and choose **Run All**.

The environment check should print:

```text
system linux
is_root True
...
Ready: root permissions are available inside the isolated container.
```

## Optional JupyterLab server

The browser-based Codespaces editor can run the notebook directly. If a
standalone JupyterLab UI is preferred, run this from the Codespaces terminal:

```bash
jupyter lab --ip=0.0.0.0 --port=8888 --no-browser --allow-root
```

Codespaces forwards port 8888 privately by default. Keep it private and retain
Jupyter's generated access token.

## Permission boundary

The container intentionally does not use Docker `--privileged`, host filesystem
mounts, or a Docker socket mount. Those are not required for this notebook and
would weaken isolation. Use security tooling only on systems you own or have
explicit authorization to test.
Loading