继上一篇 CTFd 搭建之后,紧接着要部署 Web 题了,这里比较麻烦,不过总会有解决办法的。
个人水平有限,Web 题主要是基于 PHP 语言搭建的,不过市面上大部分 CTF 比赛 PHP 占比还是蛮大的。
本篇文章参考:
基础环境说明 常用镜像
本篇文章所有镜像均采用 CTFHub 公开的环境基础镜像,主要使用镜像如下:
镜像名称
环境版本
web_httpd
Debian 12 (bookworm) amd64 Apache/2.4.57
web_nginx
Debian 12 (bookworm) amd64 nginx/1.22.1
web_httpd_php_5.6
Debian 9 (stretch) amd64 Apache/2.4.25 PHP 5.6.40
web_httpd_php_7.4
Debian 11 (bullseye) amd64 Apache/2.4.51 PHP 7.4.27
web_httpd_mysql_php_5.6
Debian 9 (stretch) amd64 Apache/2.4.25 PHP 5.6.40 MariaDB 10.1.45-MariaDB-0+deb9u1
web_httpd_mysql_php_7.4
Debian 9 (bullseye) amd64 Apache/2.4.51 PHP 7.4.27 MariaDB 10.5.19-MariaDB-0+deb11u2
web_nginx_php_5.6
Debian 9 (stretch) amd64 nginx/1.10.3 PHP 5.6.40
web_nginx_php_7.4
Debian 11 (bullseye) amd64 nginx/1.18.0 PHP 7.4.27
web_nginx_mysql_php_5.6
Debian 9 (stretch) amd64 nginx/1.10.3 PHP 5.6.40
web_nginx_mysql_php_7.4
Debian 11 (bullseye) amd64 nginx/1.18.0 PHP 7.4.27
统一配置
镜像一般采用两种软件源:
环境变量:
FLAG:设置 flag,如不覆盖 flag.sh 则默认写入到 /flag。
配置文件:
php.ini:/usr/local/etc/php/php.ini
nginx.conf:/etc/nginx/nginx.conf
000-default.conf:/etc/apache2/sites-available/000-default.conf
账号密码:
服务
账号
密码
主机
mysql
root
root
localhost
mysql
web
web
localhost
mysql
web
web
127.0.0.1
mysql
ping
ping
%
数据库文件:
位于 src/db.sql 的数据库文件将在启动时自动导入。
注:所有镜像生成之前,需要先在 enviroment 目录下使用 docker-compose build 生成父镜像。
静态 Web 题
本篇文章只涉及 example 目录内容,一般来说 enviroment 目录是不用动的。
目录结构 1 2 3 4 5 6 7 8 9 10 11 root@docker:/opt/base_image/web_httpd/example# tree . ├── docker-compose.yml ├── Dockerfile ├── files │ ├── flag.sh │ └── start.sh └── src └── index.html 2 directories, 5 files
文件说明
文件名
说明
docker-compose.yml
docker-compose.yml 文件的作用是定义和配置多容器 Docker 应用程序,用于生成镜像
Dockerfile
Dockerfile 是一个文本文件,用于定义和配置 Docker 镜像的构建过程
files
可执行文件夹
flag.sh
flag 设置脚本
start.sh
需要运行的程序脚本,一般不做修改
src
Web 源码文件夹
index.html
这里是个统称,可放入任意 Web 文件
docker-compose.yml 1 2 3 4 5 6 7 8 9 version: "3" services: challenge: build: . image: web_http ports: - "10800:80" environment: - FLAG=ctfhub{test_flag}
Dockerfile 1 2 3 4 5 FROM ctfhub_base/web_httpdCOPY files/flag.sh /flag.sh COPY files/start.sh /start.sh COPY src /var/www/html/
flag.sh 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 # !/bin/bash <<PROMPT 请根据需要自行修改此脚本,确保flag能够放置在正确位置 FLAG 平台传入的正确的flag 将flag写入到文件系统中 # 默认写入/flag write_flag_in_fs # 写入至web目录 /var/www/html/flag.txt write_flag_in_fs /var/www/html/flag.txt PROMPT write_flag_in_fs() { # 将flag写入到文件系统中 if [ -z "$1" ]; then flag_path="/flag" else flag_path="$1" fi echo ${FLAG} > ${flag_path} } write_flag_in_fs /var/www/html/flag.txt export FLAG=not_flag FLAG=not_flag
start.sh 1 2 # !/bin/bash echo start example
index.html 1 2 test page <br > <a href ="flag.txt" > flag.txt</a >
使用示例 父镜像创建
Web 题目容器需要先在 enviroment 目录下使用 docker-compose build 生成父镜像:
1 docker-compose -f enviroment/docker-compose.yml build
子镜像创建
1 docker-compose -f example/docker-compose.yml build
CTFd-Web
镜像创建完成了,在 CTFd 上创建个题目,写 docker-compose.yml 中的名字:
动态 Web 题(No MySQL) 目录结构 1 2 3 4 5 6 7 8 9 10 11 root@docker:/opt/base_image/web_nginx_php_7.4/example# tree . ├── docker-compose.yml ├── Dockerfile ├── files │ ├── flag.sh │ └── start.sh └── src └── index.php 2 directories, 5 files
文件说明
文件名
说明
docker-compose.yml
docker-compose.yml 文件的作用是定义和配置多容器 Docker 应用程序,用于生成镜像
Dockerfile
Dockerfile 是一个文本文件,用于定义和配置 Docker 镜像的构建过程
files
可执行文件夹
flag.sh
flag 设置脚本
start.sh
需要运行的程序脚本,一般不做修改
src
Web 源码文件夹
index.php
这里是个统称,可放入任意 Web 文件
docker-compose.yml 1 2 3 4 5 6 7 8 9 version: "3" services: challenge: build: . image: web_nginx_php_7.4 ports: - "10800:80" environment: - FLAG=ctfhub{test_flag}
Dockerfile 1 2 3 4 5 FROM ctfhub_base/web_nginx_php_7.4 COPY files/flag.sh /flag.sh COPY files/start.sh /start.sh COPY src /var/www/html/
flag.sh 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 # !/bin/bash <<PROMPT 请根据需要自行修改此脚本,确保flag能够放置在正确位置 FLAG 平台传入的正确的flag 将flag写入到文件系统中 # 默认写入/flag write_flag_in_fs # 写入至web目录 /var/www/html/flag.txt write_flag_in_fs /var/www/html/flag.txt PROMPT write_flag_in_fs() { # 将flag写入到文件系统中 if [ -z "$1" ]; then flag_path="/flag" else flag_path="$1" fi echo \<?php \$flag=\"${FLAG}\"\;?\> > ${flag_path} # echo ${FLAG} > ${flag_path} } write_flag_in_fs /flag_change export FLAG=not_flag FLAG=not_flag
start.sh 1 2 # !/bin/bash echo start example
index.php 1 2 3 4 5 6 7 <?php highlight_file ("index.php" );$flag = null ;include_once "/flag_change" ;echo "The flag is : " .$flag ;
使用示例 父镜像创建
Web 题目容器需要先在 enviroment 目录下使用 docker-compose build 生成父镜像:
1 docker-compose -f enviroment/docker-compose.yml build
子镜像创建
1 docker-compose -f example/docker-compose.yml build
CTFd-Web
镜像创建完成了,在 CTFd 上创建个题目,写 docker-compose.yml 中的名字:
动态 Web 题(MySQL) 目录结构 1 2 3 4 5 6 7 8 9 10 11 12 root@docker:/opt/base_image/web_nginx_mysql_php_5.6/example# tree . ├── docker-compose.yml ├── Dockerfile ├── files │ ├── flag.sh │ └── start.sh └── src ├── db.sql └── index.php 2 directories, 6 files
文件说明
文件名
说明
docker-compose.yml
docker-compose.yml 文件的作用是定义和配置多容器 Docker 应用程序,用于生成镜像
Dockerfile
Dockerfile 是一个文本文件,用于定义和配置 Docker 镜像的构建过程
files
可执行文件夹
flag.sh
flag 设置脚本
start.sh
需要运行的程序脚本,一般不做修改
src
Web 源码文件夹
db.sql
数据库文件
index.php
这里是个统称,可放入任意 Web 文件
docker-compose.yml 1 2 3 4 5 6 7 8 9 version: "3" services: challenge: build: . image: web_nginx_php_mysql_5.6 ports: - "10800:80" environment: - FLAG=ctfhub{test_flag}
Dockerfile 1 2 3 4 FROM ctfhub_base/web_nginx_mysql_php_5.6 COPY files/flag.sh /flag.sh COPY src /var/www/html/
flag.sh 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 # !/bin/bash <<PROMPT 请根据需要自行修改此脚本,确保flag能够放置在正确位置 FLAG 平台传入的正确的flag 将flag写入到文件系统中 # 默认写入/flag write_flag_in_fs # 写入至web目录 /var/www/html/flag.txt write_flag_in_fs /var/www/html/flag.txt ----------------- 将flag写入到数据库 # 默认写入web库中flag表的flag字段 write_flag_in_db # 指定库为sqli, 表为user, 列为flag写入 write_flag_in_db sqli user flag PROMPT write_flag_in_fs() { # 将flag写入到文件系统中 if [ -z "$1" ]; then flag_path="/flag" else flag_path="$1" fi echo ${FLAG} > ${flag_path} } write_flag_in_db() { local db_name="${1:-web}" local db_table="${2:-flag}" local db_column="${3:-flag}" echo mysql -uroot -proot -e "update ${db_name}.${db_table} set ${db_column}='${FLAG}';" } write_flag_in_db web flag flag export FLAG=not_flag FLAG=not_flag
start.sh 1 2 # !/bin/bash echo start example
db.sql 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE DATABASE IF NOT EXISTS web;USE web; CREATE TABLE IF NOT EXISTS `news` ( `id` int (10 ) NOT NULL , `data` varchar (20 ) NOT NULL ) ENGINE= MyISAM DEFAULT CHARSET= utf8; INSERT INTO `news` values (1 ,'ctfhub' ), (2 ,'skill' ), (114514 ,'sqli' );CREATE TABLE IF NOT EXISTS `flag` ( `flag` varchar (255 ) NOT NULL ) ENGINE= MyISAM DEFAULT CHARSET= utf8; INSERT INTO `flag` values ('FLAG' );
index.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php error_reporting (0 );$db_host = "localhost" ;$db_user = "web" ;$db_pass = "web" ;$db_name = "web" ;$conn = mysqli_connect ($db_host , $db_user , $db_pass , $db_name );if (!$conn ) { die ("connect error: " . mysqli_connect_error ()); } $sql = "select * from flag" ;$result = mysqli_query ($conn , $sql );$res = mysqli_fetch_array ($result );var_dump ($res );mysqli_close ($conn );?>
使用示例 父镜像创建
Web 题目容器需要先在 enviroment 目录下使用 docker-compose build 生成父镜像:
1 docker-compose -f enviroment/docker-compose.yml build
子镜像创建
1 docker-compose -f example/docker-compose.yml build
CTFd-Web
镜像创建完成了,在 CTFd 上创建个题目,写 docker-compose.yml 中的名字: