前言
前天搭GZ台子的时候看了很多教程,也踩了很多坑,所以就想记录下自己的安装步骤
一.GZCTF搭建及web环境搭建
1.docker安装(Windows)
1.1docker下载
英文版下载地址:Docker: Accelerated Container Application Development

汉化版下载地址:Release 4.42.0 · asxez/DockerDesktop-CN
如果下载汉化版,还要下载配置文件,到c盘中的安装路径(默认路径安装的话就为C:\Program Files\Docker\Docker\frontend\resources
),替换原来的配置文件即可,原配置文件应该是appxxxx.asar
这个名字

下载后安装的时候似乎没有其他多余选项了,直接下一步就行,但是路径目前不知道怎么修改,只有装在c盘
安装完成后重启电脑就行
1.2docker配置
首次进入docker会要求登录账户,可以注册一个Docker hub
的账户,也可以跳过
然后就去更换拉取的镜像源,默认是从Docker Hub
拉取的,但是国内的话,没用magic
可能比较慢,所以可以去换个比如阿里云,百度云的镜像源
进入docker
,在配置中找到Docker Engine
(汉化后就是Docker
引擎)

这里阿里云的镜像地址要去自己找,有自己的id
容器镜像服务 ACR 控制台

"registry-mirrors": [ "https://xxxxxxx.mirror.aliyuncs.com", "https://mirror.baidubce.com" ]
|
注意json
格式不要错了,最后保存即可
可以通过命令来验证

这样就成功了
也可以简单拉取一个docker容器来验证

