基于Docker容器的网络安全实验平台的设计与实现


基于Docker容器的网络安全实验平台的设计与实现

摘要:CTF(Capture The Flag)是常见的网络安全竞赛形式,赛事靶场部署了诸如Reverse、Misc、Crypto等附件类考题与Web、Pwn等容器类考题。若容器类考题是静态部署的,则存在非预期解题的安全隐患。针对这一问题,设计了题目容器化的网络安全实验平台,将容器类的考题动态部署到Docker容器中,实现了容器类考题的动态部署,多用户在不同的容器中对同一试题进行解答,互相隔离,消除了安全隐患。实验平台采用Vue3+Element Plus+Go+MySQL的架构设计,使用Gorm技术连接数据库并进行数据管理。实验平台界面美观,功能齐全,具有较强的可维护性与可扩展性,为参赛练习者提供了考题丰富的安全训练环境。

关键词:网络安全 Docker CTF 竞赛

[TOC]

引言

​ 2024年4月网络空间部队正式成立,标志着我国网络安全建设又迈入了一个新阶段。网络安全已经成为国家安全的重要组成部分,是中国式现代化建设的重要保障^[1]^。网络安全问题内容繁杂,从个人PC到大型企业网络甚至整个广域网,每一个层面都面临着各种不同的安全挑战。防范、化解信息化进程中的安全风险,特别是防止发生系统性、颠覆性风险,是我国网信工作的根本任务^[1]^。

​ 为了培养更多优秀的网络安全人才,网络安全实验平台是网络安全从业者、学生和爱好者进行实验、比赛和训练,提升自身的网络安全技能和知识的不二选择,同时网络安全靶场作为支撑前沿技术研究、网络安全人员培训的重要基础设施,得到各国政府、军队、企业和科研机构的高度重视[2]。但是,网络安全实验平台在使用过程中,因多用户的同时访问造成及对平台环境的渗透与更改,这些操作会影响到其他用户对平台的正常应用。

1 环境与技术介绍

1.1 网络安全实验平台

​ 网络安全平台主要用于网络安全实践和培训,为使用者提供了一个安全的、可供用户自由渗透的靶场环境,这些靶场环境往往与具体安全事件与安全风险对应。

​ 近些年在全球网络安全爱好者的自发贡献下,一批开源的网络安全平台如雨后春笋般出现,产生了如CTFd(Capture The Flag Director)等开源的网络安全实验平台,用于主持和管理CTF(Capture The Flag)竞赛^[3]^。当前免费开放的线上靶场已经有一定数量,大部分网络安全实验平台被高校用于竞赛训练。这些实验平台往往采用静态部署,落后于当前版本,初学者入门CTF门槛相对较高。目前的相关研究工作主要集中在传授式教学场景,借助实验系统辅助实现对特定知识点的教学目标^[4]^。然而,这种方式未能充分关注渗透测试所需的广泛专业知识、多样化的技术手段以及逆向思维突破困难等特点^[4]^。

1.2 CTF

​ CTF是一种经典的网络安全竞赛形式。CTF竞赛测试参与者在解决各种网络安全挑战和应对攻击方面的各项能力,包括团队合作,快速学习乃至经验。在CTF类型的比赛中,多名参赛者独立或者组队解决各种问题,包括安全杂项 MISC(缩写来源于单词miscellaneous)、网络安全Web、逆向工程 Re(缩写来源于单词reverse)、二进制安全 PWN(简称来源于单词安全俚语)、密码学Crypto(缩写来源于单词Cryptography),甚至社会工程学方面的知识和技能。

​ CTF赛事通常设有时间限制,题目的分值通常会随着成功解题次数的增加而降低,在部分比赛中会有长时间未解出题目分值上升的机制。在通常情况下这意味着参与者需要在规定的时间内,尽可能快地完成尽可能多的题目,以得到尽可能高的分数。通常,最终得分是根据参与者所获得的分值来确定排名。

​ 随着“全国大学生信息安全竞赛创新实践能力赛”,“强网杯”等知名网络安全赛事采用CTF竞赛模式,CTF竞赛的吸引力越来越强,在网络安全人才培养中的作用也越来越重要^[5]^。

1.3 Docker

​ Docker是一种通过GO语言开发的应用容器引擎,用于开发、部署应用程序。利用Docker可以将应用程序及其所需的运行环境打包到独立、可移植的Dockerfile中。在任何支持Docker的平台,包括Linux和高版本的windows环境中均可以通过Docker实现从Dockerfile文件到Docker Image的构建。并由此创建可以执行的Docker容器,而无需担心环境配置的问题。

​ 从架构上来说Dockerfile是应用程序的基础,包括源代码及运行环境、库和配置等依赖项。Docker Image是中间件,其由Dockerfile通过构建产生。而Docker容器是应用程序的运行态,是通过Docker Image创建并允许的实例。从软件生命周期的观点上讲,Dockerfile、Docker Image与Docker Container分别代表软件生命周期的三个不同阶段,Dockerfile面向软件生命周期的设计阶段,Docker Image面向软件生命周期的测试阶段,成为应用程序交付标准,Docker Container面向软件生命周期的软件运行和维护阶段。Docker架构如图1-1所示。

