Giter Club home page Giter Club logo

ctfcli's Introduction

CTFd MySQL CI Linting MajorLeagueCyber Discourse Documentation Status

What is CTFd?

CTFd is a Capture The Flag framework focusing on ease of use and customizability. It comes with everything you need to run a CTF and it's easy to customize with plugins and themes.

CTFd is a CTF in a can.

Features

  • Create your own challenges, categories, hints, and flags from the Admin Interface
    • Dynamic Scoring Challenges
    • Unlockable challenge support
    • Challenge plugin architecture to create your own custom challenges
    • Static & Regex based flags
      • Custom flag plugins
    • Unlockable hints
    • File uploads to the server or an Amazon S3-compatible backend
    • Limit challenge attempts & hide challenges
    • Automatic bruteforce protection
  • Individual and Team based competitions
    • Have users play on their own or form teams to play together
  • Scoreboard with automatic tie resolution
    • Hide Scores from the public
    • Freeze Scores at a specific time
  • Scoregraphs comparing the top 10 teams and team progress graphs
  • Markdown content management system
  • SMTP + Mailgun email support
    • Email confirmation support
    • Forgot password support
  • Automatic competition starting and ending
  • Team management, hiding, and banning
  • Customize everything using the plugin and theme interfaces
  • Importing and Exporting of CTF data for archival
  • And a lot more...

Install

  1. Install dependencies: pip install -r requirements.txt
    1. You can also use the prepare.sh script to install system dependencies using apt.
  2. Modify CTFd/config.ini to your liking.
  3. Use python serve.py or flask run in a terminal to drop into debug mode.

You can use the auto-generated Docker images with the following command:

docker run -p 8000:8000 -it ctfd/ctfd

Or you can use Docker Compose with the following command from the source repository:

docker compose up

Check out the CTFd docs for deployment options and the Getting Started guide

Live Demo

https://demo.ctfd.io/

Support

To get basic support, you can join the MajorLeagueCyber Community: MajorLeagueCyber Discourse

If you prefer commercial support or have a special project, feel free to contact us.

Managed Hosting

Looking to use CTFd but don't want to deal with managing infrastructure? Check out the CTFd website for managed CTFd deployments.

MajorLeagueCyber

CTFd is heavily integrated with MajorLeagueCyber. MajorLeagueCyber (MLC) is a CTF stats tracker that provides event scheduling, team tracking, and single sign on for events.

By registering your CTF event with MajorLeagueCyber users can automatically login, track their individual and team scores, submit writeups, and get notifications of important events.

To integrate with MajorLeagueCyber, simply register an account, create an event, and install the client ID and client secret in the relevant portion in CTFd/config.py or in the admin panel:

OAUTH_CLIENT_ID = None
OAUTH_CLIENT_SECRET = None

Credits

ctfcli's People

Contributors

coldheat avatar ctxhamza avatar dependabot[bot] avatar ifelawal avatar milymilo avatar pl4nty avatar ppaslan avatar reteps avatar riccardotornesello avatar roerohan avatar rustybower avatar sebastianpc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ctfcli's Issues

Install and Sync all commands

Add a command to install and Sync commands that allow you install all challenges in a specified directory. Allowing it to loop through the directories recursively would be nice too. That way I can store my challenges in different directories based on category.

IE: I would run ctf challenge install Challenges

where the challenges folder looks like this.
Challenges
Crypto
rsa1
challenge.yml
rsa2
challenge.yml
Binary
intoverflow
challenge.yml
bufferoverflow
challenge.yml
...

Synchronisation should not change visibility status

When updating challenges with the cli tool, the challenges are set to state "visible", regardless of their previous state.

Expected behavior:
Challenge visibility state stays hidden when being hidden beforehand.

Actual behavior:
Challenge is set to "visible", even if being hidden before.

Add templates as a new type of subcommand

We need a specific templates folder so that we can create new custom templates without having to add them to the main repo. Should be very similar to the plugins subcommand.

Something like:

ctf templates dir
ctf templates install <url>
ctf templates list
ctf templates uninstall <name>

ctf challenge verify

We should have a way to have ctfcli verify that a given installed challenge matches the local state. This could help in situations where perhaps an admin deletes files or changes a description.

