分析ctfd动态web题插件CTFd-Whale

CTFd-Whale 推荐部署实践 – glzjin (zhaoj.in)

一、前置知识

1、docker组网方式

  1. Bridge 网络:Bridge 网络是 Docker 默认的网络类型,它在单个主机上创建一个网络桥接接口,允许容器在同一主机上相互通信。Bridge 网络通常用于开发和测试环境,或者在单个主机上运行多个容器时使用。

  2. Host 网络:Host 网络将容器直接连接到主机的网络栈,使得容器可以直接使用主机的网络资源,如 IP 地址和端口。这种网络类型可以提供更高的网络性能,适用于需要最大化网络性能的场景,但缺乏隔离性。

  3. Macvlan 网络:Macvlan 网络允许容器直接使用主机网络接口的 MAC 地址,使得容器在网络中看起来像是主机的一个物理设备。这种网络类型适用于需要容器直接暴露到物理网络的场景,如需要容器与其他设备进行直接通信的情况。

  4. None 网络:None 网络是一个特殊的网络类型,它不为容器提供任何网络连接。容器在这种网络类型下没有网络接口,因此无法进行网络通信。这种网络类型适用于某些安全性要求较高的场景,或者用于临时禁用容器的网络访问。

  5. Overlay 网络:主要用于在 Docker Swarm 集群中创建跨主机的虚拟网络,使得集群中的容器能够互相通信。每个 overlay 网络在物理网络上创建了一个虚拟网络,其中的容器相互隔离,使得它们可以像在同一局域网中一样通信,而无需了解彼此的物理位置。 Overlay 网络允许 Docker Swarm 集群中的容器在不同的主机上相互通信,使得应用程序可以分布式部署在集群中的不同节点上。Overlay 网络提供了透明的服务发现机制,容器可以通过服务名称而不是 IP 地址来访问其他容器。Swarm 模式会自动管理服务发现,确保容器可以找到彼此。

2、docker 集群

​ Docker 集群是一组由 Docker 引擎组成的分布式系统,用于管理和运行大规模的容器化应用程序。它通过将多个 Docker 主机组织在一 起,实现了容器的自动化部署、扩展和管理。以下是 Docker 集群的一些关键概念和特点:

  1. 集群管理工具: Docker 集群通常由集群管理工具来管理,其中最常用的是 Docker Swarm 和 Kubernetes。这些工具提供了自动化部署、伸缩、负载均衡、容错处理等功能,使得容器的管理变得更加简单和高效。

  2. 节点(Node): Docker 集群中的每个物理或虚拟服务器都称为节点,它们运行着 Docker 引擎并提供容器化应用程序的运行环境。节点可以分为管理节点(Manager Node)和工作节点(Worker Node),管理节点用于管理集群状态和调度任务,而工作节点用于运行容器。

  3. 服务(Service): 在 Docker 集群中,服务是由一个或多个容器组成的应用程序的逻辑单元。服务定义了容器的镜像、运行参数、副本数等信息,并由集群管理工具自动在集群中的节点上部署和运行。

  4. 负载均衡: Docker 集群可以通过负载均衡器(如内置的 Docker Swarm 内部负载均衡器或外部负载均衡器)来分发流量,确保应用程序的高可用性和可伸缩性。

  5. 容器编排: Docker 集群使用容器编排技术来自动管理容器的部署和运行。容器编排包括调度任务、监控容器状态、自动扩展和缩减容器副本等功能,从而实现容器化应用程序的高效运行。

  6. 服务发现: Docker 集群提供了服务发现机制,使得容器之间可以通过服务名称来相互通信,而无需了解彼此的具体网络地址。

  7. 高可用性: Docker 集群具有高可用性特性,可以通过配置多个管理节点和工作节点来实现容错处理,从而确保集群的稳定运行和应用程序的高可用性。

3、docker Python docker库

​ Github地址:docker/docker-py: A Python library for the Docker Engine API (github.com)

​ 库文档:Docker SDK for Python — Docker SDK for Python 7.0.0 documentation (docker-py.readthedocs.io)

​ 使用该库后,可直接在python调用docker实现靶场的开启或者关闭

​ 使用案例:

# 列出docker中image列表
import docker
client = docker.from_env() # 建立连接
client.images.list()

image-20240419213919307

​ 该命令类似于docker images

4、frp工具

​ Frp(Fast Reverse Proxy)是一个轻量级的、高性能的反向代理工具,它提供了简单易用的方式来穿透 NAT 和防火墙,使得内部的服务可以被外部访问。Frp 的主要用途包括内网穿透、端口转发、反向代理等。

​ Github:FRP

重点关注

​ 该工具可以使用api直接控制,比如控制服务热重载、配置文件更新等

热重载 		  [URL]+/api/reload
配置文件更新		[URL]+/api/config

​ 需要配置文件加上

admin_addr = 127.0.0.1 #可定义
admin_port = 7400      #可定义

image-20240419230340884

5、nginx知识

需要知道nginx的一些转发配置

二、分析开始

1、搭建

篇幅限制

2、集群分析

在搭建时 会把frpc的docker放到一个集群中,并且 以后的新建题目 都会放到于frpc的同一个集群中。

3、网络分析

因为在搭建的时候使用的是Overlay 网络模式,所以不能使用ip通讯 但是可以使用容器名称来进行访问。

image-20240419232141889

4、流程分析

当用户点击获取web靶机之后,先获取数据库中该题的的Dokcer储存库名称 比如c3ting/web1 获取结束后调用docker库创建靶机,并把该靶机加入集群和该网络中。 创建结束后,会使用frp的api把该靶机映射出来,映射的地址就是该靶机的名称。 在ctfd启动时 插件会有一个定时5秒的 去判断该靶机是否过期 过期则调用docker库删除靶机

image-20240420001745505

在当中还有一些细节,比如在创建时把创建的信息放到数据库中,方便在后面的定时做判断等。

nginx的作用在与代理转发ctfd的web服务出去到80端口。

5、访问靶场

当用户访问题目时,是直接访问的frps的,在插件中 会自动拼接位置地址返回到ctfd的题目详细中,方便用户一键直达。

image-20240420001147463

三、未来

在AWD中,也可以采取该模式,针对不同赛事生成不一样的 靶机名称即可。 还可以实现每场的动态的flag值,重置环境等。这些指令在python的docker库中都有对应的命令即可实现。

Docker集群的控制方式还有很多种 也是可以值得研究的探讨

再次感谢开源的:

CTFd-Whale 推荐部署实践 – glzjin (zhaoj.in)