gzctf平台搭建教程

项目介绍

前段时间有一个想法:想搞一个校内的ctf,这其实是我们学校的第一届校内ctf,之前学校是没有举办过的。于是我就开始找项目看有没有简单操作的,找的时候自己搭建了两个平台,一个是ctfd这个项目不适合快速的搭建,一个是ocean ctf这个项目只能试用商业化了也不适合。后面就找到了gzctf,这个是我经过实测的,在一个网络安全班里面实际测试过的,跑在一个虚拟机里面,设置4g,4核完全够用,我当时测试的班里面一共有30个人,我和另外三个小伙伴出的题目,我搭建的这个平台一直开放了大概20个小时,非常的流畅,中间没有出现任何问题。

https://github.com/GZTimeWalker/GZCTF

官方的教程网址https://gzctf.gzti.me/zh

这个项目叫做gzctf,是用来搭建ctf比赛的,十分的方便

大家可以看看当时我30个人测试的效果,下面的截图是当时测试比赛时候截的图

image-20260505180225402

image-20260505180306504

image-20260505180340501

image-20260505180401191

image-20260505180444743

image-20260505180529472

image-20260505180618043

搭建教程

说多了,现在开始搭建。

我们不需要下载github上面的源码,我们只需要自己编写两个文件

1
2
├── appsettings.json
├── compose.yml

首先看appsettings.json文件怎么写

大佬可以自己研究,不想折腾的可以按照我的来配置,其中需要自己配置的我在后面有注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
ubuntu@ubuntu24:~/gzctf$ cat appsettings.json
{
"AllowedHosts": "*",
"ConnectionStrings": {
"Database": "Host=db:5432;Database=gzctf;Username=postgres;Password=gzctf" # 只需要配置一个password,数据库的账号么密码
},
"EmailConfig": {
"SenderAddress": "",
"SenderName": "",
"UserName": "",
"Password": "",
"Smtp": {
"Host": "localhost",
"Port": 587
}
},
"XorKey": "dht75kslpq29vnx",
"ContainerProvider": {
"Type": "Docker",
"PortMappingType": "Default",
"EnableTrafficCapture": false,
"PublicEntry": "192.168.8.133", #看好自己的ip地址即可,更具实际情况配置。
"DockerConfig": {
"SwarmMode": false,
"Uri": "unix:///var/run/docker.sock"
}
},
"CaptchaConfig": {
"Provider": "None",
"SiteKey": "",
"SecretKey": ""
}
} #这些不需要配置
ubuntu@ubuntu24:~/gzctf$

再看到compose.yml,这个是给docker compose使用的文件

不想折腾的可以按照我的这个配置

注意修改自己的密码即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
ubuntu@ubuntu24:~/gzctf$ cat compose.yml
services:
gzctf:
image: registry.cn-shanghai.aliyuncs.com/gztime/gzctf:develop
restart: always
environment:
- "GZCTF_ADMIN_PASSWORD=Gzctf@2026!Test" # 平台初始管理员密码,用户名默认 admin,密码要复杂一点
# 选择后台语言,如 en_US / zh_CN / ja_JP
- "LC_ALL=zh_CN.UTF-8"
ports:
- "8080:8080" # 外部80端口被占用,已修改为8080
volumes:
- "./data/files:/app/files"
- "./appsettings.json:/app/appsettings.json:ro"
- "/var/run/docker.sock:/var/run/docker.sock" # Docker 部署必须
depends_on:
db:
condition: service_healthy # 建议等数据库健康检查通过后再启动

db:
image: postgres:alpine
restart: always
environment:
- "POSTGRES_PASSWORD=gzctf" # 数据库密码,需与 appsettings.json 中完全一致
volumes:
- "./data/db:/var/lib/postgresql" # 修正了挂载路径
healthcheck: # 添加健康检查,配合上面的 condition: service_healthy
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
ubuntu@ubuntu24:~/gzctf$

之后就是直接在这些文件的目录下面运行

1
docker compose up -d

image-20260505181622132

之后就是访问设置的端口即可

登录进去密码就是自己配置的

使用教程

我们管理员的操作主要是

image-20260505181814574

在这个小扳手里面操作的

点击新建比赛之后就来到了这个页面

image-20260505181903195

这里配置很简单的,没有什么难度,下面我只讲一下需要注意的事项

这个平台注册用户的操作主要是选手注册账号之后,默认配置是选手需要新建队伍才能参加比赛的

然后新建队伍之后需要管理员审核才能参加比赛

下面这个是选手视角

image-20260505182425784

下面这个是管理员视角

image-20260505182506633

之后注意的事项就是新建题目了

image-20260505182555015

对于web一般是使用动态容器,使用动态容器是需要自己在题目里面编写动态flag的,对于动态flag的编写,gzctf也有格式

大家可以跟着我写一个测试题目

测试题目如下,有两个文件

index.php

1
2
3
4
5
6
<?php
// 直接从环境变量获取 Flag
$flag = getenv('GZCTF_FLAG');
// 然后你可以把它藏进 HTML 注释或提交给后端逻辑
echo "<!-- " . htmlspecialchars($flag) . " -->";
?>

Dockerfile

1
2
3
4
5
6
7
8
# 使用一个带 Web 服务的 PHP 基础镜像
FROM php:7.0-apache

# 把包含上述 PHP 代码的 index.php 复制到容器中
COPY index.php /var/www/html/

# 暴露 Web 服务端口
EXPOSE 80

可以看到动态flag的写法就是getenv(‘GZCTF_FLAG’); 从环境变量里面获得字段

然后

1
docker build -t echo_flag .

-t是取一个名字

构造好之后,使用docker images就可以看到在本地刚刚构造的镜像了

image-20260505183220793

upload-htaccess:v1是我测试比赛的时候构建的题目镜像

有了镜像之后就上题目了

image-20260505183323548

在这里写上镜像的名字就可以了

这个就是在本地建立题目的操作,其实也可以不用再本地构建镜像, 也可以将镜像上传到云平台,比如阿里云的镜像仓库,那么我们在容器镜像里面输入的就是阿里云的镜像地址就可以了(这个方法有的时候使用不了,我就使用不了)

其实这个项目的操作,我上面所说的只是快速搭建而已,其实人家有一套成熟的体系

不止有这些操作,这里给出别人的研究搭建文章手把手教你搭建GZCTF比赛平台+动态靶机部署,超详细教程,看这一篇就够了 - Acc1oFl4g - 博客园

结束


gzctf平台搭建教程
https://exploreio.github.io/2026/05/05/gzctf/
作者
ExploreIO
发布于
2026年5月5日
许可协议