Expand linting

  • Lint that Dockerfiles EXPOSE a port
  • Lint that if your challenge spec doesn't provide an image that you don't provide a Dockerfile
  • Lint that all files being searched for are provided

image field plans?

What are the current plans for the image field in the chal spec? One thing to keep in mind for deployment is that some chals might want multiple containers e.g. a sql db + webserver, so perhaps specifying a single image is not enough. For the CTF we recently ran, we had a docker-compose file for each challenge.

Visible and Hidden states reversed

When creating a new challenge (blank) the state of the challenge is by default set to "Hidden".

Upon adding and installing the challenge and opening CTFd the challenge will be "Visible" and not "Hidden" as per the challenge.yml.
When changing the state in the challenge.yml to "Visible" (and syncing the change) the challenge will be set to "Hidden" in CTFd.

Unable to install challenges with the same name (but different category)

The function install() in ctfcli/cli/challenge.py implements a check to see if there is already a challenge with the same name. This check does this as follows:

if c["name"] == challenge["name"]:
    click.secho(
        "Already found existing challenge with same name. Perhaps you meant sync instead of install?",
        fg="red",
    )

As a result, ctfcli refuses to install challenges with the same name regardless of the category.

I have been using a modified variant of ctfcli that determines if a challenge is already present based on the challenge name and challenge category.

if c["name"] == challenge["name"] and c["category"] == challenge["category"]:
    click.secho(
        "Already found existing challenge with same name. Perhaps you meant sync instead of install?",
        fg="red",
    )

The same check is also present in the function sync_challenge() in ctfcli/utils/challenge.py and should be changed in similar fashion to sync the correct challenge.

I guess this is the intended/expected behaviour?

Support existing git repositories

We are a monthly event and we already host our challenges in a git repo even when not using CTFd: https://github.com/montrehack/challenges

It would be nice if ctfcli would have detected that it was already in a git tree and wouldn't do anything about it. For now, I'm going to create a distinct repo for our event but I wanted to let you know of that use case.

This tool is a very nice addition to the CTFd ecosystem by the way! Thanks!

json decode error on "ctf challenge install"

ctfcli is installed with pip and initialized. Then a new challenge is created with ctf challenge new web and given the name "Hello". On ctf challenge install Hello the following result appears:

Found Hello/challenge.yml
Loaded Hello
Traceback (most recent call last):
  File "/usr/local/bin/ctf", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/site-packages/ctfcli/__main__.py", line 74, in main
    fire.Fire(CTFCLI)
  File "/usr/local/lib/python3.8/site-packages/fire/core.py", line 138, in Fire
    component_trace = _Fire(component, args, parsed_flag_args, context, name)
  File "/usr/local/lib/python3.8/site-packages/fire/core.py", line 466, in _Fire
    component, remaining_args = _CallAndUpdateTrace(
  File "/usr/local/lib/python3.8/site-packages/fire/core.py", line 675, in _CallAndUpdateTrace
    component = fn(*varargs, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/ctfcli/cli/challenges.py", line 94, in install
    installed_challenges = load_installed_challenges()
  File "/usr/local/lib/python3.8/site-packages/ctfcli/utils/challenge.py", line 28, in load_installed_challenges
    return s.get("/api/v1/challenges?view=admin", json=True).json()["data"]
  File "/usr/local/lib/python3.8/site-packages/requests/models.py", line 897, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Add ability to not upload tags/files/etc

Syncing or installing is an all or nothing procedure. Instead we shouold have switches/options to be able to choose what data to not include during installation.

Issue in challenge type dynamic.

The spec does not have the following fields for challenges having type dynamic:

  • Initial Value
  • Decay Limit
  • Final Value

Hence, you can only set challenges of standard type.

Install challenge KeyError: 'data'

Getting the following error when trying to use ctfcli. This only began to happen once I upgraded to ctfd 3.4.1 and does not occur on ctfd 3.4.0.

Traceback (most recent call last):
  File "../../utils/ctf", line 11, in <module>
    load_entry_point('ctfcli==0.0.9', 'console_scripts', 'ctf')()
  File "/home/user/.local/lib/python3.8/site-packages/ctfcli/__main__.py", line 78, in main
    fire.Fire(CTFCLI)
  File "/home/user/.local/lib/python3.8/site-packages/fire/core.py", line 138, in Fire
    component_trace = _Fire(component, args, parsed_flag_args, context, name)
  File "/home/user/.local/lib/python3.8/site-packages/fire/core.py", line 466, in _Fire
    component, remaining_args = _CallAndUpdateTrace(
  File "/home/user/.local/lib/python3.8/site-packages/fire/core.py", line 675, in _CallAndUpdateTrace
    component = fn(*varargs, **kwargs)
  File "/home/user/.local/lib/python3.8/site-packages/ctfcli/cli/challenges.py", line 143, in install
    installed_challenges = load_installed_challenges()
  File "/home/user/.local/lib/python3.8/site-packages/ctfcli/utils/challenge.py", line 28, in load_installed_challenges
    return s.get("/api/v1/challenges?view=admin", json=True).json()["data"]
KeyError: 'data'

Add a topics field

Add a field where we can specify what topics a challenge is about. This should probably also be aligned with CTFd as well. Perhaps we have a set of internal topics.

Writeups should have their own folder

I think writeups should have their own folder instead of being just WRITEUP.md in the root folder. This would make it more organized and also let writeup content not pollute other content.

Add ability to use CTFd config variables in challenges

We should in theory be able to use CTFd configuration variables in things like challenge descriptions and such. I think this is would be a really useful idea.

Perhaps something like {{ ctf_name }} or {{ ctf_description }}inside of challenge descriptions.

I think we can also have a variables section within the .ctf/config section as well.

Files not being parsed relative to challenge.yml file

I am still experiencing this error when running the version when I installed this using pip.

This is the pip and pip3 info.

$ pip3 show ctfcli
Name: ctfcli
Version: 0.0.4
Summary: Tool for creating and running Capture The Flag competitions
Home-page: UNKNOWN
Author: Kevin Chung
Author-email: [email protected]
License: Apache 2.0
Location: /home/user/.local/lib/python3.6/site-packages
Requires: requests, colorama, appdirs, fire, cookiecutter, Pygments, click, pyyaml
Required-by: 

And the error I get is as follows.

$ ctf challenge sync Over_The_Top
Found Over_The_Top/challenge.yml
Loaded Over the Top
Syncing Over the Top
Traceback (most recent call last):
  File "/home/user/.local/bin/ctf", line 8, in <module>
    sys.exit(main())
  File "/home/user/.local/lib/python3.6/site-packages/ctfcli/__main__.py", line 74, in main
    fire.Fire(CTFCLI)
  File "/home/user/.local/lib/python3.6/site-packages/fire/core.py", line 138, in Fire
    component_trace = _Fire(component, args, parsed_flag_args, context, name)
  File "/home/user/.local/lib/python3.6/site-packages/fire/core.py", line 471, in _Fire
    target=component.__name__)
  File "/home/user/.local/lib/python3.6/site-packages/fire/core.py", line 675, in _CallAndUpdateTrace
    component = fn(*varargs, **kwargs)
  File "/home/user/.local/lib/python3.6/site-packages/ctfcli/cli/challenges.py", line 134, in sync
    sync_challenge(challenge=challenge)
  File "/home/user/.local/lib/python3.6/site-packages/ctfcli/utils/challenge.py", line 95, in sync_challenge
    files.append(("file", open(f, "rb")))
FileNotFoundError: [Errno 2] No such file or directory: 'src/main.c'

If I make a directory and file in the the folder I am running the file from, the command works just fine. But if I do not have it in that directory, it fails. It should be running it from path that is relative to the challenge.yml location.

Currently I am bypassing this (and recursivly searching folders) using this command.

find . -type d -exec echo '(cd {} && ctf challenge sync)' ';' | sh

Add a finalize command

The challenge.yml file should only be created once a challenge is done. So there should probably be a ctf challenge finalize kind of command. It can parse the relevant sections that it needs and then as the author for other data.

Feedback suggested that manually generating the yml file was unnecessary work.

`ctf challenge deploy` with registry succeeds but faults with TypeError

ctf challenge deploy chal registry://myregistry fails with TypeError: cannot unpack non-iterable NoneType object, because it tries to unpack data that isn't returned when deploying to a registry:

status, domain, port = DEPLOY_HANDLERS[url.scheme](

def registry(challenge, host):
# Build image
image_name = build_image(challenge=challenge)
print(f"Built {image_name}")
url = urlparse(host)
tag = f"{url.netloc}{url.path}"
subprocess.call(["docker", "tag", image_name, tag])
subprocess.call(["docker", "push", tag])

Show debug information better

We should have a command or switches that will show what we are reading/loading.

Some useful information:

  • Target URL
  • API Key
  • Location of the .ctf/config file
  • Contents of the .ctf/config file

Remote image pull before deploy

We should have some way to be able to store and use saved copies of images so that we aren't always rebuilding images on deploy.

Essentially if we build once, we should be able to store that image and then reuse it.

Add a command to store in different folder

Add a command to allow you to create the git folder in a different place than the default /home/user/.git

The reasoning is that some of the .git folders have other files in it that may conflict with the install such as secret files. Additionally, I may want to run multiple instances on the same computer.

A decent solution may be creating individual folders in the .git folder for each individual project. IE /home/user/.git/ctf1 /home/user/.git/ctf2 etc.

ctf challenge test

We should have a ctf challenge test command. Some ideas:

  • Test that Dockerfiles build
  • Test the created image
  • Test chal is solveable

Adding challenges through external repo fails

Hi,

I may be wrong but it's not possible to add a git repo with ctf challenge add {repo_url} at first. This command relies on git subtree which is a shell script. this script calls ensure_clean to check the HEAD reference but our repo is empty at this point.

I would add a git commit --allow-empty -m "Project created" after the git init in main.py.

Generate challenge README from challenge.yml

We currently generate the README with nothing in it. We can actually generate it from the challenge.yml. We will need some way to promote the filling in of challenge.yml before pushing though as the current flow it's a little easy to miss a step. Maybe with some kind of git hooks.

Renaming challenge breaks subtree

If you rename a challenge directory or move it it will break the git subtree integration. We may need to look into a mv or rename functionality.

Pages Support

I think we may want to consider adding the ability to manage pages from ctfcli. It would help because our editor interface isn't great and this might be a good way to make that easier.

ctf challenge update not working properly

ctf challenge update isn't working properly in some situations for unknown reasons. We need to come up with a better strategy on gathering and updating challenges gathered from multiple locations.

Ability to set CTFd config

We need a way to share CTFd configuration between events. It's too easy to forget that a configuration setting needs to be set.

Explore subtree and storing branch information

git subtree was something being research when ctfcli was being implemented but it was discounted for one reason or another. I think it's worth revisiting that discussion as well as seeing how we can vary challenge repos by branch. We would need to record branch information in order to support git subtrees anyway.

I am completely rewriting ctfcli for a personal project and I wanted to share it here

I am making an "all in one" setup script using docker-compose and kubernetes with some bash and python tying it all together to make a CTFd based pentesting/malware analysis/threat actor analysis/learning project thing-a-ma-bob for my community to learn with but I needed to integrate ctfcli into the overall schema and ended up rewriting it...

I am integrating as many open source challenges as I can into the repository, it is a repository manager with ctfd/git operations that interfaces with the CTFd server. It has a masterlist yaml file that is a representation of the entire challenge set.

I have yet to fully morph the API calls to ctfd into a more abstract schema but I think you should just see it.

I have gotten the masterlist for the challenge repository working, it has read/write methods that turn code to yaml, I am now working on the getter/setter/listing methods, I am going to also get the templating and "build a challenge on the command line" thing going,

The root of the repository is here
https://github.com/mister-hai/sandboxy/tree/master/data/CTFd

the tool itself is here
https://github.com/mister-hai/sandboxy/tree/master/data/CTFd/ctfcli

And the modified open source challenges are in the "challenges" folder

I didnt know how to inform anyone of this properly, I just an trying to contribute to both of our communities and provide a platform for accelerated learning. I am trying very hard to document everything as well as I would have appreciated when I was learning the beginner stuff... I still am learning newb stuff lmao!

Thank you for your time!

Use of markdown in challenge description

Hi!

Maybe i'm missing something but I couldn't find how to use the standard markdown syntax in the description field of the challenge file. If I try to use multiline syntaxe for yaml it seems that every special char is escaped.

Could you provide an example ?
Thanks

Healthcheck parameter

We can include a healthcheck field in challenge.yml that specifies a script for us to execute to check if a challenge is viable. We can pass it the connection info in CTFd as well.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.