这样就是配置完成了
2.GZCTF搭建
2.1下载
下载地址:GZTimeWalker/GZCTF: The GZ::CTF project, an open source CTF platform.
服务器上也可以直接通过git拉取,我这里是debian的服务器
git clone https://github.com/GZTimeWalker/GZCTF.git
|
服务器上也要提前下载docker,我这里就直接用宝塔下载了
2.2配置
下载后进入GZCTF文件夹,添加两个配置文件,注意,这两个文件一定要认真弄,那天就是卡在这里很久,appsettings.json
复制使用时要删除注释内容,注意GZCTF使用的是PostgreSQL
,而且如果反向代理要弄的话还要修改nginx
配置文件
使用反向代理
appsettings.json
{ "AllowedHosts": "*", "Kestrel": { "Endpoints": { "Http": { "Url": "http://+:80", "Protocols": "Http1" } }, "Limits": { "MaxRequestBodySize": 52428800 } }, "ConnectionStrings": { "Database": "Host=db;Port=5432;Database=gzctf;Username=postgres;Password=xxxxxx;Pooling=true;" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "EmailConfig": { "SendMailAddress": "123@qq.com", "UserName": "xxx", "Password": "xxx", "Smtp": { "Host": "smtp.163.com", "Port": 465, "EnableSsl": true } }, "XorKey": "xxxx", "ContainerProvider": { "Type": "Docker", "PortMappingType": "Default", "EnableTrafficCapture": false, "PublicEntry": "xx.xx.xx.xxx", "DockerConfig": { "DockerUri": "unix:///var/run/docker.sock" } }, "RequestLogging": false, "DisableRateLimit": false, "RegistryConfig": { "UserName": "", "Password": "", "ServerAddress": "" }, "GoogleRecaptcha": { "VerifyAPIAddress": "https://www.recaptcha.net/recaptcha/api/siteverify", "Sitekey": "", "Secretkey": "", "RecaptchaThreshold": "0.5" } }
|
docker-compose.yml
services: gzctf: image: registry.cn-shanghai.aliyuncs.com/gztime/gzctf:develop restart: always environment: - "GZCTF_ADMIN_PASSWORD=xxxxx" - "LC_ALL=zh_CN.UTF-8" - ASPNETCORE_URLS=http://+:80 ports: - "8080:80" volumes: - "./data/files:/app/files" - "./appsettings.json:/app/appsettings.json:ro" - "/var/run/docker.sock:/var/run/docker.sock" depends_on: - db
db: image: postgres:alpine restart: always environment: - "POSTGRES_PASSWORD=xxxxxx" volumes: - "./data/db:/var/lib/postgresql/data"
|
nginx配置
# GZCTF 的代理配置(单独一个 server 块) server { listen 80; server_name xx.xx.xx.xxx; # 改成你的域名或服务器IP
location / { proxy_pass http://127.0.0.1:8080; # 指向 GZCTF 的 Docker 端口 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
|
这里由于80端口已经被占用,所以去弄了一个反向代理,就需要在nginx配置文件中新加一个server块,如果不需要,就在上面两个配置文件删除对应配置即可
不使用反向代理
appsettings.json
{ "AllowedHosts": "*", "ConnectionStrings": { "Database": "Host=db;Port=5432;Database=gzctf;Username=postgres;Password=xxxxxx;Pooling=true;" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "EmailConfig": { "SendMailAddress": "123@qq.com", "UserName": "xxx", "Password": "xxx", "Smtp": { "Host": "smtp.163.com", "Port": 465, "EnableSsl": true } }, "XorKey": "xxxx", "ContainerProvider": { "Type": "Docker", "PortMappingType": "Default", "EnableTrafficCapture": false, "PublicEntry": "xx.xx.xx.xxx", "DockerConfig": { "DockerUri": "unix:///var/run/docker.sock" } }, "RequestLogging": false, "DisableRateLimit": false, "RegistryConfig": { "UserName": "", "Password": "", "ServerAddress": "" }, "GoogleRecaptcha": { "VerifyAPIAddress": "https://www.recaptcha.net/recaptcha/api/siteverify", "Sitekey": "", "Secretkey": "", "RecaptchaThreshold": "0.5" } }
|
docker-compose.yml
services: gzctf: image: registry.cn-shanghai.aliyuncs.com/gztime/gzctf:develop restart: always environment: - "GZCTF_ADMIN_PASSWORD=xxxxx" - "LC_ALL=zh_CN.UTF-8" - ASPNETCORE_URLS=http://+:80 ports: - "80:80" volumes: - "./data/files:/app/files" - "./appsettings.json:/app/appsettings.json:ro" - "/var/run/docker.sock:/var/run/docker.sock" depends_on: - db
db: image: postgres:alpine restart: always environment: - "POSTGRES_PASSWORD=xxxxxx" volumes: - "./data/db:/var/lib/postgresql/data"
|
2.3运行
以下均在GZCTF目录下运行
启动docker
sudo systemctl start docker
|
设置开机启动docker
sudo systemctl enable docker
|
运行docker(-d表示后台运行)
查看docker

这里由于我已经初始化了,所以看着没多少,首次应该还是比较多的
看到出现了healthy字样就表示连接成功了,如果是unhealthy,那就慢慢去看log,丢ai找问题吧(那天数据库问题硬控我半天)
查看日志
docker logs gzctf-gzctf-1 docker logs gzctf-db-1
|

这里的http://+80
也可以表示设置80端口成功
访问后大概页面如下(这是我已经更改过的了)

如果要修改docker文件后重启,用以下命令
docker-compose down && docker-compose up -d
|
3.web题目部署
3.1本地构建
首先有个大概的文件框架如下,大概思路就是本地搭建后上传到hub,在GZCTF上再从hub上拉取下来

以一个简单的web环境举例
Dockerfile
FROM ctftraining/base_image_nginx_mysql_php_56
COPY src /var/www/html
RUN mv /var/www/html/flag.sh /flag.sh && chmod +x /flag.sh
|
flag.sh
#!/bin/sh sed -i "s/flag{testflag}/$GZCTF_FLAG/" /var/www/html/index.php
export GZCTF_FLAG=""
|
index.php
<!DOCTYPE html> <html> <head> <title>签到</title> </head> <!--flag{testflag}--> <body> <?php echo "Do u want 2 sign??<br>"; ?> </body> </html>
|
构建好后进入Dockerfile
所在文件夹下命令行
构建镜像(name为docker.io上的用户名,test1为该容器名字,.
表示最新版本)
docker build -t name/test1 .
|

这样就成功了,框的部分就是拉取镜像时需要用的
PS:这里当时配置镜像源之后还是拉不下来,要请求超时,如果遇到failed to resolve source metadata for docker.io
,可以尝试直接先从docker上搜需要的模板,自己pull
下来然后再build
3.2远程拉取
登录管理员账号,新建比赛,编辑比赛

新建题目那里如果想要动态flag就选择动态容器,进来之后在下面容器镜像的位置粘贴刚刚的那个镜像再创建测试容器,如果成功了就行

进入环境查看源码如果效果如下

这样就代表成功了,之后的web题就可以类似实现动态flag部署了
4.结尾
搭建到这里就完成了,虽然看了很多教程但是还是踩了不少坑,所以写点文章记录记录,也给后人乘凉
(PS:学长说他之前写过教配置的文章,删了。。。。。。。。。)
环境搭建在http://38.55.99.186/,现在只有一个取证题,学长出了之后没机会展示的,先放那凑凑数,后面有时间了来研究点web题