图1-1 Docker架构示意图
​ Docker Container中的每个接口都是虚拟的,在实际的部署中应将其映射到服务器或者主机的真实端口上。容器之间要相互通信的前提是两者必须有属于同一个网络的网卡[6]。由此,在基于Docker的网络安全实验平台中,通过Docker Image来创建应用程序的运行实例Docker Container,暨用户实际接触到的靶场环境,彼此之间的资源是相互隔离的。

​ 基于此,网络安全实验靶场就可以生成多个同时运行的Docker Container,而这些实例之间相互隔离,互不影响。这种方式可以实现用户对靶场环境的独占,从而保证了网络安全实验平台的正常运行。

1.4 Vue

​ Vue框架其提供了声明式、组件化的方法用于构建交互式界面。并支持.Vue单文件组件这一前端格式。Vue 3.0提供了许多重大改进和新特性,提高了性能、可维护性和开发体验。通过重新设计虚拟DOM和响应式系统,Vue 3.0能够更高效地追踪状态变化,并在需要时进行更新,从而提高了应用程序的渲染速度和响应性。

​ 其组件功能允许将页面划分为独立的组件,并对每个组件进行单独设计,在Vue3.0组件得到进一步的细化。在Vue3中,借助Prop传递、Mixins混入技术和组合式API,能够实现组件的进一步组合,这意味着可以将一些公共逻辑封装成独立对象,并在多个组件中引入和使用。可以将多个组件组合在一起构建更复杂的用户界面。Vue组件复用如图1-2所示。

图1-2 Vue组件树状结构
​ 即使考虑组件进一步细分产生的更小组件与混入技术的影响,在Vue程序开发中,组件结构依旧被设计为一棵不断嵌套的树。当节点组件需要被调用时,需要在根组件中导入,该组件将会以默认的形式暴露给外部,组件就可以作为独立模块被使用。

1.5 Go

​ Go又称Golang是一种静态强类型、编译型语言。Go其简单高效的特性,旨在解决大型软件项目中面对的一些挑战,如复杂性管理、性能优化和可维护性。在大规模项目中。Go语言具有高效率、并发安全的优势,同时具有足够的表达力和功能性。在网络服务中优势尤为明显,具有广泛的应用前景。

​ Go语言的可维护性也是其优秀特性之一。其强类型系统和严格的编码规范可以帮助开发团队保持代码的清晰和一致性,减少了在维护和扩展项目时可能出现的错误和问题。此外,Go语言还提供了一套丰富的标准库和工具,包括用于测试、文档生成、性能分析等的工具,进一步提升了代码的可维护性和可测试性。

1.6 开发环境

​ 本项目的开发过程中同时使用了HBuilder X和Visual Studio Code两款代码编辑器。分别用于开发项目的前端Vue项目与后端的Go框架与Docker操作模块。

​ VS Code是一款轻量级代码编辑器,支持多种编程语言和文件类型,适用于各种规模的项目和开发环境。其提供了优秀的集成开发环境,包括调试、终端窗口、版本控制等功能。同时有很强的代码分析能力,使得开发过程更加流畅高效。

​ HBuilder X是一款专为Vue打造的一款集成开发环境,能够提供适合Vue项目的开发环境。同时其拥有强大的语法提示功能。

1.7 WangEditor

​ WangEditor是基于JavaScript开发的编辑器,其具有兼容性好,插件化,支持自定义样式等特点。涵盖了各式各样的文本编辑功能,能够为用户提供良好的编写体验,同时可以实现对Markdown语法的兼容,便于常见的Markdown格式内容的转载。由于插件化的特点WangEditor可以集成到各种Web应用中,作为项目的一部分被调用。

2 系统需求分析

​ 本文在参考现有安全企业的网络安全实验平台设计思路与实现的基础上,对网络安全实验平台的功能需求进行分析,并进行了改进。将传统的静态的测试环境与Docker容器进行有机结合,设计了基于Docker容器的动态实现方案。

2.1 功能需求分析

​ 基于现实因素考虑,网络安全实验平台的设计定位于,面向个体和组织的开放训练环境,主要提供针对各种网络安全漏洞场景的目标环境,供个体或组织训练网络安全实践技能[7]。

​ 根据网络安全实验平台的功能分析,网络安全实验平台大致可为两个核心模块与其他通用模块,两个核心模块暨用户功能模块和系统管理员的后台管理模块。为了保证系统信息及系统本身的机密性、完整性与可用性(CIA),管理员和用户身份会有不同的功能权限。通用模块是系统的基础包括登录模块与排行榜等功能。

​ 在系统中,管理员用户负责系统维护,包括发布公告,上传问题,文章管理,问题管理和用户管理等内容,以用户身份登录成功后主要可以进行文章阅读、题目环境申请、作答及发布解题报告等功能。

(1)管理员模块

