搭建个人CTF动态靶场

Posted by Tattoo on 2020-07-28
Estimated Reading Time 8 Minutes
Words 1.8k In Total
Viewed Times

前言

根据网上的教程,用CTFd配合ctf-whale插件搭建一个动态靶机,有些踩坑的地方记录下来

官方教程https://www.zhaoj.in/read-6333.html

搭建环境

  • ubuntu18.04

  • docker19.03.12

  • docker-compose1.26.2

搭建步骤

一、安装docker

  • 方法一:使用官方脚本自动安装
1
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
  • 方法二:通过版本库安装(repository)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1. 更新系统包索引
sudo apt-get update

2. 添加HTTPS协议,允许apt从HTTPS安装软件包
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

3. 添加Docker公共密钥 Docker 官方源
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add

4. 设置版本库类型,软件版本包括三种: stable、edge、test
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

5. 安装最新版docker-ce
sudo apt-get install docker-ce

6. 设置开机自启动并启动docker
sudo systemctl enable docker
sudo systemctl start docker

二、安装docker-compose

  • 方法一:使用curl从github中安装
1
2
3
4
5
6
7
8
9
1. 进入https://github.com/docker/compose/releases 查看最新版本,当前版本为1.26.2
sudo curl -L https://github.com/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

2. 设置权限
sudo chmod +x /usr/local/bin/docker-compose

3. 查看是否安装成功
docker-compose --version
出现docker-compose version 1.26.2即安装成功
  • 方法二:使用pip安装
1
pip安装方法速度较方法一快,网上教程很多,详情不再赘述

三、设置docker镜像加速

1
2
3
1. 访问https://help.aliyun.com/document_detail/60750.html
2. 找到并进入容器镜像服务控制台
3. 按照操作文档配置镜像加速器,形如下图

四、安装启动frps

