Open-source project
ProbiusOfficial/Hello-CTF avatar
ProbiusOfficial/Hello-CTF

Two licence files, five exact pins, and an image pointed at one mirror

Hello CTF: a free, open-source introductory CTF tutorial with matching challenges, written for absolute beginners while also filling knowledge gaps for more advanced players, aiming to support the open-source CTF and cybersecurity ecosystem.

4,303 stars266 forksHTMLGPL-3.0

At a glance

What is it?
Hello-CTF is a Chinese-language capture-the-flag tutorial built as a documentation site rather than as software, and reading it as a project rather than as a book shows a small site with real infrastructure: an events feed updated daily by a workflow, an admin panel, a message collector, and a container image. Three details are worth flagging. The tree holds two licence files while the project reports one. Every documentation dependency is pinned to an exact version, and the requirements file says in a comment why. And the container hardcodes a third-party package mirror for both Python and the operating system packages.
Who is it for?
This is a good resource to read and a reasonable one to run locally, and the project is unusually clear about its own gaps, asking readers to report wrong knowledge points and unclear passages. Two things to know before you build or redistribute it.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • ProbiusOfficial/Hello-CTF4,303 ★ · +85
Star history
Repository2026-09-232026-11-14
ProbiusOfficial/Hello-CTF4.2k4.3k

85 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The repository is Chinese and the website is the product

There is one readme in the repository and it is written in Chinese, with no English version beside it. The subject matter is a beginner-oriented tutorial on capture-the-flag competitions, free and open source, written for people starting from nothing and aimed at closing the gap in information that the page says beginners otherwise spend most of their time searching for.

What gets published is a website rather than a package. The documentation is built with a static site generator's material theme and deployed through the platform's own pages feature at the address in the repository's homepage field. CDN support is credited to a named individual from a security team, which is the sort of contribution that never appears in a commit log but keeps a site reachable.

The page also sets a republication condition in one line: if you want to reprint the project, carry the source address. That is a request rather than a licence term, and the licence section of the page is worth reading separately before you treat it as binding.

The rest of the page is an invitation to contribute: the book is described as still being updated, and readers are asked to report wrong knowledge points, unclear passages and spelling errors, through the comment area under an article or as a pull request.

Five directions, and every knowledge point has a challenge

The main tutorial covers five directions, described by the abbreviations the community uses: miscellaneous, web, cryptography, reverse engineering and exploitation. Beside them sit extension areas covering attack-and-defend formats, machine learning and blockchain.

The commitment that makes it a course rather than a wiki is stated per direction. For each area's foundational knowledge the project provides a matching challenge, and each challenge ships with its attachments, its source code and a container definition. Every challenge can be run on your own machine or launched directly on a named hosted competition platform, and the text says the tutorial walks readers through them and encourages them to reproduce each one themselves.

That last part is the pedagogical claim worth taking seriously: a writeup you read is a writeup you understand, a challenge you reproduce is one you can solve on a competition day.

Two supporting sections extend the same idea. A tag index collects knowledge points that show up in competitions with a short introduction and related payloads, which is closer to a lookup table than a lesson. And a section for challenge authoring covers container teaching, tips on writing and packaging challenges, and a separate template project for containers that issue a dynamic flag per instance.

Two licence files at the root, one licence on the page

The repository reports its licence as the GNU General Public License, version 3.

The tree contains two licence files. There is one named for the licence itself, and a second with a suffix indicating it covers documentation. Nothing in the page distinguishes them, and nothing in the page mentions a second file at all.

That is worth stating plainly rather than resolving. A project split into code and documentation sometimes uses two licences deliberately, sometimes inherits a licence file from an upstream template, and sometimes forgets. From the outside those three cases look identical, and they have very different consequences for somebody who wants to republish the text with attribution.

The page's republication line asks you to carry the source address, which is good practice and is not the same thing as a grant. So the practical step is to read both files before you copy anything out of here, and to ask if the second file's scope is not obvious.

Everything else in the tree is unambiguous by comparison: a readme, a licence, a documentation licence, a requirements file, a theme override directory, and a static site generator configuration.

Five exact pins, and the file explains why

The requirements file lists five packages, and every one of them is pinned to an exact version rather than a range. The first line of the file is a comment that explains the policy:

code
requests==2.34.2
feedparser==6.0.12
mkdocs==1.6.1
mkdocs-material==9.7.7
mkdocs-video==1.5.0

The comment says the versions are locked because the theme modifications, described as custom work in the overrides directory and in CSS variables, are bound to a particular version of the site generator's theme package, so upgrading requires actively testing the site again.

That is the right reason to pin, and writing it down is rarer than doing it. A pinned set with a stated dependency on internal theme structure tells a future maintainer two things at once: the pins are not laziness, and removing one of them is a task rather than a version bump.

The shape of the list also tells you what the site does. Two packages are the site generator and its theme, one adds video support to the generator, one is an HTTP client, and one is a feed parser, which fits the README's note that foreign events are updated daily from the CTFtime RSS feed by a GitHub Action.