​ 管理员身份由Computer_Users表中的permissions位进行标记。管理员通过身份验证登录后,在后台对平台进行各种管理。在题目管理中,管理员可以上传新题目、对涉及镜像与容器题目的对应关系进行调整及题目相关信息修改或删除。同时管理员可以对远程服务器中,用户下发的靶机容器进行管理。在用户管理中,管理员可以查看用户的个人信息,进行信息的修改、重置密码、用户删除等功能。管理员同时还具有上传文章、公告及文章管理的能力。

(2)用户模块

​ 本系统用户模块的功能较少,用户可以查看排行榜和其他用户发表的文章,在练习靶场中解答对应题目,发布文章等功能。

2.2 非功能性需求分析

​ 网络安全实验平台不仅包括基本的功能需求,还需要满足一系列非功能性需求,以及对社会和行业的更高层次的需求。非功能性需求指的是系统除了具备功能性需求外,还必须具备的一些性质。具体到网络安全实验平台比如机密性、完整性与可用性等,更进一步网络安全实验平台在网络安全人才培养上也有其需求。网络安全实验平台应当在满足基本功能需求的同时,重视非功能性需求,确保平台具备简单易操作、安全可靠以及准确无误的特点,为用户提供良好的实验体验和数据支持。

​ (1)CIA:网络安全实验平台更需要注重平台的机密性、完整性与可用性,网络安全实验平台对安全的需要同时来自于内部与外部,来自平台外部的威胁包括合法用户的非授权访问和非法用户的渗透攻击。而来自系统内部风险的则是合法用户访问过程及对题目渗透中可能触发的风险溢出。

​ (2)可维护性与可扩展性:为了实现平台的长期可靠运行和后续内容的扩充,网络安全实验平台同样需要不断迭代。所以在设计之时需要对系统进行清晰的设计,使系统架构清晰明了,方便后续扩展和维护。

​ (3)对网络安全技能培养的需要:本系统定位于面向个体和组织的开放训练环境,对网络从业人员及网络安全初学者,包括专业院校学生提供有关网络安全技能全领域的能力培养是网络安全实验平台的出发点。网络安全人才的实际培养过程中,需要用到各种网络环境和大量安全数据来做分析,网络靶场可以方便地提供相关的数据源,为研究对象、实验场景、背景知识做支撑[8]。毫无疑问,CTF比赛的流行及本身具有的趣味性和挑战性,能够作为辅助教学的绝佳平台[9]。在教学中结合CTF的赛题,甚至举办一些校内的CTF竞赛,让学生在比赛中进步,提高其安全实战能力,培养国家需要的应用型人才[9]。

​ (4)性能是软件系统中至关重要的非功能性特性之一,它直接影响着用户体验、系统的可用性以及业务流程的顺畅进行。性能不仅仅关乎系统的响应速度,还包括系统的吞吐量、资源利用率以及并发处理能力等多个方面。网络安全实验平台关于性能的设计主要集中于Docker容器的下发与回收机制。

3 系统设计

​ 针对静态部署的靶场环境存在的问题,本项目设计在靶场题目中使用Docker容器环境的网络安全实验平台。整个网络安全实验平台采用Vue3+Element Plus+Go+MySQL的架构。前端采用Vue3框架,后端则使用Gin框架进行设计开发。同时使用Gorm技术链接数据库,管理系统数据,单独开启一个线程使用Redis作为存入数据库的缓冲。在Web和PWN题目中采用部署在远程服务器上的Docker容器作为题目环境,借助Go语言对Docker操作的便利性实现服务器中Docker实例。

3.1 总体设计

​ 网络安全实验平台由管理员单元、用户单元和通用单元三部分组成。管理员单元的功能主要包括部署新的题目容器、用户管理、文章管理和公告发布等功能。用户单元的功能主要包括注册账号、个人信息维护、在练习场申请实验容器、提交解题思路和发表文章等。通用单元包括排行榜、文章上传和登录注册等功能。此外实验平台后端还负责管理各项用户与平台交互产生的信息、实验容器的分发和回收、与数据库交互以维护平台信息。系统模块功能如图3-1所示。

图3-1 平台模块图
系统采用了分层架构和MVC模式的架构,如图3-2所示
图3-2 系统架构图
#### 3.2 详细设计
3.2.1 登录注册模块设计

​ 由于实验平台实际需要,管理员用户为直接写入数据库,通过注册模块注册的用户均为普通用户。当用户访问实验平台时,可以通过主页引导进入登录页面。用户登录时,系统验证用户名和凭据是否匹配数据库信息,匹配则登录成功,否则返回错误提示。用户登录注册模块的具体流程如图3-3所示。

图3-3 登录注册模块流程图
### 3.2.2 管理员功能模块

(1)发布公告功能

​ 系统使用wangeditor框架的富文本模块进行开发,并且支持代码高亮,字体格式编辑,插入表格,背景色等功能。管理员发布公告后,将会将数据存入数据库Notices表中,并将公告展示在主页中。

(2)文章管理

​ 管理员可以对平台的文章进行搜索、查看、修改、删除等操作。当用户上传文章后,管理员查看用户上传的文章,选择是否发布该文章,并可以设置推荐文章。当文章被设置为推荐文章后,将在平台主页进行展示。文章管理模块的流程如图3-4所示。

