{"id":18329806,"url":"https://github.com/ctfd/ctfcli","last_synced_at":"2025-04-15T03:52:12.757Z","repository":{"id":38183067,"uuid":"252505424","full_name":"CTFd/ctfcli","owner":"CTFd","description":"ctfcli is a tool to manage Capture The Flag events and challenges","archived":false,"fork":false,"pushed_at":"2024-12-30T20:05:16.000Z","size":237,"stargazers_count":186,"open_issues_count":48,"forks_count":80,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-15T03:52:07.733Z","etag":null,"topics":["challenge-specifications","ctf","ctf-challenges","ctf-tools","ctfd"],"latest_commit_sha":null,"homepage":"https://ctfd.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CTFd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-02T16:14:57.000Z","updated_at":"2025-04-09T15:28:00.000Z","dependencies_parsed_at":"2023-12-03T20:26:53.151Z","dependency_job_id":"d6492f1e-dbc6-43a0-9ce7-b301a3a508cf","html_url":"https://github.com/CTFd/ctfcli","commit_stats":{"total_commits":104,"total_committers":14,"mean_commits":7.428571428571429,"dds":"0.28846153846153844","last_synced_commit":"763c2de1f32b6f90458f2f3e9b2ce2c3eb94ec3e"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CTFd%2Fctfcli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CTFd%2Fctfcli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CTFd%2Fctfcli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CTFd%2Fctfcli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CTFd","download_url":"https://codeload.github.com/CTFd/ctfcli/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249003954,"owners_count":21196794,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["challenge-specifications","ctf","ctf-challenges","ctf-tools","ctfd"],"created_at":"2024-11-05T19:18:46.509Z","updated_at":"2025-04-15T03:52:12.734Z","avatar_url":"https://github.com/CTFd.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ctfcli\n\n*ctfcli is a tool to manage Capture The Flag events and challenges.*\n\n`ctfcli` provides challenge specifications and templates to make it easier to generate challenges of different categories. It also provides an integration with the [CTFd](https://github.com/CTFd/CTFd/) REST API to allow for command line uploading of challenges and integration with CI/CD build systems.\n\n`ctfcli` features tab completion, a REPL interface (thanks to [Python-Fire](https://github.com/google/python-fire)) and plugin support for custom commands.\n\n*WIP: ctfcli is an alpha project and changes will happen. Be sure to pin versions and read the CHANGELOG when updating.*\n\n# Installation and Usage\n\nctfcli can be installed with [`pipx`](https://github.com/pypa/pipx) as an executable command:\n\n`pipx install ctfcli`\n\nAlternatively, you can always install it with `pip` as a python module:\n\n`pip install ctfcli`\n\nTo install the development version of ctfcli directly from the repository you can use:\n\n`pip install git+https://github.com/CTFd/ctfcli.git`\n\n## 1. Create an Event\n\nCtfcli turns the current folder into a CTF event git repo. \nIt asks for the base url of the CTFd instance you're working with and an access token.\n\n```\n❯ ctf init\nPlease enter CTFd instance URL: https://demo.ctfd.io\nPlease enter CTFd Admin Access Token: d41d8cd98f00b204e9800998ecf8427e\nDo you want to continue with https://demo.ctfd.io and d41d8cd98f00b204e9800998ecf8427e [Y/n]: y\nInitialized empty Git repository in /Users/user/Downloads/event/.git/\n```\n\nThis will create the `.ctf` folder with the `config` file that will specify the URL, access token, and keep a record of\nall the challenges dedicated for this event.\n\n## 2. Add challenges\n\nEvents are made up of challenges.\nChallenges can be made from a subdirectory or pulled from another repository.\nGIT-enabled challenges are pulled into the event repo, and a reference is kept in the `.ctf/config` file.\n\n```\n❯ ctf challenge add [REPO | FOLDER]\n```\n\n##### Local folder:\n```\n❯ ctf challenge add crypto/stuff\n```\n\n##### GIT repository:\n```\n❯ ctf challenge add https://github.com/challenge.git\nCloning into 'challenge'...\n[...]\n```\n\n##### GIT repository to a specific subfolder:\n```\n❯ ctf challenge add https://github.com/challenge.git crypto\nCloning into 'crypto/challenge'...\n[...]\n```\n\n## 3. Install challenges\n\nInstalling a challenge will create the challenge in your CTFd instance using the API.\n\n```\n❯ ctf challenge install [challenge]\n```\n\n```\n❯ ctf challenge install buffer_overflow\nFound buffer_overflow/challenge.yml\nLoaded buffer_overflow\nInstalling buffer_overflow\nSuccess!\n```\n\n## 4. Sync challenges\n\nSyncing a challenge will update the challenge in your CTFd instance using the API. \nAny changes made in the `challenge.yml` file will be reflected in your instance.\n\n```\n❯ ctf challenge sync [challenge]\n```\n\n```\n❯ ctf challenge sync buffer_overflow\nFound buffer_overflow/challenge.yml\nLoaded buffer_overflow\nSyncing buffer_overflow\nSuccess!\n```\n\n## 5. Deploy services\n\nDeploying a challenge will automatically create the challenge service (by default in your CTFd instance).\nYou can also use a different deployment handler to deploy the service via SSH to your own server, \nor a separate docker registry.\n\nThe challenge will also be automatically installed or synced.\nObtained connection info will be added to your `challenge.yml` file.\n```\n❯ ctf challenge deploy [challenge]\n```\n\n```\n❯ ctf challenge deploy web-1\nDeploying challenge service 'web-1' (web-1/challenge.yml) with CloudDeploymentHandler ...\nChallenge service deployed at: https://web-1-example-instance.chals.io\nUpdating challenge 'web-1'\nSuccess!\n```\n\n## 6. Verify challenges\n\nVerifying a challenge will check if the local version of the challenge is the same as one installed in your CTFd instance.\n\n```\n❯ ctf challenge verify [challenge]\n```\n\n```\n❯ ctf challenge verify buffer_overflow\nVerifying challenges  [------------------------------------]    0%\nVerifying challenges  [####################################]  100%\nSuccess! All challenges verified!\nChallenges in sync:\n - buffer_overflow\n```\n\n## 7. Mirror changes\n\nMirroring a challenge is the reverse operation to syncing.\nIt will update the local version of the challenge with details of the one installed in your CTFd instance.\nIt will also issue a warning if you have any remote challenges that are not tracked locally.\n\n```\n❯ ctf challenge mirror [challenge]\n```\n\n```\n❯ ctf challenge verify buffer_overflow\nMirorring challenges  [------------------------------------]    0%\nMirorring challenges  [####################################]  100%\nSuccess! All challenges mirrored!\n```\n\n## Operations on all challenges\n\nYou can perform operations on all challenges defined in your config by simply skipping the challenge parameter.\n\n- `ctf challenge install`\n- `ctf challenge sync`\n- `ctf challenge deploy`\n- `ctf challenge verify`\n- `ctf challenge mirror`\n\n# Challenge Templates\n\n`ctfcli` contains pre-made challenge templates to make it faster to create CTF challenges with safe defaults.\n\n```\nctf challenge new\n                ├── binary\n                ├── crypto\n                ├── programming\n                └── web\n```\n\n```\n❯ ctf challenge new binary\n/Users/user/.virtualenvs/ctfcli/lib/python3.7/site-packages/ctfcli-0.0.1-py3.7.egg/ctfcli/templates/binary/default\nname [Hello]: buffer_overflow\n\n❯ ls -1 buffer_overflow\nMakefile\nREADME.md\nWRITEUP.md\nchallenge.yml\ndist/\nsrc/\n```\n\n**Contributions welcome on improving the challenge templates to make CTF challenges better for everyone!**\n\n# Challenge Specification\n\n`ctfcli` provides a [challenge specification](ctfcli/spec/challenge-example.yml) (`challenge.yml`) that outlines the major details of a challenge.\n\nEvery challenge generated by or processed by `ctfcli` should have a `challenge.yml` file.\n\nThe specification format has already been tested and used with CTFd in production events but comments, suggestions, and PRs are welcome on the format of `challenge.yml`.\n\n# Plugins\n\n`ctfcli` plugins are essentially additions to the command line interface via dynamic class modifications. See the [plugin documentation page](docs/plugins.md) for a simple example.\n\n*`ctfcli` is an alpha project! The plugin interface is likely to change!*\n\n# Sub-Repos as alternative to Sub-Trees\n\n`ctfcli` manages git-based challenges by using the built-in git `subtree` mechanism. While it works most of the time, it's been proven to have disadvantages and tends to create problems and merge conflicts.  \n\nAs an alternative, we're currently experimenting with the git [`git subrepo`](https://github.com/ingydotnet/git-subrepo) extension. \nThis functionality can be enabled by adding a `use_subrepo = True` property to the `[config]` section inside a ctfcli project config.\n\nSubrepo has to be installed separately, and is not backwards compatible with the default `subtree`. \nOnce challenges have been added by using either method, they will not work properly if you change it, and you will have to add the challenges again.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fctfd%2Fctfcli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fctfd%2Fctfcli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fctfd%2Fctfcli/lists"}