找回密码
 立即注册
欢迎中测联盟老会员回家,1997年注册的域名
查看: 1640|回复: 0

【卫星安全系列四】Patch 赛题复现

[复制链接]
发表于 2024-3-1 21:03:56 | 显示全部楼层 |阅读模式

【卫星安全系列四】Patch 赛题复现

 干饭第一名 山石网科安全技术研究院 2023-12-22 10:38 

题目介绍

 We have an encrypted telemetry link from one of our satellites but we seem to have lost the encryption key.Thankfully we can still send unencrypted commands using our COSMOS interface(included).I've also included the last version of kit_to.so that was updated to the satellite.Can you help us restore communication with the satellite so we can see what error "flag" is being transmitted? 

现阶段对题目的描述我们都可以认为是给我们的相关的提示。主要是说加密的密钥丢了,但是我们可以用COSMOS接口来发送未加密的命令。同时主办方还提供了该卫星使用的一个共享文件库kit_to.so,这里要求选手恢复与卫星的通信,其中flag就存在于传输的错误信息当中。

环境搭建

这个题因为用到了COSMOS这个东西,然后题目提供的COSMOS是OpenSatKit2.1套件当中的一部分,为了启动这个cosmos需要一定的环境,这里建议复现的话使用Ubuntu18.04即可,这样环境容易解决一些;

在cosmos下有个INSTALL文件,内容如下

$ ./setup.sh
$ source ~/.bashrc
$ rm Gemfile.lock
$ bundle install 

这里本来按照执行应该是可以直接安装启动cosmos的依赖的,但是可能是版本更替了,Ubuntu的软件源默认安装的跟本题需要的依赖版本不一致导致没办法启动,这里主要是该题目需要cosmos4.4版本的,而该版本的需要用到ruby2.3版本来启动,而现在的Ubuntu18.04 apt 直接安装的已经是2.5版本无法启动,这里使用rvm来安装对应需要的ruby版本,具体命令如下

sudo apt install rvm
rvm list known
rvm install ruby-2.3.8 --disable-stable
rvm use 2.3.8
rvm use 2.3.8 --default 

ruby -v      显示2.3.8即可 

作为上述步骤,可以尝试使用如下命令查看是否能够启动COSMOS的界面

ruby Launcher 

正常启动应该是下面这个界面

图片

但是大概率是不能正常启动的,这个时候使用如下命令来安装对应依赖,不出意外的话应该是不能够直接安装完成的。

bundle install 

这个时候直接去官网 https://rubygems.org,查看安装不成功的依赖,直接找到对应版本进行安装即可。当所有依赖安装完成时即可正常启动cosmos界面

相关背景知识

  1. cFS

cFS(core Flight Software),是NASA公布的框架,其是独立于平台和项目的可重用软件;据说可以节约成本,它主要有四个组件如下

  • core Flight Executive(cFE):核心飞行执行环境
  • Operating System Abstraction Layer(OSAL):操作系统抽象层
  • Platform Support Package(PSP):平台支持组件
  • cFS Applications:cFS应用程序 (这是这道题解题主要用到的)

其中cFS常见的应用如下

应用名称 功能
CFDP(CF) 从/向地面站接收/发送文件
Checksum(CS) 对内存、表和文件进行数据完整性校验
Command Ingest Lab(CI) 通过UDP/IP端口接收CCSDS遥测指令包
Telemetry Output Lab(TO) 发送CCSDS遥测帧
Data Storage(DS) 为下行链路记录板载的星务、工程和科学依据
File Manager(FM) 为地面站提供文件管理界面
House Keeping(HK) 从其他应用程序收集和重新打包遥测数据
Heath and Safety(HS) 确保关键业务、后台服务等正常、检测CPU占用和计算CPU利用率
Limit Checker(LC) 对阈值进行检测,在超出阈值时采取行动
Memory Dwell(MD) 允许地面遥测远程内存位置的内容,主要用于调试
Memory Manager(MM) 提供内存管理和dunp的能力
Software Bus(SB) 通过各种“插件”形式的网络协议船体软件总线消息
Scheduler(SCH) 对板载活动进行调度
Stored Command(Sc) 板载指令序列
  1. COSMOS

