Skip to content

Commit

Permalink
feat: initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
pl4nty authored Aug 24, 2023
0 parents commit 51ae0cb
Show file tree
Hide file tree
Showing 16 changed files with 659 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
indent_style = space
indent_size = 2
tab_width = 2

end_of_line = lf

trim_trailing_whitespace = true
insert_final_newline = true

# Python convention
[*.py]
indent_size = 4
tab_width = 4
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.zip filter=lfs diff=lfs merge=lfs -text
*.7z filter=lfs diff=lfs merge=lfs -text
*.zip.00* filter=lfs diff=lfs merge=lfs -text
*.7z.00* filter=lfs diff=lfs merge=lfs -text
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
blank_issues_enabled: false
52 changes: 52 additions & 0 deletions .github/ISSUE_TEMPLATE/submit-challenge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Challenge
description: Create a new challenge
title: Add your challenge name here
body:
- type: dropdown
attributes:
label: Category
options:
- crypto
- forensics
- misc
- osint
- pwn
- rev
- steg
- web
# required fields are only supported on public repos
validations:
required: true
- type: input
attributes:
label: Author
validations:
required: true
- type: textarea
attributes:
label: Description
placeholder: Add a short description for players to see
validations:
required: true
- type: input
attributes:
label: Flag
value: ctf{your_flag_here}
validations:
required: true
- type: input
attributes:
label: Image
description: The Dockerfile path for challenge containers (eg pwn or web)
placeholder: .
- type: textarea
attributes:
label: Writeup
placeholder: Describe the intended solution to your challenge here
validations:
required: true
- type: checkboxes
attributes:
label: Publishing
options:
- label: Can the challenge and its writeup be released publicly after the CTF?
122 changes: 122 additions & 0 deletions .github/challenge-schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
$schema: http://json-schema.org/draft-04/schema
title: ctfcli challenge v0.1
description: Based on https://github.com/CTFd/ctfcli/blob/master/ctfcli/spec/challenge-example.yml
type: object
required:
- name
- author
- category
- description
- flags
properties:
version:
const: "0.1"
name:
type: string
author:
type: string
category:
type: string
description:
type: string
value:
type: integer
minimum: 0
default: 500
type:
type: string
default: standard

extra:
type: object
properties:
initial:
type: integer
minimum: 0
default: 500
decay:
type: integer
minimum: 1
default: 4
function:
type: string
enum:
- linear
- exponential
default: linear
minimum:
type: integer
minimum: 0
default: 100

image:
type: string
protocol:
type: string
host:
type: string

connection_info:
type: string
healthcheck:
type: string
attempts:
type: integer
minimum: 1

flags:
type: array
items:
oneOf:
- type: string
- type: object
properties:
type:
type: string
enum:
- static
content:
type: string
data:
type: string
enum:
- case_insensitive

topics:
type: array
items:
type: string
tags:
type: array
items:
type: string

files:
type: array
items:
type: string

hints:
type: array
items:
oneOf:
- type: string
- type: object
properties:
content:
type: string
cost:
type: integer
minimum: 0

requirements:
type: array
items:
type: string

state:
type: string
enum:
- hidden
- visible
default: visible
24 changes: 24 additions & 0 deletions .github/challenge-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
version: "0.1"
name: {{ name }}
category: {{ category }}
author: {{ author }}
description: |
{{ description | indent(width=2) }}
flags:
- type: static
content: {{ flag }}
data: case_insensitive

type: dynamic
extra:
initial: 500
decay: 4
function: linear
minimum: 100

image: {{ image }}
protocol: {{ protocol }}

# files:
# -
70 changes: 70 additions & 0 deletions .github/workflows/create-challenge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Create challenge from issue

on:
issues:
types:
- opened

jobs:
process:
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected]
- uses: zentered/[email protected]
id: form

- name: Slugify challenge name
id: slugify
uses: rlespinasse/[email protected]
with:
key: title
value: ${{ github.event.issue.title }}

- name: Make challenge directory and metadata
id: chal
run: |
directory="${{ env.category }}/${{ steps.slugify.outputs.slug }}"
mkdir -p $directory
echo "directory=$directory" >> $GITHUB_OUTPUT
echo "category=${{ env.category }}" >> $GITHUB_OUTPUT
env:
category: ${{ fromJSON(steps.form.outputs.data).category.text }}

- name: Create writeup
run: echo "${{ fromJSON(steps.form.outputs.data).writeup.text }}" > ${{ steps.chal.outputs.directory }}/README.md

- name: Parse issue form to jinja2 data file
run: echo '${{ steps.form.outputs.data }}' | jq 'with_entries(.value = .value.text)' > data.json

- name: Render challenge.yml
uses: cuchi/[email protected]
with:
template: .github/challenge-template.yml
output_file: ${{ steps.chal.outputs.directory }}/challenge.yml
data_file: data.json
data_format: json # autodetects as yaml, despite docs stating it's extension-based
# Default to HTTPS protocol for web challenges
variables: |
name=${{ github.event.issue.title }}
protocol=${{ fromJSON(steps.form.outputs.data).writeup.text == 'web' && 'https' || 'tcp' }}
- run: rm data.json

- uses: peter-evans/[email protected]
with:
branch: patch-${{ github.event.issue.number }}
title: ${{ env.title }}
body: "Closes #${{ github.event.issue.number }}"
commit-message: ${{ env.title }}
env:
title: "chals(${{ steps.chal.outputs.category }}): add ${{ steps.slugify.outputs.slug }}"

- uses: peter-evans/[email protected]
with:
issue-number: ${{ github.event.issue.number }}
body: |
[Click here to upload challenge files](${{ format('{0}/{1}/upload/patch-{2}/{3}',
github.server_url,
github.repository,
github.event.issue.number,
steps.chal.outputs.directory
)}})
84 changes: 84 additions & 0 deletions .github/workflows/deploy-challenges.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Deploy challenges

on:
push:
branches:
- main
paths:
- "**/challenge.yml"
workflow_dispatch:
filter:
type: string
description: Glob pattern for target challenges
required: true
default: '**/challenge.yml'

jobs:
get-chals:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
challenges: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || steps.changed-files.outputs.all_changed_and_modified_files }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v35
with:
files: "**/challenge.yml"

deploy:
needs: get-chals
runs-on: ubuntu-latest
permissions:
contents: read

steps:
# https://github.com/actions/checkout/issues/165#issuecomment-1639209867
- name: Checkout
uses: actions/checkout@v3

- name: Create LFS file list
run: git lfs ls-files --long | cut -d ' ' -f1 | sort > .lfs-assets-id

- name: Restore LFS cache
uses: actions/cache@v3
with:
path: .git/lfs/objects
key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}
restore-keys: |
${{ runner.os }}-lfs-
- run: git lfs pull

- uses: actions/setup-python@v4
with:
python-version: 3.x

- name: Setup ctfcli
run: pip install git+https://github.com/CTFd/ctfcli # ctfcli==0.0.14

- name: Load CTFd credentials
run: |
mkdir .ctf
cat <<EOF > .ctf/config
[config]
url = https://${{ vars.CTFD_DOMAIN }}
access_token = ${{ secrets.CTFD_TOKEN }}
[cookies]
site_password = ${{ secrets.CTFD_SITE_PASSWORD }}
[challenges]
EOF
# TODO use 'ctf' once fixed
- name: Deploy challenges
run: |
for chal in ${{ needs.get-chals.outputs.challenges }}; do
python -m ctfcli challenge install $chal --force
done
Loading

0 comments on commit 51ae0cb

Please sign in to comment.