The container resolves everything through one vendor's mirrors

The container definition is the whole build, and it is short:

dockerfile
FROM python:3.12.12-alpine

ENV PIP_INDEX_URL=https://mirrors.aliyun.com/pypi/simple/
RUN pip install --upgrade pip
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories \
    && apk add --no-cache build-base

WORKDIR /Hello-CTF

COPY requirements.txt ./requirements.txt
RUN pip install -r requirements.txt

COPY mkdocs.yml ./mkdocs.yml
COPY overrides ./overrides
COPY docs ./docs

EXPOSE 8000

CMD ["mkdocs", "serve", "-a", "0.0.0.0:8000"]

Two lines in it are about where packages come from rather than what they do. One sets the Python package index to a mirror hosted by a commercial cloud provider, and one rewrites the operating system's package repository host to a mirror from the same provider before installing build tools.

Both are ordinary, sensible choices for a project built and used in a region where the default hosts are slow. Both are also baked into the image, so anyone building it elsewhere resolves every dependency through that one vendor's mirrors unless they override them, which means the build's supply chain is one company's rather than the two you would get from a stock base image.

A builder who cares can edit the Dockerfile to use their own index and drop the rewrite. A builder who does not care gets a fast build and a mirror they did not choose.

The image copies three paths and serves a development server

Look at the copy instructions again: the requirements file, the site configuration, the theme overrides directory and the docs directory. Four things enter the image.

The repository root also contains an images directory, a resources directory, a site management panel, a message collector, two update scripts, a discussion configuration file and an agent skill file. None of them is copied.

That produces two different behaviours from the two documented ways to run the site. Running the generator locally from a checkout sees the whole tree, so images and resources resolve. Running it in the container sees four paths, so anything the site references from the other directories is missing. The preview address the page gives you is a local one, which is consistent with the local path being the supported route and the container being a convenience.

The last line is also worth reading as a deployment choice rather than a build one. The container runs the generator's development server, not a static export, bound to all interfaces inside the container, and the compose file publishes port 8000 straight through:

yaml
version: '0'
services:
  hello-ctf:
    build: .
    image: hello-ctf
    container_name: hello-ctf
    ports:
      - "8000:8000"

That is fine for a laptop and not what you want in front of anything public.

The documented structure leaves half the root unmentioned

There is a project structure section, and it names five things: the docs directory holding the tutorial source, the custom homepage, the sidebar pages and the events data; an overrides directory for theme customisation; two update scripts that a workflow runs daily to refresh the events data; an admin panel described as managing events, homepage content, documentation and deployment; and a message collector that receives event submissions and feedback.

What it does not name is everything else in the root: the agent skill file, the second licence file, a resources directory, the discussion configuration, a Python version file, a formatter configuration, and an images directory.

The gap is harmless in practice. The structure section reads as a description of the moving parts, not as a complete listing, and a reader who wants the file list already has the file list. It matters in one specific way: the skill file and the second licence are exactly the two entries a reader would want explained, and neither is.

The credits section closes the picture. The site is built on the static site generator's material theme, the project started as a single readme document, and it exists because of a well-known open-source book on algorithms that the author credits as the model for the approach and recommends to anyone interested in the subject. Contributions are invited three ways: pull requests for corrections, direct contact for challenges and write-ups, or an issue.

Editorial conclusion

This is a good resource to read and a reasonable one to run locally, and the project is unusually clear about its own gaps, asking readers to report wrong knowledge points and unclear passages. Two things to know before you build or redistribute it. The tree carries two licence files while the page names one licence, so if you are republishing the text, find out what the second file governs instead of assuming. And the container resolves every dependency through a mirror the project chose, which is a reasonable choice for its home market and a supply chain decision you may want to override on your own network.

Frequently asked questions

What is Hello-CTF?

An open source, free, beginner-oriented tutorial on capture-the-flag competitions, published as a documentation website. It covers five main directions plus extension areas from entry to advanced level, and pairs each knowledge point with a challenge that ships its attachments, source and a container definition.

How do I build Hello-CTF locally?

It is a Python project: install the requirements file, then run the documentation server. A container route is documented as well, brought up with compose, and both serve a preview on the loopback address at port 8000.

Does Hello-CTF ship challenge source code?

The page says each direction's challenges come with their attachments, their source and a container definition, that every challenge can be deployed locally or launched on the NSSCTF platform, and that the tutorial guides readers through reproducing them themselves.

What licence is Hello-CTF under?

The repository reports the GNU General Public License version 3, and the tree contains both a LICENSE file and a second file whose name indicates it covers documentation. The page names one licence and does not say what the second file governs.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. ProbiusOfficial/Hello-CTF on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/probiusofficial-hello-ctf.svg)](https://hysenlabs.com/projects/probiusofficial-hello-ctf)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/probiusofficial-hello-ctf.svg)](https://hysenlabs.com/projects/probiusofficial-hello-ctf)

Was this useful?