1
2
3
4
5
6
7
8
9
10
cd
wget https://github.com/fatedier/frp/releases/download/v0.29.0/frp_0.29.0_linux_amd64.tar.gz
tar -zxvf frp_0.29.0_linux_amd64.tar.gz
cd frp_0.29.0_linux_amd64
sudo cp systemd/* /etc/systemd/system/
sudo mkdir /etc/frp
sudo cp frpc.ini frps.ini /etc/frp/
sudo cp frpc frps /usr/bin/
sudo chmod a+x /usr/bin/frpc /usr/bin/frps
sudo systemctl enable frps

坑一:第一步的cd一定要执行,进入/root目录,否则后面编辑文件位置不正确

编辑frps.ini

1
sudo vim /etc/frp/frps.ini

frps.ini内容

1
2
3
4
[common]
bind_port = 7897
bind_addr = 0.0.0.0
token = thisistoken

使用python脚本随机生成一个token,需保证与后面frpc.ini里的token一致

启动frps系统服务

1
sudo systemctl start frps

五、创建网络并启动frpc容器并配置frpc.ini

启动frpc容器

1
2
sudo docker network create ctfd_frp-containers
sudo docker run -d -v ~/frp_0.29.0_linux_amd64/frpc.ini:/etc/frp/frpc.ini --network="ctfd_frp-containers" --restart=always "glzjin/frp"

此时frpc容器处于不断重启状态,不需要在意,后面配置完状态将变为up

创建网络frpcadmin用于ctfd容器和frpc容器通信

1
2
3
1. sudo docker network create frpcadmin 
2. docker ps //查看frpcadmin容器ID
3. sudo docker network connect frpcadmin <frpc容器ID>

查看frpcadmin网络的连接情况并记录frpc容器的网络IP

1
docker network inspect frpcadmin

坑二:如果执行一次看不到IPv4Address的值,需要多连续执行几次就能看到,因为容器一直在重启

编辑frpc.ini

1
vim ~/frp_0.29.0_linux_amd64/frpc.ini

frpc.ini内容

1
2
3
4
5
6
7
[common]
server_addr = 172.17.0.1 //ifconfig之后查看docker0的ip
server_port = 7897
token = thisistoken //与前面frps.ini的token一致
admin_addr = 172.22.0.2 //这里填写frpc容器的网络IP,即IPv4Address的值,因人而异,不要一摸一样填
admin_port = 7400
log_file = ./frps.log

编辑完重启frpc容器

1
docker restart <frpc容器的ID>

此时frpc容器已经处于up状态

六、安装靶场与插件

下载靶场与插件

1
2
3
4
5
6
7
8
9
git clone https://github.com/CTFd/CTFd.git
cd CTFd/
git reset 6c5c63d667a17aec159c8e26ea53dccfbc4d0fa3 --hard //回滚到当前教程适合的版本
cd CTFd/plugins //打开ctfd插件目录
git clone https://github.com/glzjin/CTFd-Whale.git ctfd-whale
cd ctfd-whale
git reset 5b32f457e9f56ee9b2b29495f4b3b118be3c57bd --hard //回滚到当前教程适合的版本
cd ../../.. //返回CTFd主目录
vim docker-compose.yml

坑三:这里还需要更改一个css的引用地址,之前搭建完后访问非常慢,原因在于某个css的引用地址访问时极慢,如图更改

配置docker-compose.yml

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
version: '2.2'

services:
ctfd:
build: .
user: root
restart: always
ports:
- "8000:8000"
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
- /var/run/docker.sock:/var/run/docker.sock #添加这句即可,别的基本按照官方的不用动
depends_on:
- db
networks:
default:
internal:

db:
image: mariadb:10.4.12 #这里改成10.4.12,10.4.13会出错
restart: always
environment:
- MYSQL_ROOT_PASSWORD=ctfd
- MYSQL_USER=ctfd
- MYSQL_PASSWORD=ctfd
- MYSQL_DATABASE=ctfd
volumes:
- .data/mysql:/var/lib/mysql
networks:
internal:
# This command is required to set important mariadb defaults
command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --wait_timeout=28800, --log-warnings=0]

cache:
image: redis:4
restart: always
volumes:
- .data/redis:/data
networks:
internal:

networks:
default:
internal:
internal: true

修改Dockerfile

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
FROM python:2.7-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories &&\
apk update && \
apk add python python-dev linux-headers libffi-dev gcc make musl-dev py-pip mysql-client git openssl-dev
RUN adduser -D -u 1001 -s /bin/bash ctfd

WORKDIR /opt/CTFd
RUN mkdir -p /opt/CTFd /var/log/CTFd /var/uploads
RUN pip config set global.index-url https://pypi.doubanio.com/simple
RUN pip config set install.trusted-host pypi.doubanio.com
COPY requirements.txt .

RUN pip install -r requirements.txt -i https://pypi.doubanio.com/simple

COPY . /opt/CTFd

RUN for d in CTFd/plugins/*; do \
if [ -f "$d/requirements.txt" ]; then \
pip install -r $d/requirements.txt -i https://pypi.doubanio.com/simple; \
fi; \
done;

RUN chmod +x /opt/CTFd/docker-entrypoint.sh
RUN chown -R 1001:1001 /opt/CTFd
RUN chown -R 1001:1001 /var/log/CTFd /var/uploads

USER 1001
EXPOSE 8000
ENTRYPOINT ["/opt/CTFd/docker-entrypoint.sh"]

修改requirements.txt

1
2
在最后添加一行
banal==0.4.2

构建并启动镜像

1
2
docker-compose build
docker-compose up -d

将ctfd容器连接frpcadmin网络

1
docker network connect frpcadmin <ctfd容器ID>

访问IP:8000即可打开CTFd

第一次进入会要求设置管理员账号密码,按需设置即可

登录后进入管理页面选择插件

填写相关参数

Frp API IP填frpc容器网络的IP

domain没有就填None

Frp Direct IP Address填自己的公网IP

template里面写上frpc.ini的内容,其他照着填就行

至此,CTFd动态靶场已经搭建完成

七、创建题目

配置参数

Challenge Type题目类型选择dynamic_docker

Name题目名字

Category题目分类

Initial Value初始分值

Decay Value递减分值

Minimum Value最小分值

Docker Image支持动态flag的镜像

Frp Http Portfrps http开放的端口

Frp Redirect Type没有域名选择Direct

Frp Redirect Port转发到靶机容器的端口

Score Type是否启用动态分数

尝试启动靶机

第一次启动会比较慢,因为docker在pull镜像,最好先pull再创建题目,这样启动题目更快

启动成功

八、使用docker-compose一站式部署靶场、容器与网络

以下docker-compose.yml的功能涵盖了上述步骤,更方便快捷,一条命令即可部署CTFd

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
version: '2'

services:
ctfd:
build: .
user: root
restart: always
ports:
- "8000:8000" #你自己的
environment:
- UPLOAD_FOLDER=/var/uploads
- DATABASE_URL=mysql+pymysql://root:ctfd@db/ctfd
- REDIS_URL=redis://cache:6379
- WORKERS=1
- LOG_FOLDER=/var/log/CTFd
- ACCESS_LOG=-
- ERROR_LOG=-
volumes:
- .data/CTFd/logs:/var/log/CTFd
- .data/CTFd/uploads:/var/uploads
- .:/opt/CTFd:ro
- /var/run/docker.sock:/var/run/docker.sock #添加这句即可,别的基本按照官方的不用动
depends_on:
- db
networks:
default:
internal:
frpcadmin:
ipv4_address: 172.22.0.3

db:
image: mariadb:10.4.12
restart: always
environment:
- MYSQL_ROOT_PASSWORD=ctfd
- MYSQL_USER=ctfd
- MYSQL_PASSWORD=ctfd
- MYSQL_DATABASE=ctfd
volumes:
- .data/mysql:/var/lib/mysql
networks:
internal:

# This command is required to set important mariadb defaults
command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --wait_timeout=28800, --log-warnings=0]

cache:
image: redis:4
restart: always
volumes:
- .data/redis:/data
networks:
internal:
frpc:
image: glzjin/frp:latest
restart: always
volumes:
- ~/frp_0.29.0_linux_amd64/frpc.ini:/etc/frp/frpc.ini
networks:
frpcadmin:
ipv4_address: 172.22.0.2
frp-containers:
networks:
default:
internal:
internal: true
frpcadmin:
driver: bridge
internal: true
ipam:
config:
- subnet: 172.22.0.0/16
frp-containers:
driver: bridge
ipam:
config:
- subnet: 172.21.0.0/16

If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !