有趣的Hack-A-Sat黑掉卫星挑战赛——控制卫星载荷任务调度
国家安全在空间领域的具体体现是国家太空安全。随着太空技术在政治、经济、军事以及文化等多个领域中的广泛应用不断扩展,在此背景下,如今太空已成为支撑国家生存与发展的重要资源。它蕴含了重大的国家利益,在此过程中其重要性愈发凸显[1]。而在信息化时代背景下,则展现出其独特的优势与价值:太空安全与信息安全之间存在着密切的关联。
于2020年9月4日发布,《航天政策第5号令》作为一项针对太空网络空间安全的重要政策发布后
题目介绍
准备一个真正温和但又实用的学习指南来掌握cFS和Cosmos系统吧!希望通过这次学习能够为后续工作打下坚实的基础。
启动安装流程:首先运行./setup.sh启动安装程序;其次请确保配置文件已设置好;最后删除Gemfile.lock文件后调用Ruby命令进行安装。
关于Telemetry部分:建议您本地卫星上启用Telemetry服务;而UDP转发器将从那里提供TCP连接给您。
访问挑战页面calendar.satellitesabove.me上的5061端口连接以参与挑战。
从题目描述中可以获取如下信息:
(1)与cFS、COSMOS有关,在下文会有这两个系统的基本介绍。
(2)本题目需要先使能卫星的遥测功能。
(3)包含有两个压缩文件包,在其中一个文件包中嵌入了一个专门定制好的COSMOS版本,并且提供了详细的安装操作指南;解压calendar_hint1.zip后会得到三个文件组别内的多个文档均为JSON格式的文件其具体用途尚不明确后续将对此进行深入分析
cpu1_kit_sch_msg_tbl.json
cpu1_kit_sch_sch_tbl.json
cpu1_kit_to_pkt_tbl.json
此份材料完整涵盖了题目所需的所有信息内容,在获取完整资料的基础上建议安装COSMOS软件以便进一步丰富知识储备
编译及测试
为了验证下载来源代码的有效性, 可以通过编译和测试来实现. 访问/monroe目录位置, 直接进行编译操作, 整体过程较为顺利, 但耗时较长.
sudo make build
采用特定的命令执行测试(见图6-1),并通过查看图6-1的结果可以看到flag值被成功获取。
sudo make test

图6-1 monroe测试结果
相关背景知识
1.COSMOS
CPSMODS(Command and Control of Embedded Systems)是一套功能完善的嵌入式系统管理工具,支持对一系列嵌入式设备和系统的集成控制,包括测试设备如电源模块、示波器等以及开发板如Arduino等。本书采用V5版本作为基础,因此在此教材中我们主要介绍的是CPSMODS V4版本,这是一个基于Web界面的版本,而本挑战题中采用的是一个定制版
该系统采用客户端/服务器(Client/Server, C/S)架构设计,并非基于Web页面的方式。该体系结构在本书第三章有所阐述,在此简要概括: client和server之间的通信机制通过特定协议实现;数据处理能力通过分布式计算框架增强;系统稳定性则依赖于冗余设计和负载均衡算法。为了便于理解本章内容,在此简要概括: client和server之间的通信机制通过特定协议实现;数据处理能力通过分布式计算框架增强;系统稳定性则依赖于冗余设计和负载均衡算法。如图6-2所示
最中间的是一个测控指令型服务端(Command & Telemetry Server),它支持TCP、UDP以及串口等多种接口与卫星、飞行器等不同类型的航天器建立通信联系。
Left upper corner is where real-time commands and script tools are located (Realtime Commanding and Scripting Tools)
上方区域为实时远程遥测显示平台(Realtime Telemetry Visualization Tools)。
(4)左下角是辅助工具,包括配置编辑器(Config Editor)等。
(5)右下角是离线分析工具,包括遥测查看器(Telemetry Viewer)等。

图6-2 COSMOS V4架构
可以通过访问官网获取并下载COSMOS V4的源代码来进行安装。请注意,在本挑战题中使用的COSMOS是由主办方进行过修改和定制的,请注意这一特殊性。为了应对并解答这个挑战题,请严格按照题目要求使用主办方提供的版本,并根据题目指示完成相应的操作步骤。因此需要配置一个 Ubuntu14.04 64bit 的虚拟环境以便完成任务。在此过程中,请参考以下命令以完成必要的软件更新和配置操作:
sudo add-apt-repository ppa:brightbox/ruby-ngsudo apt-get update
sudo apt-get purge --auto-remove ruby
sudo apt update
sudo apt-get install ruby2.6 ruby2.6-dev
sudo gem install bundle
source ~/.bashrc
rm Gemfile.lock
sudo bundle install
然后执行如下安装命令:
./setup.sh source ~/.bashrc rm Gemfile.lock $ bundle install
安装成功后会有如图6-3所示的提示。

图6-3 COSMOS安装成功的提示
当执行该命令时, 程序将启动并显示如图6-4所示的界面. 通过观察该界面可以看出其各个小程序主要依据图6-2中的架构进行分类.
sudo ruby ~/cosmos/tools/Launcher

图6-4 COSMOS主界面
为了模仿主办方设置本挑战题环境的需求,在宿主机上执行以下指令序列:其中IP地址需根据具体情况做相应调整;这些指令的主要目标是启动一个容器,并在其内部部署monroe挑战题服务端。
执行以下操作:以读取模式运行Docker容器并终止其保留状态;设置名为SERVICE_HOST的环境变量为IP地址值192.168.31.43;设置SERVICE_PORT为端口号19021;指定随机种子值为整数序列"zulu49225delta:G1EnNVMK3-hPvlNKAdEJxcujvp9WK4rEchuEdlDp3yv_Wh_uvB5ehGq-fyRowvwkWpdAMTKbidqhK4JhFsaz1k";将映射端口配置为从本地第十九千零二十一端口到数据库第五十四千三百二十一端口;并配置完毕后将启动monroe服务作为挑战任务。
在虚拟机中首先运行如下命令,使用socat做一个端口转发。
socat -d -d TCP-L:54321,fork,reuseaddr TCP:192.168.31.43:19021
启动COSMOS应用程序于虚拟机环境中后,在界面上找到并点击配置编辑器按钮,在随后弹出显示如图6-5所示的配置界面中,请您将远程测控服务器地址设置为本地IP地址127.0.0.1,并指定远程测控服务端口为54321

图6-5 设置COSMOS中遥测服务器地址、端口信息
再次启动COSMOS程序后,在界面上方会出现图6-6的显示区域,并成功显示"COSMOS已成功连接到遥测服务器"的消息提示
选择Tlm Packets选项卡后显示当前观测到的Telemetry数据包数量为零(如图6-7所示),表明未能接收到来自被测对象的Telemetry数据。
文章指出必须首先启动遥测功能。为此,在COSMOS主界面上需点击Command Sender按钮。这将引导至指令发送对话框,请从Target下拉菜单中选择KIT_TO选项。随后,在Command下拉列表中将出现ENABLE_TELEMETRY选项,并被激活以完成配置过程(如图6-8所示)。接着请单击Send按钮并执行此指令;很快接收到了遥测数据包(如图6-9所示),从而实现了卫星的遥测功能。接下来如何进行操作才能获取flag值?

图6-6 COSMOS连接遥测服务器成功

图6-7 遥测数据包接收界面

图6-8 使能遥测功能

图6-9 接收到了遥测数据包
2.cFS
在前文中已经实现了遥测信息发送功能,并且获取了相关信息。然而要最终确认flag是否正确还需要掌握一些基本知识。通过COSMOS的操作界面设置(如命令输入界面中的Target选择列表),如图6-10所示,则能够发现许多具有CFE标记的目标。通过对相关资料的查阅和分析发现,这些与cFS有关,cFS的具体内容可参见3.2.3节中提到的相关内容
3.OpenSatKit
OpenSatKit被称作OSK别名,并整合了COSMOS和cFS,并进行了必要的扩展工作。便于用户通过图6-11直观地了解相关内容。

图6-10 指令发送界面的Target下拉列表

