docker学习以及CTFD题目发布
发布动态题目要用到docker,所以要先去了解docker是什么
docker
什么是docker
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。Docker是一种轻量级的虚拟化技术,同时是一个开源的应用容器运行环境搭建平台,可以让开发者以便捷方式打包应用到一个可移植的容器中,然后安装至任何运行Linux或Windows等系统的服务器上。相较于传统虚拟机,Docker容器提供轻量化的虚拟化方式、安装便捷、启停速度快。容器完全使用沙盒机制,相互之间不会存在任何接口。几乎没有性能开销,可以很容易地在机器和数据中心运行。
镜像和容器
在Docker中,镜像(Image)和容器(Container)是两个核心的概念:
镜像(Image):镜像是一个只读的模板,可以看作是由多个镜像层叠加起来的一个文件系统。每一层都有一个指针指向下一层,除了最底层。镜像包含运行容器所需的数据,例如程序运行代码和必要环境。你可以把镜像看作类,把容器看作类实例化后的对象。
容器(Container):容器是由镜像实例化而来的运行实例。与镜像相似,唯一的区别在于容器多了一层可读写层。也就是说,容器=镜像+读写层。容器中会运行特定的应用,包含特定应用的代码及所需的依赖文件。
总结起来,简单来说,镜像是文件,容器是进程。容器是基于镜像创建的,即容器中的进程依赖于镜像中的文件。
docker常用命令
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
| docker attach #连接到正在运行中的容器 docker build #使用 Dockerfile 创建镜像 docker commit <容器ID> <你想要新建的镜像名字> #从容器创建一个新的镜像 docker config #管理Docker配置 docker config create #创建配置文件 docker config inspect #查看配置文件信息 docker config ls #显示docker里已经保存得配置文件 docker config rm #删除配置文件 docker container #管理容器 docker container prune #删除所有已停止的容器 docker cp #用于容器与主机之间的数据拷贝 docker create #创建一个新的容器但不启动它 docker exec #在运行的容器中执行命令 docker history #查看指定镜像的创建历史 docker image #管理镜像 docker image inspect #显示一个或多个镜像的元数据 docker image ls #列出本地镜像 docker image prune #删除没有使用的镜像 docker image rm #删除一个或多个镜像 docker image rmi -f <镜像ID> # 强制删除镜像 docker images #列出本地镜像 docker import #从归档文件中创建镜像 docker info #显示 Docker 系统信息,包括镜像和容器数 docker kill #杀掉一个运行中的容器 docker load #导入使用 docker save 命令导出的镜像 docker login #登陆到一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub docker logout #登出一个Docker镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub docker logs #获取容器的日志 docker pause #暂停容器中所有的进程 docker plugin #管理插件 docker plugin create #从rootfs和配置创建一个插件。插件数据目录必须包含config.json和rootfs目录。 docker plugin disable #禁用插件 docker plugin enable #启用插件 docker plugin inspect #显示一个或多个插件的元数据 docker plugin install #安装一个插件 docker plugin ls #列出所有插件 docker plugin push #将插件推送到注册表 docker plugin rm #删除一个或多个插件 docker plugin set #更改插件的设置 docker plugin upgrade #升级现有插件 docker port #列出指定的容器的端口映射,或者查找将PRIVATE_PORT NAT到面向公众的端口 docker ps #列出所有正在运行的容器 docker ps -a #列出所有容器 docker pull #从镜像仓库中拉取或者更新指定镜像 docker push #将本地的镜像上传到镜像仓库,要先登陆到镜像仓库 docker rename #重命名容器 docker restart #重启容器 docker rm #删除一个或多个容器 docker rmi #删除一个或多个镜像 docker run #创建一个新的容器并运行一个命令 docker save #将指定镜像保存成 tar 归档文件 docker search #从Docker Hub查找镜像 docker start #启动一个或多个已经被停止的容器 docker stats #显示容器的实时流资源使用统计信息 docker stop #停止一个运行中的容器 docker tag xxx/xxx yyyy/yyyy # 改标签 x 为别人的 y为自己的 docker top #查看容器中运行的进程信息,支持 ps 命令参数 docker update #更新一个或多个容器的配置 docker version #显示 Docker 版本信息
|
CTFD动态题目发布
首先动态题目需要自定义flag,所以我们的实现思路是先拉取镜像,本地部署后然后在实例里面改相关的配置文件,最后再把该实例转化为镜像push到仓库中,然后使用CTFD的题目发布功能,将该镜像拉取下来构建题目。
这里以litctf中的导弹迷踪题目为例
1 2 3
| docker pull probius/litctf2023:Web_Missile # 首先拉取题目镜像到本地 docker run -d probius/litctf2023:Web_Missile # 新建一个容器用来运行题目镜像(后台运行容器) docker ps # 查看在运行的容器
|
然后得到如下:
1 2
| # 在正在运行的容器(bcf9d8fa6461)中启动一个交互式的sh shell docker exec -it bcf9d8fa6461 /bin/sh
|
找到flag相关的文件,用vi 打开进行编辑
写入我们想要改成的flag
wq保存退出,exit 退出shell
1
| docker commit bcf9d8fa6461 isyang666/mcmcxs2u11:ez_JsGame # 保存修改后的容器为一个新的镜像
|
创建成功了
直接push到docker仓库
1
| docker push isyang666/mcmcxs2u11:ez_JsGame
|
然后用CTFD的题目发布功能将该镜像拉取下来构建题目
发布成功