建议到官网了解:https://github.com/OpenSatKit/OpenSatKit https://openc3.com/

题目解析

题目主要信息总结如下:

  1. 与COSMOS这个系统有关,解题需要
  2. 题目给与选手两个文件,一个是kit_to.so,另外一个是cosmos.tar.gz,该压缩文件解压是完整的cosmos的目录。

本地复现按照README.md操作即可

sudo make build
sudo make test   <------------测试环境是否成功 

本地复现时,使用如下命令启动挑战镜像

socat -v tcp-listen:19020,reuseaddr exec:"docker run --rm -i -e SERVICE_HOST=172.17.0.1 -e SERVICE_PORT=19021 -e SEED=1 -e FLAG=flag{test} -p 19021\:54321 patch\:challenge" > log 2>&1 & 

然后使用nc指定ip和端口连接即可

图片

这里的打印信息存在一部分指示

Starting up CFS UDP Forwarding Service on tcp:172.17.0.1:19021 Booting... Checking File System... File System Check: ass CFE_PSP: Clearing out CFE CDS Shared memory segment. CFE_PSP: Clearing out CFE Reset Shared memory segment. CFE_PSP: Clearing out CFE User Reserved Shared memory segment. 2033-338-02:06:23.82128 OWER ON RESET due to ower Cycle (Power Cycle). 2033-338-02:06:23.82131 ES Startup: CFE_ES_Main in EARLY_INIT state CFE_PSP: CFE_PSP_AttachExceptions Called 2033-338-02:06:23.82132 ES Startup: CFE_ES_Main entering CORE_STARTUP state 2033-338-02:06:23.82132 ES Startup: Starting Object Creation calls. 2033-338-02:06:23.82132 ES Startup: Calling CFE_ES_CDSEarlyInit 2033-338-02:06:23.82135 ES Startup: Calling CFE_EVS_EarlyInit 2033-338-02:06:23.82135 Event Log cleared following power-on reset 2033-338-02:06:23.82136 ES Startup: Calling CFE_SB_EarlyInit 2033-338-02:06:23.82151 SB internal message format: CCSDS Space acket rotocol version 1 2033-338-02:06:23.82156 ES Startup: Calling CFE_TIME_EarlyInit 1980-012-14:03:20.00000 ES Startup: Calling CFE_TBL_EarlyInit 1980-012-14:03:20.00005 ES Startup: Calling CFE_FS_EarlyInit 1980-012-14:03:20.00009 ES Startup: Core App: CFE_EVS created. App ID: 0 EVS ort1 42/1/CFE_EVS 1: cFE EVS Initialized. cFE Version 6.7.1.0 EVS ort1 42/1/CFE_EVS 14: No subscribers for MsgId 0x808,sender CFE_EVS 1980-012-14:03:20.05038 ES Startup: Core App: CFE_SB created. App ID: 1 1980-012-14:03:20.05043 SB:Registered 4 events for filtering EVS ort1 42/1/CFE_SB 1: cFE SB Initialized EVS ort1 42/1/CFE_SB 14: No subscribers for MsgId 0x808,sender CFE_SB 1980-012-14:03:20.10088 ES Startup: Core App: CFE_ES created. App ID: 2 EVS ort1 42/1/CFE_ES 1: cFE ES Initialized EVS Port1 42/1/CFE_SB 14: No subscribers for MsgId 0x808,sender CFE_ES EVS Port1 42/1/CFE_ES 2: Versions:cFE 6.7.1.0, OSAL 5.0.1.0, PSP 1.4.0.0, chksm 918 EVS Port1 42/1/CFE_SB 14: No subscribers for MsgId 0x808,sender CFE_ES EVS Port1 42/1/CFE_ES 91: Mission osk                    EVS Port1 42/1/CFE_SB 14: No subscribers for MsgId 0x808,sender CFE_ES EVS Port1 42/1/CFE_ES 92: Build 202312050206 root@c564afab4cbd 1980-012-14:03:20.15117 ES Startup: Core App: CFE_TIME created. App ID: 3 EVS Port1 42/1/CFE_TIME 1: cFE TIME Initialized 1980-012-14:03:20.20175 ES Startup: Core App: CFE_TBL created. App ID: 4 EVS Port1 42/1/CFE_TBL 1: cFE TBL Initialized.  cFE Version 6.7.1.0 1980-012-14:03:20.25228 ES Startup: Finished ES CreateObject table entries. 1980-012-14:03:20.25231 ES Startup: CFE_ES_Main entering CORE_READY state
1980-012-14:03:20.25235 ES Startup: Opened ES App Startup file: /cf/cfe_es_startup.scr
1980-012-14:03:20.25249 ES Startup: Loading shared library: /cf/cfs_lib.so
CFS Lib Initialized.  Version 2.2.0.01980-012-14:03:20.25272 ES Startup: Loading shared library: /cf/osk_app_lib.so
1980-012-14:03:20.25318 ES Startup: Loading shared library: /cf/expat_lib.so
EXPAT Library 2.1.0 Loaded
1980-012-14:03:20.25336 ES Startup: Loading file: /cf/kit_to.so, APP: KIT_TO   
1980-012-14:03:20.25345 ES Startup: KIT_TO loaded and created
1980-012-14:03:20.25356 ES Startup: Loading file: /cf/kit_ci.so, APP: KIT_CI  
1980-012-14:03:20.25361 ES Startup: KIT_CI loaded and created
EVS Port1 42/1/KIT_CI 100: KIT_CI Initialized. Version 1.0.0.0
1980-012-14:03:20.25372 ES Startup: Loading file: /cf/kit_sch.so, APP: KIT_SCH 
1980-012-14:03:20.25380 ES Startup: KIT_SCH loaded and created
1980-012-14:03:20.25391 ES Startup: Loading file: /cf/mm.so, APP: MM          
1980-012-14:03:20.25400 ES Startup: MM loaded and created           
EVS Port1 42/1/MM 1: MM Initialized. Version 2.4.1.0
EVS Port1 42/1/KIT_TO 135: Removed 0 table packet entries
EVS Port1 42/1/KIT_TO 122: Loaded new table with 62 packets
EVS Port1 42/1/KIT_TO 15: Sucessfully Replaced table 0 using file /cf/kit_to_pkt_tbl.json
EVS Port1 42/1/KIT_TO 100: KIT_TO Initialized. Version 1.0.0.0
EVS Port1 42/1/KIT_SCH 15: Sucessfully Replaced table 0 using file /cf/kit_sch_msg_tbl.json
EVS Port1 42/1/KIT_SCH 15: Sucessfully Replaced table 1 using file /cf/kit_sch_sch_tbl.json
EVS Port1 42/1/KIT_SCH 101: KIT_SCH Initialized. Version 1.0.0.0
1980-012-14:03:20.30456 ES Startup: CFE_ES_Main entering APPS_INIT state
1980-012-14:03:20.30457 ES Startup: CFE_ES_Main entering OPERATIONAL state
EVS Port1 42/1/CFE_TIME 21: Stop FLYWHEEL
EVS Port1 42/1/KIT_SCH 136: Multiple slots processed: slot = 0, count = 2
EVS Port1 42/1/KIT_SCH 136: Multiple slots processed: slot = 1, count = 2
EVS Port1 42/1/KIT_SCH 134: Major Frame Sync too noisy (Slot 1). Disabling synchronization. 