图3-4 文章发布流程图
​ 题目管理:管理员端的题目管理包括题目上传及题目管理两部分,题目上传,暨上传题目到实验平台,题目管理可以查看平台目前已有的所有题目信息,并对其修改,删除。由于练习场中部分题目涉及容器模块,题目管理下还包括容器管理部分。由于云服务器依旧空间有限,管理员可以在必要时强行关闭客户开启的靶机容器。题目部署流程如图3-5所示。
图3-5 题目部署流程图
​ 用户管理:管理员可以对用户信息进行操作,包括修改用户信息,重置密码,将用户从数据库中删除等操作,当管理员发现用户积分异常变化时,可以将用户成绩在成绩排行榜中屏蔽。

3.2.3 用户功能

​ 个人信息:用户可以通过个人中心查看、修改个人信息及密码。同时平台统计的各种信息也会展示在用户个人信息中,包括用户知识结构等内容。

​ 文章功能:个人用户和管理员用户均可以发布文章。普通用户发布的文章会直接存入数据库中,但是只有经过管理员审核后批准的才会展示在主页。同时个人用户可以通过个人中心查看自己发布的文章并对其进行修改。在文章模块中用户可以通过关键字进行搜索查看带有该关键字的文章。

3.2.4 练习场及题目设计

​ 主要题目类型包含Web 网络安全、Re 逆向工程、Pwn 二进制漏洞利用、Crypto密码攻击、Mobile 移动安全以及Misc安全杂项等^[10]^,这些内容暨GB/T 42446-2023中K01-003网络安全基础知识及K05-003网络安全威胁和漏洞管理,K05-005渗透测试技术与方法,K05-006网络攻防技术等知识^[11]^。

​ 在本实验平台中,练习场题目分为两种类型,附件型和容器型,附件型题目包括逆向工程、安全杂项、密码学、移动安全等,容器型包括二进制安全和Web安全。用户可以在练习场中进行实验操作,在附件型题目中,用户需要下载附件并在本地解答题目,得到题目Flag之后提交到平台进行验证。在容器型题目中,用户需要申请实验容器、在下发的容器地址中得到题目答案,通过平台提交答案及解题思路等。练习场解题流程如图3-6所示。

img

图3-6 解题流程图
​ 逆向工程Re和二进制安全Pwn两种题目,这两类题目考察参赛者发现和利用软件漏洞的能力。需要解题者具备一定的编程能力和软件测试能力。解题者通过反编译技术将应用程序恢复为伪代码形式,在此基础上分析程序的行为,包括函数逻辑和数据处理流程。以求找到程序中隐藏的漏洞并对其进行利用,来获取必要的系统权限或者窃取敏感信息。

​ 移动安全Mobile是近期备受关注的一个领域,涉及到移动应用程序的安全漏洞甚至移动端系统层漏洞及相应攻防技术。这一类题目可以被视为是逆向工程和二进制安全在移动平台上综合应用。在这类CTF赛题中包括了Android和iOS等平台上的应用程序分析、反编译、漏洞利用等内容。参赛者需要了解移动应用程序的工作原理、移动系统的工作原理以及常见的安全漏洞,并能够对其进行复现和利用。

​ Crypto密码攻击起源于密码学的密码编码学与密码分析学的实际应用,是网络安全领域中的重要分支,涉及到密码学的理论和实践。CTF赛题中的密码学题目包括了从古典密码到非对称加密、国密算法等多个方面的内容,参与者需要运用数学知识和密码学算法来破解加密算法并解密密文。

​ 安全杂项Misc,涵盖了各种与安全相关的各种内容,如电子取证、网络协议分析、社会工程学攻击、隐写术等。网络安全题目类别图如图3-7所示。

图3-7 网络安全题目分类
#### 3.3 数据库设计
3.3.1 概念结构设计

​ 通过系统的需求分析,进行数据抽象,抽象出用户实体、文章实体、题目实体、公告实体、镜像实体和容器实体等六个实体。

​ 文章实体的属性包括文章ID、文章标题、文章类型、文章内容、作者、创建时间和浏览量等,文章实体的E-R图如图3-8所示。

图3-8 文章实体E-R图
​ 用户实体的属性包括用户ID、账号、邮箱、昵称、密码、积分、签名、创建时间、更新时间和权限等,用户实体的E-R图如图3-9所示。

​ 题目实体的属性包括题目ID、问题名、问题描述、问题类型、分值、问题提示、答案、创建时间、更新时间动态答案标志和题目首通用户等,题目实体的E-R图如图3-10所示。

img

图3-9 用户实体E-R图
图3-10 题目实体E-R图
​ 公告实体的属性包括公告ID、标题、作者、公告内容、创建时间和更新时间等,公告实体的E-R图如图3-11所示。
图3-11 公告实体 E-R图
​ 镜像实体的属性包括镜像ID、仓库名称、创建时间和更新时间等,镜像实体的E-R图如图3-12所示。

​ 容器实体的属性包括容器ID、容器名称、容器状态、仓库名称、启动端口、映像端口、剩余时间、创建时间和更新时间等,镜像实体的E-R图如图3-13所示。

图3-12 镜像实体 E-R图
图3-13 容器实体E-R图
​ 用户发布文章和公告,为一对多的联系,同时用户解答题目为多对多的联系。在部分设计镜像的题目中,系统会由题目的附件构建Docker Image,题目与镜像为一对一的联系。通过一个镜像可以构建多个容器,表现为一对多的联系。数据库全局E-R图如图3-14所示

图3-14 数据库全局E-R图
### 3.3.2 逻辑结构设计

​ 在逻辑结构设计中,将概念结构设计阶段得到的E-R图转换为关系模式,本系统转换的各关系模式如下。

(1)用户关系 Computer_Users

​ 用户关系Computer_Users主要存放了系统用户的相关信息,其中id为主键。系统用户包括管理员用户和普通用户,使用Permissions位区分两类用户,Permissions值为1表示为管理员,0位普通用户。Password中并未存放实际用户密码,而是存放密码经过加密后的散列值,详情如表3-1所示。

表3-1 用户数据表 Computer_Users
| 列名 | 数据类型 | null | 默认 | 说明 | | ------------ | ------------- | ---- | ---- | ------------------ | | id | int | 否 | | 主键,用于区分用户 | | Number | varchar (255) | 否 | | 账号 | | Email | varchar (25) | 否 | | 邮箱 | | Nick_Name | varchar (25) | 是 | | 昵称 | | Password | varchar (255) | 否 | | 密码 | | Autograph | varchar (255) | 是 | 0 | 签名 | | Integral | int | 否 | | 积分 | | Create_Time | datetime | 否 | | 创建时间 | | Updated_Time | datetime | 是 | 0 | 更新时间 |

(2)题目关系 Problems

​ 题目关系Problem主要用来存放题目信息,其中包括题目序号、名称、正确答案、问题通过次数、问题提交次数等信息。其中ID是本表的主键。Problem_A_Blood_Id为题目首通用户ID,同时用来标识题目是否有人通过和首通用户。Flag_Bool为题目动态答案标志,默认为0,即固定答案,当Flag_Bool为1表示为动态答案。详细信息如表3-2所示。

表3-2 题目信息表 Problems
| 列名 | 数据类型 | null | 默认 | 说明 | | ------------------ | ------------- | ---- | ---------------- | ------------------ | | id | int | 否 | | 主键,用于区分题目 | | Problem_Name | varchar (255) | 否 | | 问题名 | | Describe | varchar (255) | 否 | | 问题描述 | | Problem_Type | varchar (255) | 否 | 200 | 问题类型 | | Score | varchar (255) | 是 | | 分值 | | Tips | varchar (255) | 是 | | 问题提示 | | Answer | varchar (255) | 否 | | 答案 | | Problem_A_Blood_Id | varchar (255) | 否 | 0 | 题目首通用户ID | | Flag_Bool | varchar (255) | 是 | flag{xxxxxxxxxx} | 动态答案标志 | | Create_Time | datetime | 否 | | 创建时间 | | Updated_Time | datetime | 是 | | 更新时间 |

(3)公告关系 Notices

​ 公告关系Notices主要用来存放公告信息,其中包括公告和其内容。其中序号ID是本表的主键。由于使用了Wangeditor框架开发,通过json流将带有标签和样式的信息存入Content中。其中序号ID是本表的主键。其详细信息如表3-3所示。

表3-3 公告信息表 Notices
| 列名 | 数据类型 | null | 默认 | 说明 | | ------------ | ------------ | ---- | ----- | ------------------ | | id | int | 否 | | 主键,用于区分公告 | | Title | varchar (25) | 否 | Admin | 公共名 | | Author | varchar (25) | 是 | | 作者 | | Content | text | 否 | | 内容 | | Create_Time | datetime | 否 | | 创建时间 | | Updated_Time | datetime | 是 | | 更新时间 | | User_ID | int | 否 | | 用户ID,外键 |

(4)文章关系 Articles

​ 文章关系 Articles用来存放文章信息,包括文章的标题、文章类型、作者、内容等信息,其中序号ID是本表的主键。借助Wangeditor框架通过json流将带有标签和样式的信息存入Content中。Recommend的值初始为0为对应文章的浏览量。详细信息如表3-4所示。

表3-4 文章信息表 Articles
| 列名 | 数据类型 | null | 默认 | 说明 | | --------- | ------------- | ---- | ---- | ------------------ | | id | int | 否 | | 主键,用于识别文章 | | Title | varchar (255) | 否 | | 标题 | | News_Type | varchar (25) | 是 | | 文章类型 | | Author | varchar (25) | 是 | | 作者 | | Content | text | 是 | | 文章内容 | | Time | datetime | 否 | 0 | 创建时间 | | Recommend | int | 是 | | 浏览量 | | User_ID | int | 否 | | 用户ID,外键 |

(5)解题关系 Submit_Problems

​ 解题信息表 Submit_Problems主要用来存放解题记录。其中序号ID是本表的主键,通过User_ID在Computer_Users表中唯一确定一个用户,Problem_ID绑定Problems中的Display,实现唯一对应一道题目,实现用户解题历史的记录。Problem_Submit_Number为提交次数,Problem_Pass为验证,默认为0表示题目还未通过,当值为1时即用户解题成功。通过对表中各条记录的统计可以得到对应题目的提交次数与通过次数。其详细信息如表3-5所示。

