yongz
发布于 2023-11-07 / 0 阅读
0

CTFd 动态 Web 题制作

CTFd 动态 Web 题制作

继上一篇 CTFd 搭建之后,紧接着要部署 Web 题了,这里比较麻烦,不过总会有解决办法的。

个人水平有限,Web 题主要是基于 PHP 语言搭建的,不过市面上大部分 CTF 比赛 PHP 占比还是蛮大的。

本篇文章参考:

1 基础环境说明

1.1 常用镜像

本篇文章所有镜像均采用 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

看名称就知道用途了这里不多赘述,除此之外看个人使用情况,酌情添加。

简单整合的项目,删除了些个人用不到的文件:https://github.com/Y0n9zh/base_image

1.2 统一配置

镜像一般采用两种软件源:

环境变量:

  • 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 生成父镜像。

2 静态 Web 题

本篇文章只涉及 example 目录内容,一般来说 enviroment 目录是不用动的。

2.1 目录结构

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

2.2 文件说明

文件名

说明

docker-compose.yml

docker-compose.yml 文件的作用是定义和配置多容器 Docker 应用程序,用于生成镜像

Dockerfile

Dockerfile 是一个文本文件,用于定义和配置 Docker 镜像的构建过程

files

可执行文件夹

flag.sh

flag 设置脚本

start.sh

需要运行的程序脚本,一般不做修改

src

Web 源码文件夹

index.html

这里是个统称,可放入任意 Web 文件

2.2.1 docker-compose.yml

version: "3"
services:
  challenge:
    build: .
    image: web_http # image name
    ports:
      - "10800:80"
    environment:
      - FLAG=ctfhub{test_flag}

2.2.2 Dockerfile

FROM ctfhub_base/web_httpd

COPY files/flag.sh /flag.sh
COPY files/start.sh /start.sh
COPY src /var/www/html/

2.2.3 flag.sh

#!/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

2.2.4 start.sh

#!/bin/bash
echo start example

2.2.5 index.html

test page <br>
<a href="flag.txt">flag.txt</a>

2.3 使用示例

2.3.1 父镜像创建

Web 题目容器需要先在 enviroment 目录下使用 docker-compose build 生成父镜像:

docker-compose -f enviroment/docker-compose.yml build

2.3.2 子镜像创建

有了父镜像,子镜像也按照相同步骤创建即可:

docker-compose -f example/docker-compose.yml build

2.3.3 CTFd-Web

镜像创建完成了,在 CTFd 上创建个题目,写 docker-compose.yml 中的名字:

image-20231107151257642

开启题目:

image-20231107151224898

BingGo!

image-20231107151534990

3 动态 Web 题(No MySQL)

3.1 目录结构

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

3.2 文件说明

文件名

说明

docker-compose.yml

docker-compose.yml 文件的作用是定义和配置多容器 Docker 应用程序,用于生成镜像

Dockerfile

Dockerfile 是一个文本文件,用于定义和配置 Docker 镜像的构建过程

files

可执行文件夹

flag.sh

flag 设置脚本

start.sh

需要运行的程序脚本,一般不做修改

src

Web 源码文件夹

index.php

这里是个统称,可放入任意 Web 文件

3.2.1 docker-compose.yml

version: "3"
services:
  challenge:
    build: .
    image: web_nginx_php_7.4
    ports:
      - "10800:80"
    environment:
      - FLAG=ctfhub{test_flag}

3.2.2 Dockerfile

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/

3.2.3 flag.sh

#!/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

3.2.4 start.sh

#!/bin/bash
echo start example

3.2.5 index.php

<?php

highlight_file("index.php");
$flag = null;
include_once "/flag_change";

echo "The flag is : ".$flag;

3.3 使用示例

3.3.1 父镜像创建

Web 题目容器需要先在 enviroment 目录下使用 docker-compose build 生成父镜像:

docker-compose -f enviroment/docker-compose.yml build

3.3.2 子镜像创建

有了父镜像,子镜像也按照相同步骤创建即可:

docker-compose -f example/docker-compose.yml build

3.3.3 CTFd-Web

镜像创建完成了,在 CTFd 上创建个题目,写 docker-compose.yml 中的名字:

image-20231107153353975

开启题目:

image-20231107153440902

BingGo!

image-20231107153549717

4 动态 Web 题(MySQL)

4.1 目录结构

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

4.2 文件说明

文件名

说明

docker-compose.yml

docker-compose.yml 文件的作用是定义和配置多容器 Docker 应用程序,用于生成镜像

Dockerfile

Dockerfile 是一个文本文件,用于定义和配置 Docker 镜像的构建过程

files

可执行文件夹

flag.sh

flag 设置脚本

start.sh

需要运行的程序脚本,一般不做修改

src

Web 源码文件夹

db.sql

数据库文件

index.php

这里是个统称,可放入任意 Web 文件

4.2.1 docker-compose.yml

version: "3"
services:
  challenge:
    build: .
    image: web_nginx_php_mysql_5.6
    ports:
      - "10800:80"
    environment:
      - FLAG=ctfhub{test_flag}

4.2.2 Dockerfile

FROM ctfhub_base/web_nginx_mysql_php_5.6

COPY files/flag.sh /flag.sh
COPY src /var/www/html/

4.2.3 flag.sh

#!/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

4.2.4 start.sh

#!/bin/bash
echo start example

4.2.5 db.sql

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');

4.2.6 index.php

<?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);
?>

4.3 使用示例

4.3.1 父镜像创建

Web 题目容器需要先在 enviroment 目录下使用 docker-compose build 生成父镜像:

docker-compose -f enviroment/docker-compose.yml build

4.3.2 子镜像创建

有了父镜像,子镜像也按照相同步骤创建即可:

docker-compose -f example/docker-compose.yml build

4.3.3 CTFd-Web

镜像创建完成了,在 CTFd 上创建个题目,写 docker-compose.yml 中的名字:

image-20231107154544744

开启题目:

image-20231107160403200

BingGo!

image-20231107160350419