使用 docker 搭建可复现的 php 漏洞靶场,核心在于利用官方 `php:apache` 镜像作为基础,通过自定义 dockerfile 将目标代码和依赖注入容器,并配置好数据库服务。具体做法是编写一个包含 from php:8.1-apache 的基础镜像指令,随后使用 copy 命令将本地项目文件复制到 /var/www/html,并通过 docker-compose.yml 编排 web 服务与 mysql 服务的网络通信,确保环境隔离且状态可重置。

如何构建包含特定漏洞代码的 PHP 镜像?
构建镜像的关键在于编写正确的 Dockerfile,重点处理权限问题和依赖安装。以常见的 SQL 注入漏洞为例,我们需要创建一个简单的 index.php 文件,其中包含未过滤的用户输入直接拼接进 SQL 语句的逻辑。在 Dockerfile 中,除了复制文件,还需确保 Apache 用户(通常是 www-data)对写入目录有权限,或者将文件所有权赋予该用户,避免运行时出现 403 错误。

FROM php:8.1-apache # 安装 pdo_mysql 扩展 RUN docker-php-ext-install pdo_mysql # 创建项目目录 RUN mkdir -p /var/www/html/vuln # 复制漏洞代码 COPY index.php /var/www/html/vuln/index.php # 设置权限,确保 www-data 可以读取 RUN chown -R www-data:www-data /var/www/html/vuln # 暴露端口 EXPOSE 80 # 启动 Apache CMD ["apache2-foreground"]
上述代码定义了一个名为 vuln-app 的镜像构建过程。它基于官方的 PHP 8.1 Apache 镜像,安装了必要的 PDO MySQL 扩展以便连接数据库。接着创建了 /var/www/html/vuln 目录并放入了 index.php。最后修改了文件所有者为 www-data,这是 Apache 在 Debian/Ubuntu 系统下运行的默认用户。构建完成后,运行 docker build -t php-vuln . 即可生成镜像。
如何通过 Docker Compose 编排多服务环境?
单靠 Web 镜像无法完成完整的漏洞测试,必须搭配数据库服务。使用 docker-compose.yml 可以同时启动 Web 容器和 MySQL 容器,并通过自定义网络让它们互相发现。在配置中,需要为 MySQL 设置环境变量如 MYSQL_ROOT_PASSWORD 和 MYSQL_DATABASE,并在 Web 容器的入口点或初始化脚本中创建对应的数据表结构,模拟真实的业务场景。
Docker Hub (hub.docker.com)。此技能适用于所有 Docker Hub 操作,包括读取、创建、更新和删除数据。只要任务涉及 Docker Hub,就使用此技能。

version: '3.8'
services:
web:
build: .
ports:
- "8080:80"
depends_on:
- db
environment:
DB_HOST: db
DB_USER: root
DB_PASS: password
DB_NAME: testdb
networks:
- vuln-net
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: testdb
volumes:
- db_data:/var/lib/mysql
networks:
- vuln-net
volumes:
db_data:
networks:
vuln-net:
这个 docker-compose.yml 文件定义了两个服务:web 和 db。web 服务使用当前目录构建的镜像,将宿主机的 8080 端口映射到容器的 80 端口,方便外部访问。它依赖于 db 服务,并通过环境变量传递数据库连接信息。db 服务使用 MySQL 8.0 镜像,设置了根密码和初始数据库名。两者都连接到名为 vuln-net 的自定义网络,使得 web 容器可以通过主机名 db 直接访问数据库服务。这种编排方式确保了环境的完整性和可复现性。
当数据库连接失败时,PHP 应用会返回什么结果?
在排查环境搭建问题时,如果 docker-compose.yml 中的环境变量配置错误或数据库服务尚未完全启动,PHP 应用在尝试连接数据库时会抛出异常或返回特定的错误信息。例如,如果在 index.php 中使用 new PDO() 连接数据库,而 DB_HOST 指向错误的主机或端口不通,程序通常会触发 PDOException。若未进行全局异常捕获,这可能导致页面显示白屏或默认的 Apache 错误页;若进行了简单捕获,则可能输出类似 “SQLSTATE[HY000] [2002] Connection refused” 的错误字符串,这有助于开发者快速定位是网络配置还是服务状态问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