表3-5 解题信息表 Submit_Problems
| 列名 | 数据类型 | null | 默认 | 说明 | | --------------------- | ------------- | ---- | ---- | ------------ | | id | int | 否 | | 主键,自增 | | User_Id | int | 否 | | 用户ID,外键 | | Problem_Id | int | 否 | | 题目ID,外键 | | Problem_Submit_Number | varchar (255) | 否 | 1 | 提交次数 | | Problem_Pass | varchar (255) | 否 | 0 | 是否通过 | | Create_Time | datetime | 否 | | 创建时间 | | Updated_Time | datetime | 是 | | 更新时间 |

(6)镜像关系 Image

​ 镜像信息表Image用于存放服务器中的镜像信息,id为其主键,Image_Id为镜像的id,Repository为仓库名称,使用组合式写法即Repository:Tag形式,Problem_Id负责与对应题目绑定。

表3-6 镜像信息表 Image
| 列名 | 数据类型 | null | 默认 | 说明 | | ------------ | ------------- | ---- | ---- | ------------ | | Image_Id | int | 否 | | 镜像ID | | Repository | varchar (255) | 否 | | 仓库名称 | | Create_Time | datetime | 否 | | 创建时间 | | Updated_Time | datetime | 是 | | 更新时间 | | Problem_Id | int | 否 | | 题目ID,外键 |

(7)容器关系 Docker_information

​ 容器关系Docker_information主要用于存放当前启动的容器的相关信息,Docker_ID为主键。Container_Port为服务器对外开放的端口,Port为容器开放端口,实际是要将容器的80端口映射到服务器对外开放的端口上。Container_Status,为容器状态,0表示容器停止,1表示容器正在启动,2为未知状态。Repository为仓库名称,使用组合式写法即Repository:Tag形式,Remaining_time为容器剩余时间,默认为60分钟,用户延时后剩余时间会对应增加。容器信息表详细信息如表3-7所示。

表3-7 容器信息表 Docker_information
| 列名 | 数据类型 | null | 默认 | 说明 | | ---- | -------- | ---- | ---- | ---- | | | | | | |

4 系统实现

4.1 系统登录与注册模块实现

4.1.1 用户登录模块实现

​ 平台在用户没有登录时大部分功能无法正常使用。当点击Header栏登录按钮,会打开登录界面。输入账号并点击继续后,系统会检查账号是否存在。不存在则跳转注册页面,存在则输入密码并在后端进行验证。如果数据库中存在相应用户信息,且密码准确,将登录进入主界面,反之将出现密码错误的弹窗。登录页面如图4-1所示。

关键代码如下:

func Innumber (db *gorm.DB, str string) bool {
  var user model. ComputerUser
  db. Where ("number=?", str). Find(&user)
  if len (user. Number)! = 0 {
     return true}
}

func Check (content, encrypted string) bool {
  return strings. EqualFold (Encode(content), encrypted)
}

func Encode (data string) string {
  h: = md5.New()
  h. Write ([] byte(data))
  return hex. EncodeToString (h. Sum(nil))
}
图4-1系统登录界面
##### 4.1.2 注册页面实现

​ 当点击注册按钮,将跳转到注册页面,通过平台注册界面注册的用户,其Computer_Users表中的Permissions值均为0,为普通用户。对输入数据前端及后端均会进行验证,避免平台数据库受到攻击。用户注册模块页面如图4-2所示。

图4-2 用户注册界面
用户关键代码如下:
func Register (c *gin. Context) {
  DB: = common. GetDB ()
  json: = Username {}
  c.BindJSON(&json)
  md: = Encode (json. Password)
  DB. Create(&newUser)
}

4.2 用户功能模块实现

​ 用户登录后的主页如下图所示,前台会展示管理员选择推荐的文章,和管理员发布的公告。同时用户可以通过主页访问练习场模块和排行榜模块。点击左上角的头像按钮将弹出下拉菜单,普通用户可以由此进入个人中心和文章模块。管理员用户的下拉菜单有所不同,其下拉菜单中包含后台选项,管理员用户可以由此进入系统后台。平台为保证用户有能力解决网络安全相关题目,用户可以通过其他中的访问平台搜集的各种在线工具和资源下载途径。用户主页界面如图4-3所示。

图4-3用户主页界面
##### 4.2.1 练习场模块的实现

​ 此模块在未登录时仅显示题目列表,用户点击不会触发点击事件,无法解答题目,用户在登录后才可以正常解答题目。当用户进入练习场后,可以通过左侧菜单栏按照类别题目类型,右侧会动态展示相应类型的题目。用户点击进入想要解答的题目,之后按照题目要求选择下发靶机环境或者下载附件。当解答完成后,用户将从附件或容器中获取到Flag提交,如果结果正确将显示提交正确,并为账号添加相应题目的分值。在用户不再尝试解题时可以点击按钮关闭当前已下发的靶场环境,后台会自动强制关闭该题目对应容器。题目列表会显示题目的通过人数和提交次数。用户解题成功后会使用红色标注,对于已通过的题目再次解题将不再得分。页面具体展示如图4-4所示。

