# ๐ฉ CTF Builder
A tool to build, test, and deploy CTFs.

## ๐ฅ Installation
### ๐ฆ Requirements
- [Docker](https://docs.docker.com/get-docker/)
### ๐ PIP
System-wide:
```
pip install ctf-builder
```
[venv](https://docs.python.org/3/library/venv.html):
```
python -m venv .venv
source .venv/bin/activate
pip install ctf-builder
```
## โ๏ธ Usage
All tools are available through the `ctf` executable. Documentation can found in the help menu.
```
ctf -h
```
Note: use the environment variable `CTF=/path/to/ctf` if the command is not being run inside a CTF package.
Have a look at the [sample](./sample) CTF for the structure of a CTF package.
## ๐ Documentation
```
ctf doc
```
Provides the [JSON schema](https://json-schema.org/) for `challenge.json`. This is automatically generated from [schema.py](ctf_builder/schema.py).
## ๐จ Schema
```
ctf schema
```
Validates `challenge.json`. Provides what type is expected and a useful comment for fields.
## ๐จ Build
```
ctf build
```
Builds challenge static files. This is useful for challenges that requires compiling binaries, making assets, etc. Instead of uploading the artifacts part of the repository they can stay separate.
## ๐งช Test
```
ctf test
```
Checks that solve scripts produce the provided flag. This is useful to validate that the challenge logic.
### ๐ฑ Environment Variables
The automatic testing provides the following environment variables to solve scripts.
```
CHALLENGE_ID - the challenge offset inside 'challenges' array.
CHALLENGE_HOST - deploy only: the challenge host name.
CHALLENGE_PORT - deploy only: the challenge port.
FLAG - the value of the flag to test.
FLAG_TYPE - the type of flag to test (static, regex).
```
## ๐ Docker
```
ctf docker list
ctf docker start
ctf docker stop
ctf docker deploy
```
Deploys challenges to [Docker](https://docs.docker.com/get-docker/). This is useful for containerizing challenges.
### ๐ Ports
Exposed/public ports **DO NOT** match the host port. This is to prevent collisions between challenges. Each challenge is allocated `5` public ports. These ports are assigned to challenges alphabetically, so if `a` has `1-5` then `b` will `6-10` etc. Integrations will make sure handle this. Ports can also be determined through [Docker](https://docs.docker.com/get-docker/).
```
docker container ls
```
### ๐ Multi-deployment
Challenges can be deployed on multiple local virtual hosts. This can be used to provide every team their own infrastructure.
#### ๐ฅ๏ธ Setup Hosts
Determine the IP range and interface for the network.
```
ip addr
```
Let's assume this is `eth0` and `192.168.0.0/24`. New IPs can be added for the number of infrastructures.
```
sudo ip addr add 192.168.0.2/24 dev eth0
sudo ip addr add 192.168.0.3/24 dev eth0
...
```
#### ๐ Deploy
The infrastructures can be deployed as follows.
```
ctf start --network team1 --ip 192.168.0.2 --network team2 --ip 192.168.0.3 ...
```
The shorthand version can also be used.
```
ctf start -n team1 -i 192.168.0.2 -n team2 -i 192.168.0.3 ...
```
## โ Kubernetes
```
ctf k8s build
```
Deploys challenges to [Kubernetes](https://kubernetes.io/). This is the most robust way to deploy challenges.
## ๐ฉ CTFd
[CTFd](https://ctfd.io/) is supported out of the box. This allows to automate deploying challenges.
### ๐ง Dev
```
ctf ctfd dev
```
A simple development environment. Automatically spins up challenges without any hassle.
#### ๐ Credentials
The credentials for the default/admin user is the following.
```
Name: admin
Password: admin
```
#### ๐ฅ๏ธ Interactive Console
By default, an interactive console is open when the environment spun up. This is an [argparse](https://docs.python.org/3/library/argparse.html), therefore acts like a CLI argument parser. Help for available commands can be accessed through `-h`.
### ๐ Deploy
```
ctf ctfd init
ctf ctfd deploy teams
ctf ctfd deploy challenges
```
Easiest way to get started is to run the [Docker container](https://docs.docker.com/get-docker/) for [CTFd](https://ctfd.io/).
```
docker run -p 8000:8000 -it ctfd/ctfd
```
The CTF can be initialized from the `ctfd/setup.json`.
```
ctf ctfd init -p ADMIN_PASSWORD
```
An access token is needed to make more changes. It should have the `ctfd_...` format.
```
http://localhost:8000/settings > Access Tokens > Generate
```
Teams can be added through `ctfd/teams.json`. A `ctfd/teams.out.json` will generated with the teams/users credentials.
```
ctf ctfd deploy teams -k ctfd_...
```
Challenges can be deploy as follows.
```
ctf ctfd deploy challenges -k ctfd_...
```
Raw data
{
"_id": null,
"home_page": "https://github.com/alexandre-lavoie/ctf-builder",
"name": "ctf-builder",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": null,
"author": "Alexandre Lavoie",
"author_email": "alexandre.lavoie00@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/87/e8/8b9802daac37b717eb1f5a30362730a2dc04256f67d2a3dbd72b37f10bd0/ctf_builder-0.0.19.tar.gz",
"platform": null,
"description": "# \ud83d\udea9 CTF Builder\n\nA tool to build, test, and deploy CTFs.\n\n\n\n## \ud83d\udce5 Installation\n\n### \ud83d\udce6 Requirements\n\n- [Docker](https://docs.docker.com/get-docker/)\n\n### \ud83d\udc0d PIP\n\nSystem-wide:\n\n```\npip install ctf-builder\n```\n\n[venv](https://docs.python.org/3/library/venv.html):\n\n```\npython -m venv .venv\nsource .venv/bin/activate\npip install ctf-builder\n```\n\n## \u2699\ufe0f Usage\n\nAll tools are available through the `ctf` executable. Documentation can found in the help menu.\n\n```\nctf -h\n```\n\nNote: use the environment variable `CTF=/path/to/ctf` if the command is not being run inside a CTF package.\n\nHave a look at the [sample](./sample) CTF for the structure of a CTF package.\n\n## \ud83d\udcd4 Documentation\n\n```\nctf doc\n```\n\nProvides the [JSON schema](https://json-schema.org/) for `challenge.json`. This is automatically generated from [schema.py](ctf_builder/schema.py).\n\n## \ud83c\udfa8 Schema\n\n```\nctf schema\n```\n\nValidates `challenge.json`. Provides what type is expected and a useful comment for fields.\n\n\n## \ud83d\udd28 Build\n\n```\nctf build\n```\n\nBuilds challenge static files. This is useful for challenges that requires compiling binaries, making assets, etc. Instead of uploading the artifacts part of the repository they can stay separate.\n\n## \ud83e\uddea Test\n\n```\nctf test\n```\n\nChecks that solve scripts produce the provided flag. This is useful to validate that the challenge logic.\n\n### \ud83c\udf31 Environment Variables\n\nThe automatic testing provides the following environment variables to solve scripts.\n\n```\nCHALLENGE_ID - the challenge offset inside 'challenges' array.\nCHALLENGE_HOST - deploy only: the challenge host name.\nCHALLENGE_PORT - deploy only: the challenge port.\n\nFLAG - the value of the flag to test.\nFLAG_TYPE - the type of flag to test (static, regex).\n```\n\n## \ud83d\udc0b Docker\n\n```\nctf docker list\nctf docker start\nctf docker stop\nctf docker deploy\n```\n\nDeploys challenges to [Docker](https://docs.docker.com/get-docker/). This is useful for containerizing challenges.\n\n### \ud83d\udd0c Ports\n\nExposed/public ports **DO NOT** match the host port. This is to prevent collisions between challenges. Each challenge is allocated `5` public ports. These ports are assigned to challenges alphabetically, so if `a` has `1-5` then `b` will `6-10` etc. Integrations will make sure handle this. Ports can also be determined through [Docker](https://docs.docker.com/get-docker/).\n\n```\ndocker container ls\n```\n\n### \ud83c\udf10 Multi-deployment\n\nChallenges can be deployed on multiple local virtual hosts. This can be used to provide every team their own infrastructure. \n\n#### \ud83d\udda5\ufe0f Setup Hosts\n\nDetermine the IP range and interface for the network.\n\n```\nip addr\n```\n\nLet's assume this is `eth0` and `192.168.0.0/24`. New IPs can be added for the number of infrastructures. \n\n```\nsudo ip addr add 192.168.0.2/24 dev eth0\nsudo ip addr add 192.168.0.3/24 dev eth0\n...\n```\n\n#### \ud83d\ude80 Deploy\n\nThe infrastructures can be deployed as follows.\n\n```\nctf start --network team1 --ip 192.168.0.2 --network team2 --ip 192.168.0.3 ...\n```\n\nThe shorthand version can also be used.\n\n```\nctf start -n team1 -i 192.168.0.2 -n team2 -i 192.168.0.3 ...\n```\n\n## \u2693 Kubernetes\n\n```\nctf k8s build\n```\n\nDeploys challenges to [Kubernetes](https://kubernetes.io/). This is the most robust way to deploy challenges.\n\n## \ud83d\udea9 CTFd\n\n[CTFd](https://ctfd.io/) is supported out of the box. This allows to automate deploying challenges.\n\n### \ud83d\udd27 Dev\n\n```\nctf ctfd dev\n```\n\nA simple development environment. Automatically spins up challenges without any hassle.\n\n#### \ud83d\udd11 Credentials\n\nThe credentials for the default/admin user is the following.\n\n```\nName: admin\nPassword: admin\n```\n\n#### \ud83d\udda5\ufe0f Interactive Console\n\nBy default, an interactive console is open when the environment spun up. This is an [argparse](https://docs.python.org/3/library/argparse.html), therefore acts like a CLI argument parser. Help for available commands can be accessed through `-h`. \n\n### \ud83d\ude80 Deploy\n\n```\nctf ctfd init\nctf ctfd deploy teams\nctf ctfd deploy challenges\n```\n\nEasiest way to get started is to run the [Docker container](https://docs.docker.com/get-docker/) for [CTFd](https://ctfd.io/).\n\n```\ndocker run -p 8000:8000 -it ctfd/ctfd\n```\n\nThe CTF can be initialized from the `ctfd/setup.json`.\n\n```\nctf ctfd init -p ADMIN_PASSWORD\n```\n\nAn access token is needed to make more changes. It should have the `ctfd_...` format.\n\n```\nhttp://localhost:8000/settings > Access Tokens > Generate\n```\n\nTeams can be added through `ctfd/teams.json`. A `ctfd/teams.out.json` will generated with the teams/users credentials.\n\n```\nctf ctfd deploy teams -k ctfd_...\n```\n\nChallenges can be deploy as follows.\n\n```\nctf ctfd deploy challenges -k ctfd_...\n```\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Tool for building CTFs",
"version": "0.0.19",
"project_urls": {
"Homepage": "https://github.com/alexandre-lavoie/ctf-builder"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5652d1b63224885c7edbf23aa355076ecb38deba2eef3f796020c5fca77d1602",
"md5": "6b3e67b59fa59380936f91829d468e48",
"sha256": "952c7ded97b37f19ed4de553c5a04462a707372b6a412ab806a425539b0220a2"
},
"downloads": -1,
"filename": "ctf_builder-0.0.19-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6b3e67b59fa59380936f91829d468e48",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 58861,
"upload_time": "2025-02-12T02:36:37",
"upload_time_iso_8601": "2025-02-12T02:36:37.205636Z",
"url": "https://files.pythonhosted.org/packages/56/52/d1b63224885c7edbf23aa355076ecb38deba2eef3f796020c5fca77d1602/ctf_builder-0.0.19-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "87e88b9802daac37b717eb1f5a30362730a2dc04256f67d2a3dbd72b37f10bd0",
"md5": "5db6a9078b3475dfb0801f11e17ef085",
"sha256": "01f0bb8b70f68594017b19959d2227658e65817c8ff137b51ab467c31139778b"
},
"downloads": -1,
"filename": "ctf_builder-0.0.19.tar.gz",
"has_sig": false,
"md5_digest": "5db6a9078b3475dfb0801f11e17ef085",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 38547,
"upload_time": "2025-02-12T02:36:39",
"upload_time_iso_8601": "2025-02-12T02:36:39.235401Z",
"url": "https://files.pythonhosted.org/packages/87/e8/8b9802daac37b717eb1f5a30362730a2dc04256f67d2a3dbd72b37f10bd0/ctf_builder-0.0.19.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-12 02:36:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "alexandre-lavoie",
"github_project": "ctf-builder",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "requests",
"specs": [
[
"==",
"2.32.3"
]
]
},
{
"name": "docker",
"specs": [
[
"==",
"7.1.0"
]
]
},
{
"name": "rich",
"specs": [
[
"==",
"13.7.1"
]
]
},
{
"name": "pydantic",
"specs": [
[
"==",
"2.8.2"
]
]
}
],
"lcname": "ctf-builder"
}