通过Starting up CFS UDP Forwarding Service on tcp:172.17.0.1:19021了解,这个服务是系统为cFS,且说明了IP地址和端口号;

通过COSMOS的使用说明,可以知道,需要修改cmd_tlm_server.txt文件中的端口号,其位置在cosmos/config/tools/cmd_tlm_server下。主要修改如下

INTERFACE LOCAL_CFS_INT tcpip_client_interface.rb 127.0.0.1 54321 54321 10 nil 

这里两个端口号分别是读写端口,需要修改为题目开头连接的端口号

INTERFACE LOCAL_CFS_INT tcpip_client_interface.rb 127.0.0.1 19021 19021 10 nil 

这里nc连接是19020端口,cosmos连接的是19021端口,这样cosmos发送指令在终端才会有回显

然后使用ruby 启动cosmos的图形化界面

图片

这时候已经成功连接上了题目

在题目回显当中有如下

1980-012-14:03:20.25336 ES Startup: Loading file: /cf/kit_to.so, APP: KIT_TO   
1980-012-14:03:20.25345 ES Startup: KIT_TO loaded and created 

结合文件名字以及cFS和COSMOS的相关知识,猜测KIT_TO可能是cFS中的服务,在COSMOS当中就是Targets界面当中的KIT_TO

图片

