docker
Docker是什么
在没有Docker之前 如果你要在电脑上跑一个别人写的 CTF Web 题目 要在自己电脑上装一堆符合的环境 Docker 就是一个极其轻量级的“虚拟机”替代方案 两个最核心的概念
镜像 (Image) 它是一个只读的文件,里面打包好了操作系统基础、运行环境(比如 PHP)和题目代码
容器 (Container) 容器是一个隔离的沙箱,题目就在这个沙箱里运行
基础操作
- 镜像
docker images- 作用:查看本地所有镜像(看看你的武器库里都有啥)。
docker search <关键词>- 场景:你想找个现成的靶场,比如输入
docker search sqli-labs,可以直接在终端搜找别人做好的镜像。
- 场景:你想找个现成的靶场,比如输入
docker pull <镜像名:标签>作用:把云端的镜像拉到本地。如果不写标签(冒号后面的部分),默认拉取
latest(最新版)。示例:
docker pull ubuntu:20.04
docker rmi <镜像ID或名字>作用:删除镜像(Remove Image)。
避坑:如果报错说镜像正在被使用,说明有基于它的容器(即使是停止状态的)存在。必须先删容器,再删镜像。
- 容器
docker ps- 作用:查看正在运行的容器。这能帮你快速找到当前开了哪些端口。
docker ps -a- 作用:查看所有容器(包括报错闪退的、已经停止的)。排错时非常有用。
docker stop <容器名/ID>/docker start <容器名/ID>- 作用:优雅地停止/启动容器。
docker rm <容器名/ID>- 作用:删除容器。如果容器还在跑,可以加
-f(force) 强制删除:docker rm -f my_ctf_web。
- 作用:删除容器。如果容器还在跑,可以加
docker logs -f <容器名/ID>- 场景:Web 服务报错误了用这个命令实时追踪容器的后台输出日志,
-f表示持续跟踪不退出
- 场景:Web 服务报错误了用这个命令实时追踪容器的后台输出日志,
docker exec -it <容器名/ID> /bin/bash- 作用:钻进运行中的容器里,获得一个交互式 Shell 进行调试
- 参数
| 参数 | 英文全称 | 说明 | 实用场景/示例 |
|---|---|---|---|
| -d | Detach | 后台运行 | 跑 Web 靶场必加,避免终端被卡住无法执行其他命令 |
| -p | Publish | 端口映射,格式:-p 宿主机端口:容器端口 | 示例:-p 8080:80(将宿主机8080端口映射到容器80端口) |
| –name | Name | 为容器自定义命名 | 示例:–name xiexie(避免系统生成随机难记的容器名) |
| -e | Env | 设置容器内的环境变量 | 示例:-e FLAG=flag{xiexie} |
| -v | Volume | 目录挂载,格式:-v /本地代码目录:/容器内部目录 | 宿主机改代码容器内实时生效,无需反复重启容器 |
| –rm | Remove | 阅后即焚,容器停止后自动销毁 | 适合一次性测试,不残留容器文件、不占用磁盘空间 |
| 4. 核心命令大全 |
| 命令 | 功能 | 示例 |
|---|---|---|
| docker run | 启动一个新的容器并运行命令 | docker run -d ubuntu |
| docker ps | 列出当前正在运行的容器 | docker ps |
| docker ps -a | 列出所有容器(包括已停止的容器) | docker ps -a |
| docker build | 使用Dockerfile构建镜像 | docker build -t my-image . |
| docker images | 列出本地存储的所有镜像 | docker images |
| docker pull | 从 Docker 仓库拉取镜像 | docker pull ubuntu |
| docker push | 将镜像推送到 Docker 仓库 | docker push my-image |
| docker exec | 在运行的容器中执行命令 | docker exec -it 23dfd567926a bash |
| docker stop | 停止一个或多个容器 | docker stop container_name |
| docker start | 启动已经停止的容器 | docker start container_name |
| docker restart | 重启一个容器 | docker restart container_name |
| docker rm | 删除一个或多个容器 | docker rm container_name |
| docker rmi | 删除一个或多个镜像 | docker rmi my-image |
| docker logs | 查看容器的日志 | docker logs container_name |
| docker inspect | 获取容器或镜像的详细信息 | docker inspect container_name |
| docker exec -it | 进入容器的交互式终端 | docker exec -it container_name /bin/bash |
| docker network ls | 列出所有 Docker 网络 | docker network ls |
| docker volume ls | 列出所有 Docker 卷 | docker volume ls |
| docker-compose up | 启动多容器应用(从 docker-compose.yml 文件) | docker-compose up |
| docker-compose down | 停止并删除由 docker-compose 启动的容器、网络等 | docker-compose down |
| docker info | 显示 Docker 系统的详细信息 | docker info |
| docker version | 显示 Docker 客户端和守护进程的版本信息 | docker version |
| docker stats | 显示容器的实时资源使用情况 | docker stats |
| docker login | 登录 Docker 仓库 | docker login |
| docker logout | 登出 Docker 仓库 | docker logout |
如何让科学上网生效 / 配置镜像源
- 配置科学上网 这里略 走魔法代理即可
- 配置国内镜像源 这里在Docker Engine里面修改一下 换成国内镜像源 这里因为买服务器给了一个比较稳定的源 (打脸了 这个其实也不太稳定 最后还是走代理了)
Dockerfile
- Dockerfile 是一个文本文件,包含了一系列用于构建 Docker 镜像的指令 Docker 引擎通过读取这些指令来自动化构建镜像
- Dockerfile常用指令
| 指令 | 说明 |
|---|---|
| FROM | 设置构建镜像时使用的基础镜像 |
| MAINTAINER | 镜像的创建者 |
| RUN | 构建镜像时用于执行后面跟着的命令行命令(在 docker build 时执行) |
| CMD | 类似于 RUN 指令,启动容器时用于执行后面跟着的命令行命令(在 docker run 时执行) |
| ENTRYPOINT | 启动容器时会将其后面的命令当作参数,结合CMD 指令的命令一起执行 |
| COPY | 构建镜像时复制文件或者目录到容器里指定路径 |
| ADD | 功能与COPY指令类似,不同点在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令会自动复制并解压到 <目标路径>,在不解压的前提下,无法复制 tar 压缩文件(推荐使用 COPY指令) |
| ENV | 设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量 |
| ARG | 构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量 |
| VOLUME | 定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷 |
| EXPOSE | 声明端口 |
| WORKDIR | 指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的) |
| USER | 用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在) |
| LABEL | 用来给镜像添加一些元数据(metadata),以键值对的形式 |
| ONBUILD | 用于延迟构建命令的执行。简单的说,就是 Dockerfile 里用 ONBUILD 指定的命令,在本次构建镜像的过程中不会执行(假设镜像为 test-build)。当有新的 Dockerfile 使用了之前构建的镜像 FROM test-build ,这是执行新镜像的 Dockerfile 构建时候,会执行 test-build 的 Dockerfile 里的 ONBUILD 指定的命令 |
| 下面是自己编写的一个最简单的php后门题的Dockerfile |
1 | FROM php:7.4-apache |
.dockerignore
当我们在 Dockerfile 中执行 COPY . /var/www/html/ 时,会把宿主机当前文件夹里的所有文件都塞进容器的 Web 目录 但我如果把自己的exp或者是什么源码之类的一起放上去 选手能直接访问到
.dockerignore作用就在这里 在 Dockerfile 同级目录下创建 .dockerignore 文件 在里面编写好需要忽略的文件 例如
1 | # .dockerignore 示例(注释用 # 开头) |
这里还可以用到匹配 但是出题貌似用的少 现在能力还做不了那么复杂的题
docker-compose.yaml
Dockerfile只可以用来构建单个镜像,在docker-compose.yml文件中,可以定义多个服务,每个服务可以包含一系列配置选项,例如镜像名称、容器端口、环境变量等。
比如在一道题目里面 有前端 后端 加上一个服务之类的 需要手动配置它们相互通信的虚拟网络 还需要run好多次 如果配置文件写好之后 只需要 docker compose up -d 即可全部部署好
例如一个最简单的
builid构建镜像
ports去映射
假设有服务的那种 就比如是sql 文件结构如下
1 | ├── docker-compose.yaml |
文件
1 | services: |
记第一次自己出题
出的题和寒假学习到的一个知识点相关 结合了sqlite的ATTTACH跨库查询 堆叠注入
目录如下
1 | sqlite/ |
- 对dockerfile的要求 run一个sqlite 创目录 然后run两个数据库 一个是正常业务 一个是flag 对正常业务有读写 对flag数据库设权为444 还有就是Web 目录和 Flag 目录不可写 防止直接加上马RCE了
- 对前端 这里比较重要的是ai优化了非预期解 输出都经过
htmlspecialchars()净化 - 对后端核心漏洞也就是直接拼接字符串 但是需要此库无任何有价值数据 需要跨库查询
自己打打啦 具体文件就不放了