图6-11 OSK的简化组成
从图6-11中可以看出,在该页面上OSK增加了几个应用程序的具体信息展示在图6-11的深色框区域中,并且这些新增的应用程序具有以下功能模块划分、数据管理优化以及流程标准化等特性
- KIT_CI(Kit Command Ingest):负责接收COSMOS发送过来的CCSDS格式指令(如本书前面章节所述),并通过软总线发布这些指令。
- KIT_TO(Kit Telemetry Output):通过软总线读取CCSDS格式遥测数据报(亦称消息),并将这些数据报发送回COSMOS系统。
- KIT_SCH(Kit Scheduler):作为调度机制,在每秒执行一次操作,根据调度表中的指示安排消息发送到软总线上。该机制包含了消息表和调度表两个关键表格。
启用遥测功能时,在配置中设置了Target为KIT_TO和Command为ENABLE_TELEMETRY。这些设置旨在通过修改OSK中的KIT_TO字段值来实现遥测功能的数据接收与传输工作。
在题目所提供的三个文件名称中可以看出这三个文件应与属于KIT_TO和KIT_SCH两个程序相配套的三张表如下
cpu1_kit_sch_msg_tbl.json:KIT_SCH的消息表。
cpu1_kit_sch_sch_tbl.json:KIT_SCH的调度表。
cpu1_kit_to_pkt_tbl.json:KIT_TO的过滤表。
至于如何使用这3张表,在下文将会进一步分析。
题目解析
1.KIT_SCH的消息表
打开cpu1_kit_sch_msg_tbl.json这个JSON文件中包含以下信息其中定义了消息的格式这些信息中包含了典型的CCSDS消息即Coordinate Compression Segment Data Stream消息无需重复介绍相关内容对于解决当前挑战题目而言并不需要深入了解其具体细节
"name": "Scheduler Table Message Table",
"description": [
"Maximum of 32 words per CCSDS message. The first three words are",
"the primary header that must be big endian: ",
"uint16 StreamId; /* packet identifier word (stream ID) */ ",
" /* bits shift description */",
" /* 0x07FF 0 : application ID */",
" /* 0x0800 11 : secondary header: 0 = absent, 1 = present */",
" /* 0x1000 12 : packet type: 0 = TLM, 1 = CMD */",
" /* 0xE000 13 : CCSDS version, always set to 0 */",
"uint16 Sequence; /* packet sequence word */ ",
" /* bits shift description */",
" /* 0x3FFF 0 : sequence count */",
" /* 0xC000 14 : segmentation flags: 3 = complete packet */",
"uint16 Length; /* packet length word */ ",
" /* bits shift description */",
" /* 0xFFFF 0 : (total packet length) - 7 */"
],
在定义完成之后存在一些具体的 msg 值需要注意。其中有一个明确的 msg 值与其相关联,并通过 msg 名称分析表明这应当是被 send 给 Kit_to 的 flag 信息。
{"message": {
"name": "KIT_TO_SEND_FLAG_MID ",
"descr": "Super Secret Flag Sending Telemetry Message",
"id": 42,
"stream-id": 33304,
"seq-seg": 192,
"length": 256
}},
2.KIT_SCH的调度表
打开JSON文件名cpu1_kit_sch_sch_tbl.json后发现其中详细说明了这张表的功能与作用机制。该表格主要阐述了其在系统调度中的核心职责:即在每秒钟内负责调度并执行5个槽位(slots)。每个槽位最多可处理10个活动项(activities),其核心机制是基于该JSON文件中的数据动态地分配和释放计算资源。具体而言,“KIT_SCH”的核心逻辑就是根据这一表格信息,在不同时间点周期性地分配计算资源以支持这些活动项的运行。
name: "Scheduling Activity Timeline",
description: [
".活动被定义为时间段内的事件块,在每一秒中包含五个这样的块。",
".每个时间段包含十个事件条目;该组件表按照应用程序角色进行组织。",
".飞行表则基于实时需求设计。",
".布尔属性采用字符串表示以简化逻辑。",
".FSW解析器使用命名对象来实现回调功能;然而由于命名对象无法作为数组元素(因为它们通常具有动态键),因此它们被放置在方括号中。"
]
举个例子来说吧,第一个槽的内容大概是这样的情况:每一个activity属性里都有一个msg-id字段。需要注意的是这个msg-id应该是与KIT_SCH消息表中的每一个消息ID相对应的。
{"slot": {
"index": 0,
"activity-array" : [
{"activity": {
"name": "cFE ES Housekeeping",
"descr": "",
"index": 0,
"enable": "true",
"frequency": 4,
"offset": 0,
"msg-id": 0
}},
......
{"activity": {
"name": "Time Housekeeping",
"descr": "",
"index": 4,
"enable": "true",
"frequency": 4,
"offset": 0,
"msg-id": 4
}}
]
}},
3.KIT_TO的过滤表
打开cpu1_kit_to_pkt_tbl.json文档,在其开头部分进行了说明:定义了会被该KIT_TO发送的遥测数据包,并指出此处所使用的KIT_TO不具备过滤功能。进一步说明了与flag消息相关的遥测数据包。然而,在本挑战题的解答过程中并未使用此文件。
{
"name": "Telemetry Output Table",
"description": "Define default telemetry packets that are forwarded by KIT_TO.
KIT_TO does not have any filtering capabilities.
Each packet entry contains:
CFE_SB_MsgId_t, CFE_SB_Qos_t (Priority,Reliability), Buffer Limit",
......
"packet": {
"name": "KIT_TO_TLM_FLAG_MID",
"stream-id": "\u0886",
"dec-id": 2182,
"priority": 0,
"reliability": 0,
"buf-limit": 4
},
4.KIT_SCH工作过程分析
OSK官方文档对KIT_SCH的介绍较为简略。要深入理解其运作机制,则需通过代码进行详细分析。获取OSK源码后,在该函数(KIT_SCH_AppMain)内部调用InitApp函数,在该函数内部会依次加载两张消息表和一张调度表——这两张消息表即为我们上文所提的KIT_SCH的消息库与调度框架。具体代码如下:
#define KIT_SCH_DEF_MSG_TBL_FILE_NAME "/cf/kit_sch_msg_tbl.json"
#define KIT_SCH_DEF_SCH_TBL_FILE_NAME "/cf/kit_sch_sch_tbl.json"
......
TBLMGR_RegisterTblWithDef(TBLMGR_OBJ, MSGTBL_LoadCmd, MSGTBL_DumpCmd, KIT_SCH_DEF_MSG_TBL_FILE_NAME);
TBLMGR_RegisterTblWithDef(TBLMGR_OBJ, SCHTBL_LoadCmd, SCHTBL_DumpCmd, KIT_SCH_DEF_SCH_TBL_FILE_NAME);
......
在KIT_SCH_AppMain函数中进行处理后会进入一个循环过程,在此过程中该函数会持续调用SCHEDULER_Execute函数来执行相应的操作步骤。具体而言,在每次调用中SCHEDULER_Execute函数都会依次读取KIT_SCH调度表中的slot定义内容并执行其中所包含的各项activity这些活动的主要操作包括将对应的消息发送至软总线上当相关应用接收到该消息时则会根据需求执行相应的处理流程以完成整个挑战题目的解决目标为此我们需要找到一种方法将KIT_SCH的消息表中的消息KIT_TO_SEND_FLAG_MID插入到KIT_SCH的调度表中使其成为其中一个具体的activity项
5.修改KIT_SCH的调度表的activity
上文已详细阐述了解题思路。借助COSMOS平台,在指令发送界面中,“当Target设置为KIT_SCH时”,存在一条名为LOAD_SCH_ENTRY的指令(如图6-12所示)。将该参数设置为位于KIT_SCH的消息表cpu1_kit_sch_msg_tbl.json中找到的KIT_TO_SEND_FLAG_MID(其值为42),然后单击Send按钮即可完成操作。

图6-12 当Target选择为KIT_SCH,指令可以选择LOAD_SCH_ENTRY
请查看TLM包数据选项卡下的FLAG_TLM_PKT字段(如图6-13所示),然后点击该选项卡上的View in Packet Viewer按钮(如图6-14所示),系统将切换到Packet Viewer窗口并显示相关的flag值信息。

图6-13 选择Tlm Packets选项卡中的FLAG_TLM_PKT

图6-14 显示收到的flag