然后使用ida对kit_to.so文件进行逆向分析,打开发现其符号表都存在,方便查找,同时题目中说明了flag是存在于传输中的信息当中,所以在ida中直接搜索flag字符串,找到一个flag相关的函数如下

图片

代码很简单,从环境变量中获取flag,环境变量中不存在flag则将flag设置为一个默认值,然后对KitToFlagPkt进行清零,之后用strcpy将flag存放到KitToFlagPkt当中去,很明显如果我们能将KitToFlagPkt的内存dump下来就能得到flag。

注意到回显信息有如下两行

1980-012-14:03:20.25391 ES Startup: Loading file: /cf/mm.so, APP: MM          
1980-012-14:03:20.25400 ES Startup: MM loaded and created  

猜测其中MM对应cFS的服务Memory Manager(MM),其提供内存的dump服务。

找到cosmos的Command Sender操作,其界面如下

图片

这里Target选择为MM服务,Command选择为NOOP发现其有5个固定的参数,所以其他Command操作我们需要从第6个参数开始设置

这里我们需要dump内存,所以Command选择使用PEEK_MEM,其要求参数如下

图片
  • DATA_SIZE:每次读取的字符的比特数,只有8、16、32可选;经过测试,16.32会报错只能选择8
  • MEM_TYPE:读取的内存的类型
  • PAD_16:Structure padding
  • ADDR_OFFSET:在结构体当中偏移量
  • ADDR_SYMBOL_NAME:结构体名称

我们这里只需要找到对应的偏移量即可,应为给的kit_to.so的符号信息都存在,直接ida查看即可

很显然,到这里可以知道不扣掉符号表之类的信息是因为cosmos是通过对应的函数名来以及对应偏移来进行一些指令操作的。


图片


可以看见,flag的偏移量为0xc。如果使用Command Sender的话需要手动多次发送,所以这里借鉴了书上的ruby脚本

12.upto(212) { |off|  offset = off
 cmd("MM PEEK_MEM with CCSDS_STREAMID 6280, CCSDS_SEQUENCE 49152, CCSDS_LENGTH 73, CCSDS_FUNCCODE 2, CCSDS_CHECKSUM 0, DATA_SIZE 8, MEM_TYPE 1, PAD_16 0, ADDR_OFFSET #{offset}, ADDR_SYMBOL_NAME 'KitToFlagPkt'")
}


图片


因为前面我将flag设置为flag{test}所以较短,这里只需要将后面的bits Data转换为字符即可得到flag。

卫星安全 · 目录
上一篇【卫星安全系列三】Leaky Crypto赛题复现下一篇【卫星安全系列五】attitude 赛题复现
写下你的留言
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表