​ 对于需要启动Docker的题目其流程如下所示:点击下发容器后,系统后台会下发相应容器,容器有一定运行时间限制。当容器运行时间结束时,会提示是否进行延时,如果不进行延时,系统会自动回收Docker容器,如果选择延时,系统将会延长Docker容器的运行时间。同时一个用户只能同时启动一个容器,如果需要启动其他题目,则需要先点击销毁容器,系统会回收相应容器资源。完成解题后将获取到flag后提交,如果结果正确将显示提交正确,并为账号添加相应题目的分数,同时系统会销毁容器并回收相应资源。靶机启动前后如图4-5所示。

图4-4练习场界面
图4-5 Web题目启动前后对比图
​ 由于本地环境的限制,包括存储与计算资源、网络连接以及安全要求等方面的限制,将Docker容器放在本地并不现实。因此为满足平台不断变化需求的需要,更便捷地部署和管理Docker容器,选择将Dockerfile及由此经过构建并运行的Docker Container部署在云服务器上。

​ 本系统在实际实现的过程中将Docker相关内容部署到阿里云服务器上。当前端用户点击下发容器后,后端将相关操作发送给服务器,进而对Docker容器进行操作。容器的下发与回收如图4-6所示。

容器创建的关键代码如下:

func CreateAndStartContainer(g *gin.Context) {
  createImage := request.CreateImageRequest{}
  err := g.ShouldBindJSON(&createImage)
  data, ok := util.VerifyPermissions(createImage.Token, g)

  uid, exists := data["uid"].(string)

  username, _ := data["username"].(string)
  createImage.UserId = uid
  createImage.Username = username
  containerManager, err := common.NewContainerManager()
}

​ 在具体实现过程中,即通过前端点击触发后端接口进而通过云服务器创建容器,并将容器的80端口映射到服务器的开放端口。由于阿里云服务器自带防火墙,会隔绝外部访问,所以需要进行安全组管理,将接口池的30080端口到30880端口设置为测试端口,允许外部IP地址访问。在容器下发完成后,平台用户访问对应题目,即访问远程服务器开放端口。

图4-6容器的下发与回收
##### 4.2.2 文章模块的实现

​ 用户端的文章模块,管理员和用户可以将自己认为有价值的内容上传,也可是上传平台题目解题思路,同时前台将进行展示。文章模块提供搜索功能,可以检索带有关键字的文章。文章模块如图4-7所示。

​ 同时文章模块可以根据Articles库中的id值,将存储在Articles表中的文章信息映射到对应的Article:id页面,进行展示。由于在文章发布模块使用WangEditor,通过json流将带有标签和样式的信息存入Content中。对应文章页面的实现过程与存入过程正好相反,通过json数据流读出数据库Content中的标签及样式信息,写入前端Vue文件中,并对其进行动态渲染,从而实现对应文章的展示。

关键代码如下:

// FindArticle 查询文章

func FindArticle (f *gin. Context) {
  DB: = common. GetDB ()

  title, _: = f. GetQuery("title")

  var cat [] model. Article
  DB. Where ("title LIKE?", "%"+title+"%"). Find(&cat)
}
图4-7文章模块实现
#### 4.3 管理员功能模块实现

​ 安全是“三分技术,七分管理”,网络安全实验平台的长期安全运营,也需要经过实践的检验。系统中管理员功能主要职责为维护网络安全实验平台的正常运行,主要实现信息发布,用户信息管理、文章管理、题目管理、容器管理等功能。

4.3.1 用户信息管理的实现

​ 在该系统后台中管理员不仅可以管理用户账号和用户信息,还能对用户的个人账户密码进行更改,从而保证了系统的正常运行。在特点情况下可以删除用户,如图4-8所示。

图4-8用户信息管理页面
##### 4.3.2 文章管理模块的实现

​ 文章管理功能,包括文章信息管理和文章发布及公共发布,文章发布功能使用wangeditor框架的富文本模块进行开发,将管理员在前端输入内容与样式作为整体存入数据库,文章信息管理则与前面的用户信息管理内容相似。题目上传页面具体内容如图4-9所示。

图4-9 题目上传页面
题目上传代码如下所示:
func ProblemUpload (p *gin. Context) {

  DB: = common. GetDB ()
  var Pr model. Problem
  DB. Where ("display=?", Display). Find(&Pr)
  DB. Create(&NewProblem)

  url: =. /data/file/" + ProblemType + "/"

  err: = os. MkdirAll (url, os. ModePerm)

  file, _: = p. FormFile("file")
  fileStr: = file. Filename

  for j: = len(fileStr); j > 0; j-- {
     if fileStr[j-1] == '.' {
       str: = fileStr[j:]
         fe: = Display + "." + str
         p. SaveUploadedFile (file, url+fe)
         return
     }
  }
}
4.3.3 题目管理模块的实现

