Docker搭建CTF(Web)环境
一、Docker基本命令
纯笔记,其实也已经够用了。 详细资料请移步下方链接🔗
拉取查看篇
1 | docker pull ubuntu:16.04 # 拉取对应镜像 |
运行篇
1 | docker run -it 容器id # 以交互模式运行容器,为容器重新分配一个伪输入终端 |
停止删除篇
1 | docker stop 容器id #停止指定容器 |
进入退出容器篇
1 | docker exec -it 容器id /bin/bash # 进入容器的bash界面 |
之前的docker exec -it ID /bin/bash
其实并没有进入这个容器,而是弹了一个bash
出来让我们能在容器里操作,而attach
才算进入了容器内部。
查看相关配置
1 | docker port 容器id # 查看容器映射端口 |
导出导入篇
1 | docker export 容器id > ctf.tar # 导出为tar文件 |
若导入时出现这个问题open /var/lib/docker/tmp/docker-import-970689518/bin/json: no such file or directory
,说明这个tar包缺少docker所需要的一些json文件,不能直接导入。
二、文件目录总览
目录文件夹如下:
三、Dockerfile
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
👉 Dockerfile相关指令教程 👈
文件名:Dockerfile1
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
50FROM ubuntu:16.04
LABEL Author="Ztop"
LABEL Blog="https://www.zeker.top"
ENV REFRESHED_AT 2022-03-01
ENV LANG C.UTF-8
# 先写 修改源/更新 【如果必须的话】
# 替换源(这里可用sed或者直接COPY一个完整的sources.list来替换)
RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list && \
sed -i s@/security.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list && \
apt-get update -y
#防止Apache安装过程中地区的设置出错
ENV DEBIAN_FRONTEND noninteractive
#安装apache2
RUN apt-get install apache2 -y
#安装php
RUN apt-get install php -y
RUN apt-get install libapache2-mod-php -y --fix-missing
RUN apt-get install php7.0-mysql -y
# #安装mysql
# RUN apt-get install mysql-server -y
# RUN apt-get install mysql-client -y
# 然后才是复制文件,不推荐挂载卷
# ADD会自动解压压缩包,而COPY不会
# ADD html.tgz /var/www
#将题目源码放进去
RUN rm -rf /var/www/html/index.html
COPY ./src/ /var/www/html/
WORKDIR /var/www/html/
#启动脚本
COPY ./run.sh /root/run.sh
RUN chmod +x /root/run.sh
ENTRYPOINT ["/root/run.sh"]
#设置环境变量
#ENV FLAG=flag{test_flag}
#暴露端口
EXPOSE 80
在 Dockerfile 文件的存放目录下,执行构建动作。1
2
3
4
5
6
7
8docker build -t ctf:v1 . # dockerfile目录下输入构建命令,用来构建基于ubuntu:16.04的自定义镜像。
docker run -d -p 5555:80 -e FLAG=flag{$(cat /proc/sys/kernel/random/uuid)} 镜像id # 添加系统uuid作为动态flag字段
docker ps # 查看是否运行
docker exec -it 容器id /bin/bash # 进入容器
exit # 在容器内退出
四、Shell文件
文件名:run.sh1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 定义动态flag字段
uuid=$(cat /proc/sys/kernel/random/uuid)
FLAG="flag{$uuid}"
sed -i "s/flag_is_here/$FLAG/" /var/www/html/flag
# sed -i "s/flag_is_here/$FLAG/" /var/www/html/flag
# 覆盖掉环境变量,防止非预期
export FLAG=not_flag
FLAG=not_flag
#启动apache
service apache2 restart
# # never exit,此处是为了运行完上条应用服务后,有对应的前台进程
tail -f /dev/null
附上flag
文件中的内容1
flag_is_here
五、Docker-compose
Docker-compose
是一个用来把 docker
自动化的东西。
有了 docker-compose
你可以把所有繁杂重复的 docker 操作全都一条命令
,自动化的完成。
Compose
是用于定义和运行多容器 Docker 应用程序的工具。
通过 Compose
,你可以使用 YML
文件来配置应用程序需要的所有服务。
然后,使用一个命令,就可以从 YML
文件配置中创建并启动所有服务。
文件名:docker-compose.yml1
2
3
4
5
6
7
8
9
10
11
12
13
14# 指定该文件版本
version: '3'
# 把每个子目录视为一个镜像,开始构建
services:
web1:
# 此处仅允许 image, build, ports,禁止其他字段出现,如果有 volume,cmd 等设置需求,请在 Dockerfile 里进行文件拷贝或者申明。
image: ctf/test1 #镜像名字
build: ./web/ #build的位置,docker会去web1中的dockerfile开始搭建
# restart: always
ports:
- "5555:80" #设置映射的断口
environment:
- FLAG=flag{this_is_test_flag} # 这里定义了flag,但是不会覆盖sh里的$FLAG
# - FLAG=flag{$(cat /proc/sys/kernel/random/uuid)} # 获取容器的uuid作为flag 会报错
- version
说明了yml文件指明的版本号,一般我们使用2,3
这两个版本。 - services
yml文件的主体,定义了服务了配置。里面的web
标签是我们自己定义的。
build表明了以dockerfile类型启动一个容器,后面跟的是dockerfile的路径,支持相对路径和绝对路径,在这个yml文件里面,表明dockerfile与yml处在同个目录下。
- environment
构建了相关的环境变量,在这里我们是定义了一个FLAG
环境变量,并且值为flag{this_is_test_flag}
定义之前要删除shell文件
中的定义变量,否则会报错 - ports
定义了映射的端口,5555:80
表示映射到本机的5555
端口,后面的80
端口则要与Dockerfile文件中EXPOSE
的端口保持一致。
编写完成,直接运行下面第一条compose命令1
2
3docker-compose up -d # 创建并启动所有服务(常用)
docker-compose build # 容器镜像创建(没启动)
docker-compose stop # 关闭所有服务
此时访问主机的5555端口,即http://your-ip:5555
,即可看到题目👇
查看一下是否实现本地动态flag👇
六、好用的出题镜像
从上面的过程中,我们看到对于一道题目来说,除了源码以外,最大的不方便之处就是还要有相关的一些文件配置。
在这里我推荐virink
写的base_image_nginx_mysql_php_56来辅助我们快速出题。
这个镜像主要好在不需要我们去配置其他的nginx
设置,而且还支持自动导入db.sql
文件,支持自动执行flag.sh
文件。
这里以一道题为例,题目中主要是需要配置数据库.
我们只需要src文件夹
中放入源码
、flag.sh
、db.sql
(文件名不能变),现在我们dockerfile只需要这么写:1
2
3
4
5
6FROM ctftraining/base_image_nginx_mysql_php_56
COPY src /var/www/html
RUN mv /var/www/html/flag.sh / \
&& chmod +x /flag.sh
这个镜像就会自动为我们配置相关的nginx
文件,同时自动导入要执行的db.sql
文件来配置数据库(默认用户为root,密码也为root,执行后db.sql会被删掉)
同时镜像还会自动执行flash.sh
来从环境变量中读取flag写入到flag.php
中(需要注意的是,flag.sh必需在根目录下,也就是我们需要执行mv /var/www/html/flag.sh /
这一步的原因所在)。
可以看到,这个镜像极大的方便了我们对Dockerfile的编写,把Dockerfile简化到只需要两三句话就能搞定。
如果是要在php7
的环境下出题,可以采用base_image_nginx_mysql_php_73
更多docker模板
可前往链接 👉 https://github.com/DASCTF-Test 👈 ,这个docker模板中囊括了很多比赛题目需要的环境,web方面拥有多个版本php mysql的环境,拥有java与python等题目环境,pwn也拥有多个版本的操作系统与题目环境。
如果还想通过更多的环境学习如何出题,可以在这个 👉 项目 👈 中查看更多的题目。