​ 题目管理功能,包括题目信息管理和题目上传,管理员通过设置Display ID作为题目的唯一标识符,设置题目类型,答案等信息,后端接收到前端传输的附件或者Dockerfile文件后会将其放在后端的对应位置,并将其根据Display ID进行更名。题目信息管理则与前面的用户信息管理内容相似。题目管理页面具体内容如图4-10所示。

​ 同时由于在Web和Pwn两种类型的题目中使用了Docker容器,管理员模块在题目管理下设一栏容器管理。在容器管理中会显示服务器中目前运行的Docker容器信息,包括容器的IP地址,所占空间,开启用户等。同时由于平台云服务器实际条件的限制,允许管理员可以在后台手动释放用户开启的容器。

图4-10 题目管理页面
#### 4.4 排行榜及积分实现

用户在提交正确的Flag后,用户会获得当前题目的分值,该分值由题目初始分值和题目通过次数与解题次数共同决定。后端会将题目当前的分值添加给用户。排行榜通过统计用户获得的分数对用户进行排名,并将系统内前十的用户成绩展示,排名模块如图4-11所示。

img

图4-11 排行榜模块实现

关键代码如下:

func InquireLeaderboard (i *gin. Context) {
  DB: = common. GetDB ()
  var UserList [] ComputerUser
  DB. Select ([] string{"nick_name","number","integral"}). Limit (10). Order ("integral desc"). Find(&UserList)
  i.JSON (200, gin.H {
  "data": UserList,
  })
}

4.5 题目搜集和整理

​ 由于CTF赛题涉及知识范围广泛,参与者通过这类竞赛能够接触到网络安全的各个领域,从而全面提升网络安全从业人员的技术水平和知识储备。对其中各种网络安全基础知识的掌握是解决相应CTF赛题的关键。这些知识包括了网络协议的原理、反编译技术、密码编码学、常见的渗透方式和加固策略等内容。通过解决与网络安全相关的CTF赛题,参与者可以更加深入地了解网络协议、加解密算法、漏洞利用技术等内容,从而在未来可能面临的网络安全维护中更加熟练地应对各种挑战。

​ 题库搜集过程中详细阅读了从0到1 CTFer成长之路,据此主要围绕附件型题目搜集,覆盖了附件型题目常见知识点,并根据难易程度进行了梯度划分,适合初学者提高网络安全能力。Web题目主要依据白帽子讲Web安全中介绍的常见Web渗透场景及漏洞,用户可以根据自身情况,在不同阶段选择适合自己的不同类型的题目,循序渐进,逐步提升自身能力^[12]^。

5 总结

基于Docker容器的网络安全实验平台,在借鉴了现有网络安全实验平台的设计思路与实现方式的基础上,明确了系统的基本功能模块并进行总体设计,采用 Vue3+Element Plus+Go+MySQL 的架构。同时采用详细的设计保证系统的机密性、完整性与可用性,并设置预留扩展接口,保证平台的可拓展性。

在系统实现后,参考网络安全经典书籍与知识体系收集了大量CTF题目,目前题库中已经上传大量网络安全题目,包括历年各项赛事真题。本系统为网络安全初学者和高校中参加CTF竞赛的学生提供一个在线练习平台。涵盖了Web、Reverse、Misc、Crypto、Pwn等多种类型,涉及知识全面。

同时基于Docker容器的网络安全实验平台尚有些许不足,平台着重于CTF类型的题目,对于新兴的AWD以及AWD plus等比赛形式涉及较少,可考虑后期扩充。

参考文献

[1] 吴世忠.2024年网络与信息安全风险前瞻[J].中国信息安全,2023(12):14-18.

[2] 李伦,王曦,郝志宇.美国网络空间靶场建设情况综述[J].保密科学技术,2021(06):53-60.

[3] 赵静,汤荣秀.网络攻防竞赛平台搭建[J].无线互联科技,2023,20(17):160-162.

[4] 玄世昌,王巍,苘大鹏等.基于虚拟靶场的渗透测试实践教学机制探索[J].高教学刊,2024,10(02):29-32.

[5] 宋晓锋,倪林,韩鹍等.CTF竞赛融入网络安全人才培养过程的探索与实践[J].计算机教育,2021(11):1-5.

[6] 梁建辉,侯昱辉,刘润福等.基于Docker的网络安全靶场设计与实现[J].铁路计算机应用,2022,31(11):67-70.

[7] 刘京菊,王永杰.面向人才培养的网络靶场体系与分类研究[J].保密科学技术,2021(06):18-23.

[8] 王海涛,宋丽华.浅析网络靶场的概念、分类与体系架构[J].保密科学技术,2021(06):4-9.

[9] 刘莉,刘持标,尤垂桔等.结合CTF竞赛的网络安全课程教学改革[J].计算机教育,2019(04):107-111.

[10] 闫梅.基于Docker容器化的Web渗透测试平台实现与应用[J].信息记录材料,2021,22(09):138-140.

[11] GB/T 42446-2023,信息安全技术 网络安全从业人员能力基本要求[S].

[12] 王济昂,朱雨晨,马越等.基于Docker容器化部署的CTF线上靶场系统[J].电子技术与软件工程,2021,(07):210-212.


  目录