ARTICLE / 安全

低轨卫星互联网安全取证深度分析

低轨卫星互联网(Low Earth Orbit Satellite Internet)是指部署在距地面200至2000公里轨道上的卫星星座系统,通过数千乃至数万颗卫星的协同组网,为全球用户提供低延迟、高带宽的互联网接入服务。与传统地球同步轨道(GEO)卫星通信系统不同,LEO卫星星座具有传播延迟低(单向延迟约20-40ms)、路径损耗小、终端设备小型化等显著优势,已广泛应用于偏远地区宽带接入、海事通信、航空Wi-Fi、军事通信和应急响应等领域。以SpaceX的Starlink星座为例,截至2026年已在轨运行超过7000颗卫星,服务覆盖全球70多个国家和地区,日活用户数突破500万。

近年来,LEO卫星互联网面临的安全威胁日益严峻,多起公开安全事件引起了国际社会的高度关注。2022年,乌克兰Starlink终端遭受俄罗斯电子战干扰和信号欺骗攻击,SpaceX被迫紧急推送固件更新以增强抗干扰能力;2023年,安全研究人员在Starlink用户终端(User Terminal)中发现了可通过JTAG接口提取固件并绕过DRM保护的硬件漏洞(CVE-2022-46169);2024年,安全社区披露了针对OneWeb和Telesat地面站基础设施的供应链攻击向量;2025年,多家安全厂商报告了针对卫星通信管理平面的APT攻击活动,攻击者利用卫星网管系统漏洞实现对卫星波束指向和频谱资源的操控。此外,信号劫持(Signal Hijacking)、星间链路窃听、卫星固件篡改等新型攻击技术不断涌现,给传统网络安全取证带来了前所未有的挑战。

LEO卫星互联网安全取证面临的核心挑战在于:攻击面横跨太空段(Space Segment)、地面段(Ground Segment)和用户段(User Segment)三个物理隔离域;星地链路采用定制化通信协议(如DVB-S2X、CCSDS标准),传统网络取证工具难以直接解析;卫星遥测数据和日志分散在地面站、网管系统和终端设备中,需要多源关联分析;取证证据保全需要考虑空间环境特殊性,包括卫星过顶时间窗口有限、终端物理访问困难等因素。本文将系统性地构建LEO卫星互联网安全取证的完整方法论,从星地链路协议分析、地面站入侵取证、终端固件逆向、频谱异常检测到管理平面安全评估,结合公开案例和自动化检测工具,为安全从业者提供一套可实操的卫星通信安全取证指南。


0x01 技术基础与LEO卫星互联网架构概述

1.1 LEO卫星星座架构

LEO卫星互联网系统由三大核心段组成,每一段都包含独立的安全边界和攻击面。

架构组件功能描述典型代表安全关键性
太空段(Space Segment)在轨卫星节点,负责信号中继与星间路由Starlink V2 Mini、OneWeb Gen2🔴极高
地面段(Ground Segment)地面网关站(Gateway)、网关控制站(GCS)、卫星操作中心(SOC)SpaceX Gateway、OneWeb teleport🔴极高
用户段(User Segment)用户终端设备(CPE/UT),包括固定式和移动式终端Starlink Dishy McFlatface、Starlink Mini🟡高
核心网段(Core Network)核心路由、网管系统(NMS)、编排调度系统SpaceX NOC、卫星调度中心🔴极高

LEO星座的轨道特性决定了其安全模型与传统卫星通信系统的根本差异:

  • 高速移动性:卫星轨道速度约7.5km/s,单颗卫星过顶时间约5-15分钟,终端需要频繁进行波束切换(Handover)和卫星切换(Satellite Handoff)
  • 星间链路(ISL):采用激光星间链路实现卫星间数据中继,形成太空Mesh网络,支持跨区域数据传输
  • 动态波束成形:通过相控阵天线实现灵活波束指向,波束切换间隔约数秒级
  • 软件定义卫星:新一代LEO卫星支持在轨软件更新,攻击面从传统硬件扩展到软件层
# 使用Satellite Tracker工具获取当前可见LEO卫星信息
# 安装: pip install orbital-trackpredict
python3 -c "
from orbital_trackpredict import predict
satellites = predict.get_visible_satellites(
    latitude=39.9042, longitude=116.4074,
    min_elevation=10,
    tle_file='stations.txt'
)
for sat in satellites:
    print(f'{sat.name}: Az={sat.azimuth:.1f}° El={sat.elevation:.1f}° Range={sat.range:.0f}km')
"

1.2 通信协议栈

LEO卫星互联网采用分层通信协议栈,每一层都存在独特的安全风险和取证分析需求。

协议层功能协议/标准取证关注点
物理层射频调制解调DVB-S2X、CCSDS、自定义OFDM信号特征分析、频谱异常检测
链路层帧封装与差错控制CCSDS TC/TM、AOS帧注入、重放攻击
网络层星地路由与寻址IPv6、定制路由协议路由劫持、地址欺骗
传输层端到端数据传输TCP/UDP over Satellite中间人攻击、会话劫持
应用层网管与控制SNMP、NETCONF、gRPC管理平面入侵、配置篡改
# 使用Wireshark的DVB-S2 dissector解析卫星链路流量
# 需要安装wireshark-plugin-dvbs2
tshark -r satellite_capture.pcap -Y "dvbs2" -T fields \
  -e dvbs2.modcod -e dvbs2.frame_type -e dvbs2.payload_length \
  -e dvbs2.plscodes -e dvbs2.bch_err_count 2>/dev/null

# 提取卫星链路中的IP流量进行分析
tshark -r satellite_capture.pcap -Y "ip.addr == 10.0.0.0/8 && dvbs2" \
  -T fields -e frame.time -e ip.src -e ip.dst -e tcp.port \
  -e udp.port -e dvbs2.modcod > satellite_ip_analysis.csv

1.3 取证工具链

LEO卫星互联网安全取证需要结合传统网络取证工具和卫星通信专用分析工具:

工具类别工具名称用途适用取证场景
频谱分析GNU Radio + UHD软件定义无线电信号采集与分析频谱干扰检测、信号欺骗识别
协议分析Wireshark + DVB-S2 Plugin卫星链路协议解析链路层取证、协议异常检测
固件分析Binwalk + Ghidra卫星终端固件逆向固件篡改检测、后门分析
网络探测Nmap + Masscan地面站基础设施扫描攻击面发现、服务指纹识别
日志分析ELK Stack地面站与网管系统日志聚合入侵痕迹关联、时间线重建
流量捕获tcpdump + PF_RING高速网络流量采集地面站流量审计、数据渗出检测
固件取证Firmwalker + FirmAnalyzer固件文件系统提取与分析敏感信息泄露、凭证提取
信号分析Inspectrum + SigMF射频信号可视化与分析信号欺骗取证、调制异常检测
# 搭建LEO卫星取证分析环境(Ubuntu 22.04+)
sudo apt update && sudo apt install -y \
  wireshark tshark \
  gnuradio \
  binwalk \
  nmap masscan \
  ghidra \
  python3-pip

pip3 install --user \
  scapy \
  pyelftools \
  capstone \
  keystone-engine \
  unicorn \
  satellite-js

# 安装GNU Radio DVB-S2模块
sudo apt install -y gr-dvbs2
# 或从源码编译
# git clone https://github.com/akosinern/gr-dvbs2.git
# cd gr-dvbs2 && mkdir build && cd build
# cmake .. && make -j$(nproc) && sudo make install && sudo ldconfig

0x02 星地链路协议安全分析与中间人攻击检测

2.1 星地链路通信模型

LEO卫星星地链路(Satellite-to-Ground Link)采用时分多址(TDMA)或频分多址(FDMA)接入方式,上行链路(Uplink)和下行链路(Downlink)使用不同频段。以Starlink系统为例,用户终端使用Ku频段(10.7-12.75GHz下行、14.0-14.5GHz上行)与卫星通信,地面网关使用Ka频段(17.7-21.2GHz下行、27.5-31.0GHz上行)与卫星中继。

链路类型频段带宽通信方向安全风险等级
用户上行(UL)Ku/Ka500MHzUT → Satellite🔴高
用户下行(DL)Ku/Ka500MHzSatellite → UT🟡中
网关上行Ka1GHzGateway → Satellite🔴高
网关下行Ka1GHzSatellite → Gateway🟡中
星间链路V波段/激光多GbpsSatellite ↔ Satellite🔴高

星地链路的中间人攻击(Man-in-the-Middle)可发生在多个位置:

攻击位置攻击手段技术复杂度检测难度影响范围
用户终端侧信号劫持、协议注入🟡中🟡中单用户
星地链路中段射频中继、信号重放🔴高🔴极高区域性
地面网关侧网关入侵、路由篡改🔴高🟡中区域性
核心网侧BGP劫持、DNS投毒🟡中🟡中全网

2.2 DVB-S2X协议层攻击分析

DVB-S2X(Digital Video Broadcasting - Satellite - Second Generation Extensions)是当前LEO卫星系统广泛采用的物理层和链路层标准。协议的开放性使得攻击者可以在协议层面实施多种攻击。

攻击类型MITRE ATT&CK攻击原理检测特征
帧注入攻击T1557.003构造合法DVB-S2帧格式注入卫星链路帧头CRC异常、PLSCODE不匹配
ModCod欺骗T1557.002伪造低阶调制编码格式降低链路性能突发ModCod降级、吞吐量异常
帧同步干扰T1561.002干扰帧同步序列导致接收端失锁帧同步丢失频率异常升高
重放攻击T1557截获并重放合法卫星帧帧计数器回退、时序异常
长度攻击T1557.003篡改帧长度字段导致解调失败帧长度分布异常、CRC错误率升高
# 使用GNU Radio捕获卫星下行信号进行DVB-S2X协议分析
# 创建GNU Radio流图捕获脚本
cat > dvbs2_capture.py << 'PYEOF'
#!/usr/bin/env python3
from gnuradio import gr, blocks, dvb
import numpy as np

class dvbs2_capture(gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self, "DVB-S2X Capture")
        samp_rate = 2.4e6
        center_freq = 11720e6
        self.source = blocks.ufd_source(
            device_addr="type=b200",
            stream_args=gr.stream_args("fc32"),
            center_freq=center_freq,
            samp_rate=samp_rate,
            gain=40
        )
        self.fft_sink = blocks.probe_signal_vc(1024)
        self.file_sink = blocks.file_sink(
            gr.sizeof_gr_complex, "/tmp/satellite_capture.raw"
        )
        self.connect(self.source, self.fft_sink)
        self.connect(self.source, self.file_sink)

if __name__ == '__main__':
    tb = dvbs2_capture()
    tb.start()
    import time
    time.sleep(60)
    tb.stop()
    tb.wait()
PYEOF
python3 dvbs2_capture.py

# 分析捕获的信号频谱特征
python3 << 'PYEOF'
import numpy as np
from scipy import signal

data = np.fromfile('/tmp/satellite_capture.raw', dtype=np.complex64)
f, t, Sxx = signal.spectrogram(data, fs=2.4e6, nperseg=4096)
peak_freq = f[np.argmax(np.mean(Sxx, axis=1))]
bandwidth = f[Sxx.mean(axis=1) > Sxx.mean().max() * 0.5].ptp()
print(f"Peak frequency offset: {peak_freq:.0f} Hz")
print(f"Estimated signal bandwidth: {bandwidth:.0f} Hz")
print(f"Mean power: {10*np.log10(np.mean(np.abs(data)**2)):.1f} dBFS")
PYEOF

2.3 星地链路中间人攻击检测

检测星地链路中间人攻击需要结合物理层信号分析和协议层一致性验证。攻击者在射频层面实施的中间人攻击会引入可测量的信号特征变化,包括传播延迟异常、信号功率波动和多径效应特征改变。

#!/usr/bin/env python3
import time
import struct
import hashlib
from collections import deque

class StarlinkLinkIntegrityChecker:
    def __init__(self, window_size=1000):
        self.latency_window = deque(maxlen=window_size)
        self.throughput_window = deque(maxlen=window_size)
        self.crc_error_window = deque(maxlen=window_size)
        self.alerts = []

    def check_round_trip_delay(self, timestamp_send, timestamp_recv, sat_id):
        rtt = (timestamp_recv - timestamp_send) * 1000
        self.latency_window.append(rtt)
        if len(self.latency_window) >= 100:
            mean_rtt = sum(self.latency_window) / len(self.latency_window)
            std_rtt = (sum((x - mean_rtt) ** 2 for x in self.latency_window) / len(self.latency_window)) ** 0.5
            if rtt > mean_rtt + 3 * std_rtt:
                self.alerts.append({
                    'type': 'RTT_ANOMALY',
                    'severity': 'HIGH',
                    'satellite': sat_id,
                    'rtt': rtt,
                    'baseline_mean': mean_rtt,
                    'baseline_std': std_rtt,
                    'timestamp': time.time(),
                    'attack_vector': 'T1557 - Adversary-in-the-Middle'
                })
                return True
        return False

    def check_throughput_consistency(self, bytes_transferred, interval_sec, expected_throughput_mbps):
        actual_throughput = (bytes_transferred * 8) / (interval_sec * 1e6)
        self.throughput_window.append(actual_throughput)
        if len(self.throughput_window) >= 50:
            recent_avg = sum(list(self.throughput_window)[-10:]) / 10
            if actual_throughput < expected_throughput_mbps * 0.3:
                self.alerts.append({
                    'type': 'THROUGHPUT_DEGRADATION',
                    'severity': 'MEDIUM',
                    'actual_mbps': actual_throughput,
                    'expected_mbps': expected_throughput_mbps,
                    'degradation_ratio': actual_throughput / expected_throughput_mbps,
                    'timestamp': time.time(),
                    'attack_vector': 'T1561.002 - Disk Wipe (Signal Degradation)'
                })
                return True
        return False

    def check_crc_error_rate(self, total_frames, crc_errors):
        error_rate = crc_errors / total_frames if total_frames > 0 else 0
        self.crc_error_window.append(error_rate)
        if len(self.crc_error_window) >= 20:
            baseline_rate = sum(self.crc_error_window) / len(self.crc_error_window)
            if error_rate > baseline_rate * 5 and error_rate > 0.01:
                self.alerts.append({
                    'type': 'CRC_ERROR_SPIKE',
                    'severity': 'HIGH',
                    'current_rate': error_rate,
                    'baseline_rate': baseline_rate,
                    'total_frames': total_frames,
                    'timestamp': time.time(),
                    'attack_vector': 'T1498 - Network Denial of Service'
                })
                return True
        return False

    def generate_report(self):
        report = {
            'total_alerts': len(self.alerts),
            'high_severity': len([a for a in self.alerts if a['severity'] == 'HIGH']),
            'medium_severity': len([a for a in self.alerts if a['severity'] == 'MEDIUM']),
            'alerts': self.alerts
        }
        return report

checker = StarlinkLinkIntegrityChecker()
for i in range(100):
    checker.check_round_trip_delay(time.time(), time.time() + 0.035, "SAT-001")
report = checker.generate_report()
print(f"Link integrity check complete: {report['total_alerts']} alerts")

0x03 地面站(Gateway)安全审计与入侵取证

3.1 地面站架构与攻击面

LEO卫星地面站(Gateway)是连接卫星网络与互联网骨干网的核心枢纽,通常部署在数据中心或专用设施内,包含射频前端(RF Frontend)、基带处理单元(BBU)、网络路由交换设备和卫星网管系统(NMS)。地面站的安全态势直接决定了整个卫星网络的数据安全和服务可用性。

地面站组件功能常见设备/软件典型漏洞类型
射频前端(RFE)信号收发与变频LNB、BUC、ODU固件后门、未授权访问
基带处理(BBU)信号调制解调Newtec MDM、iDirect认证绕过、缓冲区溢出
路由交换设备数据转发与路由Cisco ASR/Juniper MXBGP劫持、ACL绕过
网管系统(NMS)卫星资源管理自研Web系统、SNMPSQL注入、XSS、RCE
卫星监控系统遥测遥控TMTC系统命令注入、权限提升
传输设备地面回传DWDM、SDH信号窃听、中间人攻击

3.2 地面站网络渗透测试

对地面站进行安全审计需要系统性地识别和验证各层攻击面:

# 阶段1:地面站网络资产发现
# 使用Nmap进行全端口扫描和服务识别
nmap -sS -sV -O -p- \
  --script=banner,ssl-cert,http-title \
  -T4 \
  -oX gateway_scan.xml \
  -oN gateway_scan.txt \
  192.168.100.0/24

# 阶段2:SNMP安全审计(卫星网管常用协议)
# 枚举SNMP社区字符串
snmpwalk -v2c -c public 192.168.100.1 1.3.6.1.2.1.1
snmpwalk -v2c -c private 192.168.100.1 1.3.6.1.2.1.1

# 检查SNMP MIB中的卫星设备信息
snmpwalk -v2c -c public 192.168.100.1 1.3.6.1.4.1 2>/dev/null | \
  grep -E "satellite|gateway|modem|frequency"

# 阶段3:NETCONF/YANG配置审计
# 卫星设备常用NETCONF管理
python3 -c "
import xml.etree.ElementTree as ET
from ncclient import manager

with manager.connect(
    host='192.168.100.1',
    port=830,
    username='admin',
    password='admin',
    hostkey_verify=False
) as m:
    config = m.get_config(source='running').data_xml
    root = ET.fromstring(config)
    for elem in root.iter():
        if 'satellite' in elem.tag.lower() or 'frequency' in elem.tag.lower():
            print(f'{elem.tag}: {elem.text}')
" 2>/dev/null

# 阶段4:Web管理界面安全测试
# 使用ffuf进行目录和参数枚举
ffuf -u http://192.168.100.10/FUZZ \
  -w /usr/share/wordlists/dirb/common.txt \
  -mc 200,301,302,403 \
  -o web_enum.json -of json

# 测试SQL注入
ffuf -u "http://192.168.100.10/api/satellite?id=FUZZ" \
  -w /usr/share/seclists/Fuzzing/special-chars.txt \
  -mr "error|warning|syntax" \
  -o sqli_test.json -of json

3.3 地面站入侵取证

当地面站确认遭受入侵后,取证分析需要覆盖多个层面:

# 地面站Linux服务器取证脚本
#!/bin/bash
EVIDENCE_DIR="/forensics/gateway_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$EVIDENCE_DIR"/{memory,network,filesystem,logs}

# 内存取证
echo "[*] Capturing memory dump..."
sudo dd if=/proc/kcore of="$EVIDENCE_DIR/memory/kcore.raw" bs=1M 2>/dev/null
sudo cp /proc/meminfo "$EVIDENCE_DIR/memory/meminfo.txt"
# 使用LiME获取完整内存镜像
sudo insmod lime.ko "path=$EVIDENCE_DIR/memory/memdump.lime format=lime"

# 网络状态快照
echo "[*] Capturing network state..."
ss -tlnp > "$EVIDENCE_DIR/network/listening_ports.txt"
ss -tanp > "$EVIDENCE_DIR/network/all_connections.txt"
ip route > "$EVIDENCE_DIR/network/routes.txt"
ip addr > "$EVIDENCE_DIR/network/interfaces.txt"
sudo iptables -L -v -n > "$EVIDENCE_DIR/network/iptables.txt"
# 捕获ARP缓存
arp -an > "$EVIDENCE_DIR/network/arp_cache.txt"

# 进程快照
echo "[*] Capturing process information..."
ps auxwww > "$EVIDENCE_DIR/filesystem/processes.txt"
ls -la /proc/*/exe 2>/dev/null > "$EVIDENCE_DIR/filesystem/proc_exe.txt"
ls -la /proc/*/cmdline 2>/dev/null > "$EVIDENCE_DIR/filesystem/proc_cmdline.txt"

# 文件系统时间线
echo "[*] Building filesystem timeline..."
find / -xdev -type f -printf '%T+ %m %u:%g %p\n' 2>/dev/null | \
  sort > "$EVIDENCE_DIR/filesystem/timeline.txt"

# 日志收集
echo "[*] Collecting logs..."
for logfile in /var/log/syslog /var/log/auth.log /var/log/secure \
  /var/log/messages /var/log/audit/audit.log; do
  if [ -f "$logfile" ]; then
    cp "$logfile" "$EVIDENCE_DIR/logs/"
  fi
done
# 卫星网管系统日志
find /var/log/ -name "*.log" -newer /etc/hostname -exec \
  cp {} "$EVIDENCE_DIR/logs/" \; 2>/dev/null

# 计算所有取证证据的哈希值
echo "[*] Computing evidence hashes..."
find "$EVIDENCE_DIR" -type f -exec sha256sum {} \; > "$EVIDENCE_DIR/evidence_hashes.txt"
echo "[+] Forensics collection complete: $EVIDENCE_DIR"

3.4 地面站常见入侵指标

入侵指标检测方法取证证据严重程度
异常SNMP查询SNMP日志分析查询频率突增、非工作时间查询🟡高度可疑
未授权NETCONF会话连接日志审计异常源IP、异常用户名🔴确认恶意
网管系统Web Shell文件完整性检查新增PHP/JSP文件、Web目录变更🔴确认恶意
BGP路由异常路由表快照比对非预期路由条目、AS路径篡改🔴确认恶意
卫星命令注入TMTC日志审计非授权波束切换、频率变更🔴确认恶意
异常数据外传流量分析大量上行数据、异常目标IP🟡高度可疑
SSH暴力破解auth.log分析大量失败登录、来源IP集中🟡高度可疑
定时任务篡改cron配置检查新增crontab条目、异常执行路径🔴确认恶意

0x04 卫星终端(User Terminal)固件取证与逆向分析

4.1 卫星终端硬件架构

LEO卫星用户终端(User Terminal, UT)是用户接入卫星互联网的端侧设备,以Starlink Dish为代表,集成了相控阵天线、射频模块、基带处理芯片和网络接口。终端固件的安全性直接关系到用户数据安全和整个卫星网络的稳定性。

组件模块典型芯片/方案功能固件存储位置
应用处理器BCM2711/定制SoC主控、网络协议栈eMMC/SD卡
基带处理器SpaceX定制ASICDVB-S2X调制解调SPI Flash
射频收发器定制RFICKu/Ka频段收发内部寄存器
相控阵控制FPGA/ASIC波束成形控制SPI Flash
安全模块TPM/Secure Element密钥存储、安全启动安全芯片

4.2 固件提取方法

卫星终端固件提取是取证分析的第一步,通常采用以下几种方法:

提取方法技术手段难度适用场景风险等级
JTAG调试接口J-Link/OpenOCD🟡中已知调试引脚布局可能触发DRM
SPI Flash读取CH341A/Flashrom🟡中外置Flash芯片物理拆解
UART串口USB-TTL适配器🟢低已知串口引脚
eMMC拆焊热风枪+读卡器🔴高BGA封装存储器不可逆操作
软件提取OTA固件包抓取🟢低固件更新通道未加密无物理接触
JTAGulator自动引脚识别🟡中未知PCB布局中等
# 方法1:通过OTA更新通道获取固件
# 使用mitmproxy拦截Starlink终端的固件更新请求
mitmproxy --mode transparent \
  --set upstream_cert=false \
  -w starlink_traffic.cap \
  --listen-port 8080 &

# 配置终端代理后监控固件更新流量
tcpdump -i eth0 port 8080 -w proxy_capture.pcap

# 从捕获的流量中提取固件包
python3 << 'PYEOF'
import re

def extract_firmware_from_pcap(pcap_path):
    with open(pcap_path, 'rb') as f:
        data = f.read()
    magic_patterns = [
        b'UBI#',        # UBI filesystem
        b'hsqs',        # SquashFS
        b'\x7fELF',     # ELF binary
        b'MTD',         # MTD partition header
    ]
    offsets = []
    for magic in magic_patterns:
        pos = 0
        while True:
            idx = data.find(magic, pos)
            if idx == -1:
                break
            offsets.append((idx, magic.decode('ascii', errors='replace')))
            pos = idx + 1
    return offsets

results = extract_firmware_from_pcap('proxy_capture.pcap')
for offset, magic in results:
    print(f"Found {magic} at offset 0x{offset:08x}")
PYEOF

# 方法2:JTAG接口固件提取
# 使用JTAGulator识别调试引脚
python3 -c "
from serial.tools.list_ports import comports
for port in comports():
    print(f'Port: {port.device}, Description: {port.description}')
"

# 使用OpenOCD连接并转储Flash
openocd -f interface/jlink.cfg \
  -c 'transport select jtag' \
  -f target/stm32f4x.cfg \
  -c 'adapter speed 1000' \
  -c init \
  -c 'reset halt' \
  -c 'flash read_bank 0 /forensics/firmware_dump.bin' \
  -c shutdown

4.3 固件逆向分析

提取固件后,逆向分析需要对固件进行解包、文件系统提取和二进制分析:

# 使用Binwalk解包固件镜像
binwalk -e firmware_update_v2024.1.bin --directory /tmp/firmware_extract

# 提取文件系统
sudo unsquashfs -d /tmp/squashfs-root firmware.squashfs

# 查找敏感文件和配置
find /tmp/squashfs-root -type f \( \
  -name "*.conf" -o -name "*.cfg" -o -name "*.key" -o \
  -name "*.pem" -o -name "*.crt" -o -name "passwd" -o \
  -name "shadow" -o -name "*.sh" -o -name "authorized_keys" \
\) -exec ls -la {} \; 2>/dev/null

# 搜索硬编码凭证
grep -rn "password\|passwd\|secret\|key\|token\|api_key" \
  /tmp/squashfs-root/etc/ \
  --include="*.conf" --include="*.cfg" --include="*.json" \
  2>/dev/null | head -50

# 搜索嵌入的私钥
find /tmp/squashfs-root -type f -exec grep -l "BEGIN.*PRIVATE KEY" {} \; 2>/dev/null

# 使用Ghidra headless模式进行自动化逆向分析
analyzeHeadless /tmp/firmware_analysis \
  -import /tmp/squashfs-root/usr/bin/satellite_modem \
  -postScript ghidra_satellite_analysis.py \
  -scriptPath /forensics/scripts \
  -deleteProject

# Ghidra脚本:识别卫星通信相关函数
cat > /forensics/scripts/ghidra_satellite_analysis.py << 'PYEOF'
from ghidra.program.model.symbol import SymbolType
from ghidra.app.decompiler import DecompInterface

program = getCurrentProgram()
listing = program.getListing()
func_mgr = program.getFunctionManager()

keywords = [
    'encrypt', 'decrypt', 'authenticate', 'modem',
    'frequency', 'beam', 'handover', 'telemetry',
    'command', 'update', 'firmware', 'download',
    'upload', 'connect', 'disconnect', 'key_exchange'
]

functions = func_mgr.getFunctions(True)
suspicious = []
for func in functions:
    name = func.getName().lower()
    for kw in keywords:
        if kw in name:
            suspicious.append({
                'name': func.getName(),
                'address': func.getEntryPoint(),
                'size': func.getBody().getNumAddresses(),
                'keyword_match': kw
            })
            break

with open('/tmp/suspicious_functions.json', 'w') as f:
    import json
    json.dump(suspicious, f, indent=2)
print(f"Identified {len(suspicious)} suspicious functions")
PYEOF

0x05 频谱干扰与信号欺骗攻击取证

5.1 频谱攻击分类

频谱干扰与信号欺骗是针对LEO卫星系统最直接的物理层攻击手段,尤其在军事冲突和地缘政治对抗场景中频繁出现。这类攻击的取证分析需要专业的软件定义无线电(SDR)工具和信号处理技术。

攻击类型MITRE ATT&CK攻击原理检测方法取证难度
压制式干扰T1561.002发射大功率噪声信号淹没合法信号频谱能量监测🟡中
欺骗式干扰T1557.002发射仿真合法信号诱导终端锁定信号特征比对🔴高
跳频干扰T1561.002跟踪跳频图案进行瞄准干扰跳频序列分析🔴高
协议层干扰T1561在协议层注入错误帧协议一致性检测🟡中
互调干扰T1561.002利用非线性器件产生互调产物频谱互调分析🟢低

5.2 频谱异常检测系统

建立频谱异常检测系统是频谱攻击取证的基础设施。该系统需要持续监测卫星通信频段的频谱特征,并在检测到异常时自动采集和标记证据。

#!/usr/bin/env python3
import numpy as np
from scipy import signal
from collections import deque
import time
import json

class SpectrumAnomalyDetector:
    def __init__(self, center_freq=12e9, bandwidth=500e6, num_bins=4096):
        self.center_freq = center_freq
        self.bandwidth = bandwidth
        self.num_bins = num_bins
        self.freq_axis = np.linspace(
            center_freq - bandwidth/2,
            center_freq + bandwidth/2,
            num_bins
        )
        self.baseline_psd = None
        self.psd_history = deque(maxlen=100)
        self.anomaly_log = []

    def calibrate_baseline(self, baseline_samples):
        psd_list = []
        for sample in baseline_samples:
            f, psd = signal.welch(sample, fs=self.bandwidth, nperseg=self.num_bins)
            psd_list.append(psd)
        self.baseline_psd = np.mean(psd_list, axis=0)
        self.baseline_std = np.std(psd_list, axis=0)
        print(f"Baseline calibrated with {len(baseline_samples)} samples")

    def detect_jamming(self, current_psd):
        if self.baseline_psd is None:
            return False
        noise_floor = np.median(self.baseline_psd)
        current_floor = np.median(current_psd)
        power_ratio = current_floor / noise_floor
        if power_ratio > 3.0:
            self.anomaly_log.append({
                'type': 'JAMMING_DETECTED',
                'power_increase_db': 10 * np.log10(power_ratio),
                'timestamp': time.time(),
                'severity': 'CRITICAL'
            })
            return True
        freq_deviation = np.abs(current_psd - self.baseline_psd)
        max_deviation_bins = np.where(freq_deviation > 3 * self.baseline_std)[0]
        if len(max_deviation_bins) > self.num_bins * 0.3:
            self.anomaly_log.append({
                'type': 'WIDEBAND_JAMMING',
                'affected_bins': len(max_deviation_bins),
                'percentage': len(max_deviation_bins) / self.num_bins * 100,
                'timestamp': time.time(),
                'severity': 'CRITICAL'
            })
            return True
        return False

    def detect_spoofing(self, current_psd, current_signal):
        if self.baseline_psd is None:
            return False
        peak_freq_idx = np.argmax(current_psd)
        baseline_peak_idx = np.argmax(self.baseline_psd)
        freq_offset = abs(self.freq_axis[peak_freq_idx] - self.freq_axis[baseline_peak_idx])
        if freq_offset > 1e6:
            self.anomaly_log.append({
                'type': 'FREQUENCY_SPOOFING',
                'freq_offset_hz': freq_offset,
                'expected_freq': self.freq_axis[baseline_peak_idx],
                'detected_freq': self.freq_axis[peak_peak_idx] if peak_freq_idx else 0,
                'timestamp': time.time(),
                'severity': 'HIGH'
            })
            return True
        _, autocorr = signal.correlate(current_signal, current_signal, mode='full'), None
        autocorr = signal.correlate(current_signal, current_signal, mode='full')
        autocorr = autocorr[len(autocorr)//2:]
        autocorr = autocorr / autocorr[0]
        periodic_peaks = []
        for i in range(1, len(autocorr) - 1):
            if autocorr[i] > autocorr[i-1] and autocorr[i] > autocorr[i+1] and autocorr[i] > 0.8:
                periodic_peaks.append(i)
        if len(periodic_peaks) > 2:
            self.anomaly_log.append({
                'type': 'SPOOFED_SIGNAL_DETECTED',
                'periodic_peaks': len(periodic_peaks),
                'timestamp': time.time(),
                'severity': 'HIGH'
            })
            return True
        return False

    def generate取证报告(self):
        report = {
            'detection_period': {
                'start': self.anomaly_log[0]['timestamp'] if self.anomaly_log else time.time(),
                'end': self.anomaly_log[-1]['timestamp'] if self.anomaly_log else time.time()
            },
            'total_anomalies': len(self.anomaly_log),
            'jamming_events': len([a for a in self.anomaly_log if 'JAMMING' in a['type']]),
            'spoofing_events': len([a for a in self.anomaly_log if 'SPOOFING' in a['type']]),
            'critical_events': len([a for a in self.anomaly_log if a['severity'] == 'CRITICAL']),
            'anomalies': self.anomaly_log
        }
        return report

detector = SpectrumAnomalyDetector(center_freq=11.72e9, bandwidth=500e6)
baseline = [np.random.randn(4096) * 0.01 for _ in range(50)]
detector.calibrate_baseline(baseline)
print("Spectrum anomaly detector initialized")

5.3 频谱攻击取证流程

频谱攻击的取证流程需要遵循严格的证据链管理,确保射频证据的法律效力:

取证步骤操作内容工具/方法证据类型
1. 环境建立部署SDR采集设备、校准天线USRP B210/X310 + GPSDO设备校准记录
2. 基线采集在无干扰环境下采集正常信号特征GNU Radio + SigMF频谱基线数据
3. 异常检测实时频谱监测与异常告警自研检测系统异常事件日志
4. 信号采集在异常期间全带宽采集IQ数据USRP + NVMe高速存储IQ原始数据
5. 信号分析分析干扰信号特征和来源Inspectrum + MATLAB信号分析报告
6. 定位溯源利用多站到达时间差(TDOA)定位多站协作TDOA系统干扰源坐标
7. 证据固化哈希计算、签名、证据链文档sha256sum + GPG签名证据链文档
# 使用USRP进行IQ数据采集并保存为SigMF格式
python3 << 'PYEOF'
import uhd
import numpy as np
import time
import json
import hashlib

def collect_iq_evidence(output_path, duration_sec=30, sample_rate=25e6, center_freq=11.72e9):
    usrp = uhd.usrp.MultiUSRP("type=b200")
    usrp.set_rx_rate(sample_rate)
    usrp.set_rx_freq(center_freq)
    usrp.set_rx_gain(40)
    num_samples = int(sample_rate * duration_sec)
    buffer_size = 4096
    all_samples = np.zeros(num_samples, dtype=np.complex64)
    for i in range(0, num_samples, buffer_size):
        samples = usrp.recv(buffer_size, timeout=5.0)
        all_samples[i:i+len(samples)] = samples
    all_samples.tofile(output_path)
    sigmf_metadata = {
        "global": {
            "core:datatype": "cf32_le",
            "core:sample_rate": sample_rate,
            "core:version": "0.0.1",
            "core:recording": "LEO_Satellite_Evidence"
        },
        "captures": [{
            "core:sample_start": 0,
            "core:frequency": center_freq,
            "core:time": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
        }],
        "annotations": []
    }
    meta_path = output_path + ".sigmf-meta"
    with open(meta_path, 'w') as f:
        json.dump(sigmf_metadata, f, indent=2)
    with open(output_path, 'rb') as f:
        sha256 = hashlib.sha256(f.read()).hexdigest()
    evidence_record = {
        'file': output_path,
        'sha256': sha256,
        'sample_rate': sample_rate,
        'center_freq': center_freq,
        'duration': duration_sec,
        'collection_time': time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
    }
    print(f"IQ evidence collected: {output_path}")
    print(f"SHA256: {sha256}")
    return evidence_record

evidence = collect_iq_evidence(
    "/forensics/spectrum/iq_capture_20260719.raw",
    duration_sec=30,
    sample_rate=25e6,
    center_freq=11.72e9
)
print(json.dumps(evidence, indent=2))
PYEOF

# TDOA多站定位分析
python3 << 'PYEOF'
import numpy as np

def tdoa_localize(station_coords, tdoa_measurements, c=3e8):
    n_stations = len(station_coords)
    reference = station_coords[0]
    A = np.zeros((n_stations - 1, 2))
    b = np.zeros(n_stations - 1)
    for i in range(1, n_stations):
        A[i-1, 0] = station_coords[i][0] - reference[0]
        A[i-1, 1] = station_coords[i][1] - reference[1]
        d_ref = np.linalg.norm(reference)
        d_i = np.linalg.norm(station_coords[i])
        b[i-1] = tdoa_measurements[i-1] * c + 0.5 * (d_i**2 - d_ref**2)
    x, residuals, rank, sv = np.linalg.lstsq(A, b, rcond=None)
    return x

stations = [
    (39.9042, 116.4074, 50),
    (31.2304, 121.4737, 30),
    (23.1291, 113.2644, 40)
]
tdoa = [1.2e-6, 3.5e-6]
location = tdoa_localize(stations, tdoa)
print(f"Estimated jammer location: {location[0]:.4f}°N, {location[1]:.4f}°E")
PYEOF

0x06 卫星网络管理平面与控制平面安全分析

6.1 管理平面架构

LEO卫星网络的管理平面(Management Plane)负责卫星星座的运行管理,包括卫星姿态控制、波束资源分配、频率协调、用户接入控制和计费管理等功能。管理平面的安全性直接关系到整个卫星网络的可控性。

管理功能协议/接口安全机制常见风险
卫星遥测遥控(TMTC)CCSDS TM/TCAES-256加密+HMAC命令注入、遥测篡改
波束管理gRPC/NETCONFTLS+证书认证波束劫持、资源耗尽
用户接入认证RADIUS/DiameterEAP-AKA'认证绕过、会话劫持
频率管理SNMP v3AuthPriv安全级别社区字符串泄露
软件更新分发HTTPS+Code SigningRSA/ECDSA签名固件篡改、降级攻击
计费系统RADIUS/自研协议内网隔离+加密费用欺诈、数据泄露

6.2 控制平面安全评估

控制平面(Control Plane)承载卫星网络的路由信息、信令数据和资源调度指令,是卫星网络安全的核心。控制平面攻击可导致大面积服务中断甚至卫星失控。

# 卫星网络BGP安全审计
# 监控卫星网关的BGP路由变化
sudo tcpdump -i eth0 -w bgp_capture.pcap port 179 &
BGP_PID=$!

# 使用BGPStream分析路由异常
python3 << 'PYEOF'
import pybgpstream

stream = pybgpstream.BGPStream(
    from_time="2026-07-19 00:00:00",
    until_time="2026-07-19 23:59:59",
    record_type="updates",
    collectors=["route-views2"]
)

suspicious_prefixes = []
for rec in stream.records():
    for elem in rec:
        if elem.type == 'A':
            prefix = elem.fields['prefix']
            as_path = elem.fields['as-path']
            origin_as = as_path.split()[-1]
            satellite_asns = ['AS14593', 'AS14633']
            if origin_as in satellite_asns:
                suspicious_prefixes.append({
                    'prefix': prefix,
                    'as_path': as_path,
                    'origin_as': origin_as,
                    'timestamp': elem.time,
                    'type': 'ROUTE_HIJACK_SUSPECT'
                })

if suspicious_prefixes:
    print(f"Found {len(suspicious_prefixes)} suspicious route announcements")
    for sp in suspicious_prefixes:
        print(f"  {sp['prefix']} via {sp['as_path']}")
PYEOF

# 卫星网络SNMP管理安全审计
# 枚举卫星管理MIB
snmpbulkwalk -v2c -c public 10.0.0.1 \
  1.3.6.1.4.1.44967 \
  -On 2>/dev/null | head -100

# 检查SNMPv1/v2c的不安全配置
python3 << 'PYEOF'
import subprocess
import re

community_strings = ['public', 'private', 'admin', 'satellite', 'gateway',
                     'starlink', 'operator', 'nms', 'default', 'test']

results = []
for community in community_strings:
    cmd = f'snmpget -v2c -c {community} 10.0.0.1 1.3.6.1.2.1.1.1.0'
    proc = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=5)
    if proc.returncode == 0 and 'No Such' not in proc.stdout:
        results.append({
            'community': community,
            'response': proc.stdout.strip(),
            'status': 'VULNERABLE',
            'risk': 'SNMP community string guessable'
        })

for r in results:
    print(f"[VULN] Community '{r['community']}' accepted: {r['response']}")
PYEOF

6.3 管理平面入侵痕迹分析

管理平面入侵通常会在多个系统中留下痕迹,需要进行跨系统关联分析:

日志来源关键字段入侵指标检测规则
TMTC系统日志command_code, timestamp, source_ip非授权命令执行命令白名单比对
NMS操作日志operator_id, action, target_resource异常时间操作基线行为偏离
RADIUS认证日志user_name, nas_ip, result暴力破解、异常位置频率阈值告警
BGP路由日志prefix, as_path, timestamp路由劫持ROA验证失败
固件分发日志version, hash, target_satellite降级攻击版本单调性检查
数据库审计日志query, user, rows_affected数据泄露大量查询告警

0x07 卫星通信加密链路验证与异常检测

7.1 卫星通信加密体系

LEO卫星通信系统的加密体系覆盖多个通信链路,每个链路采用不同的加密策略和密钥管理机制:

加密链路加密协议密钥管理密码算法取证关注点
用户数据加密IPsec/DTLSIKEv2密钥协商AES-256-GCM密钥交换异常
管理通道加密TLS 1.3X.509证书ECDHE+AES-256证书伪造、降级攻击
遥测遥控加密CCSDS SLS地面预置密钥AES-256-CCM密钥泄露、重放攻击
星间链路加密自研协议卫星间密钥协商未公开(推测ECDH)链路窃听
用户认证EAP-AKA'SIM卡密钥Milenage算法克隆攻击、SIM劫持

7.2 加密链路异常检测

即使无法解密卫星通信数据,仍然可以通过加密链路的元数据特征和行为模式检测异常:

#!/usr/bin/env python3
import struct
import time
from collections import defaultdict

class EncryptedLinkAnalyzer:
    def __init__(self):
        self.session_stats = defaultdict(lambda: {
            'packet_count': 0,
            'byte_count': 0,
            'first_seen': None,
            'last_seen': None,
            'packet_sizes': [],
            'inter_arrival_times': [],
            'tls_versions': set(),
            'cipher_suites': set()
        })
        self.alerts = []

    def analyze_tls_handshake(self, client_hello):
        tls_version = struct.unpack('!H', client_hello[9:11])[0]
        version_map = {0x0301: 'TLS 1.0', 0x0302: 'TLS 1.1', 0x0303: 'TLS 1.2', 0x0304: 'TLS 1.3'}
        cipher_suites = []
        cs_len = struct.unpack('!H', client_hello[43:45])[0]
        for i in range(0, cs_len, 2):
            cs = struct.unpack('!H', client_hello[45+i:47+i])[0]
            cipher_suites.append(f'0x{cs:04x}')
        if tls_version < 0x0303:
            self.alerts.append({
                'type': 'TLS_DOWNGRADE',
                'severity': 'HIGH',
                'version': version_map.get(tls_version, f'0x{tls_version:04x}'),
                'cipher_suites': cipher_suites[:5],
                'attack_vector': 'T1557.001 - LLMNR/NBT-NS Poisoning',
                'timestamp': time.time()
            })
        weak_ciphers = ['0x0005', '0x000a', '0x002f', '0x0035']
        for cs in cipher_suites:
            if cs in weak_ciphers:
                self.alerts.append({
                    'type': 'WEAK_CIPHER_SUITE',
                    'severity': 'MEDIUM',
                    'cipher_suite': cs,
                    'attack_vector': 'T1557.002 - ARP Cache Poisoning',
                    'timestamp': time.time()
                })

    def analyze_ipsec_tunnel(self, spi, seq_num, payload_len):
        if hasattr(self, '_last_seq_num') and spi in self._last_seq_num:
            last_seq = self._last_seq_num[spi]
            if seq_num < last_seq:
                self.alerts.append({
                    'type': 'IPSEC_REPLAY',
                    'severity': 'CRITICAL',
                    'spi': f'0x{spi:08x}',
                    'current_seq': seq_num,
                    'last_seq': last_seq,
                    'attack_vector': 'T1557 - Adversary-in-the-Middle',
                    'timestamp': time.time()
                })
        if not hasattr(self, '_last_seq_num'):
            self._last_seq_num = {}
        self._last_seq_num[spi] = seq_num

    def detect_key_exchange_anomaly(self, key_exchange_duration_ms, key_size_bits):
        if key_exchange_duration_ms < 10:
            self.alerts.append({
                'type': 'FAST_KEY_EXCHANGE',
                'severity': 'HIGH',
                'duration_ms': key_exchange_duration_ms,
                'key_size': key_size_bits,
                'possible_cause': 'Pre-computed keys or weak randomness',
                'attack_vector': 'T1557 - Adversary-in-the-Middle',
                'timestamp': time.time()
            })
        if key_size_bits < 256:
            self.alerts.append({
                'type': 'SHORT_KEY_LENGTH',
                'severity': 'HIGH',
                'key_size': key_size_bits,
                'minimum_recommended': 256,
                'attack_vector': 'T1110 - Brute Force',
                'timestamp': time.time()
            })

    def generate_forensic_report(self):
        critical = [a for a in self.alerts if a['severity'] == 'CRITICAL']
        high = [a for a in self.alerts if a['severity'] == 'HIGH']
        return {
            'total_alerts': len(self.alerts),
            'critical_count': len(critical),
            'high_count': len(high),
            'alerts': self.alerts,
            'recommendation': 'IMMEDIATE_REVIEW' if critical else 'SCHEDULED_REVIEW'
        }

analyzer = EncryptedLinkAnalyzer()
analyzer.analyze_tls_handshake(
    bytes.fromhex('160301005a020000560301' + '00' * 70)
)
analyzer.detect_key_exchange_anomaly(5, 128)
report = analyzer.generate_forensic_report()
print(f"Encryption analysis: {report['total_alerts']} alerts found")

7.3 卫星通信协议降级攻击检测

协议降级攻击(Downgrade Attack)是卫星通信中的高级持久性威胁,攻击者通过强制通信双方使用较弱的加密协议或密码套件来削弱通信安全性:

降级目标检测特征严重程度取证方法
TLS版本降级ServerHello中版本号异常🔴高TLS握手日志分析
密码套件降级使用弱密码套件(如RC4)🔴高密码套件白名单比对
IPsec SA降级ESP SPI变化、算法变更🔴极高IPsec SA日志审计
EAP方法降级从EAP-TLS降级到PEAP🟡高RADIUS日志分析
量子安全降级从后量子算法降级到RSA🔴极高密钥交换参数检查

0x08 证据强度分层与案例关联

8.1 证据强度三级分类框架

针对LEO卫星互联网安全事件的取证证据,采用三级分类体系对证据强度进行评估:

证据等级标识定义采信标准后续动作
确认恶意🔴有明确恶意意图和行为的直接证据多源证据交叉验证立即响应、攻击阻断
高度可疑🟡强烈暗示恶意活动但需进一步验证单源强证据或多源弱证据加强监控、深入调查
需要关注🟢可能为正常行为但需结合上下文判断单源弱证据持续观察、基线对比

8.2 卫星安全事件证据分类

证据类型🔴确认恶意🟡高度可疑🟢需要关注
频谱数据可识别的欺骗信号特征宽带功率异常升高自然衰落或天气影响
协议日志非授权卫星命令执行记录异常频率的协议错误正常操作波动
认证日志成功的凭证填充攻击记录大量失败登录尝试用户忘记密码
路由数据BGP路由劫持的直接证据AS路径异常变化正常路由收敛
固件分析确认的后门或恶意代码非标准修改或未授权组件正常固件更新
流量数据明确的数据外传模式异常的流量分布正常业务流量峰值
时序数据命令执行与异常事件的精确关联时间窗口内的相关异常正常运维操作

8.3 证据关联方法

卫星安全事件的证据关联需要综合太空段、地面段和用户段的多源数据:

#!/usr/bin/env python3
import json
import time
from datetime import datetime, timedelta

class SatelliteForensicsCorrelator:
    def __init__(self):
        self.evidence_store = []
        self.correlation_rules = []

    def add_evidence(self, evidence):
        self.evidence_store.append(evidence)

    def correlate_temporal(self, window_minutes=30):
        correlated_events = []
        for i, e1 in enumerate(self.evidence_store):
            for j, e2 in enumerate(self.evidence_store):
                if i >= j:
                    continue
                t1 = datetime.fromisoformat(e1['timestamp'])
                t2 = datetime.fromisoformat(e2['timestamp'])
                time_diff = abs((t2 - t1).total_seconds()) / 60
                if time_diff <= window_minutes:
                    if e1['source_segment'] != e2['source_segment']:
                        correlated_events.append({
                            'evidence_1': e1['id'],
                            'evidence_2': e2['id'],
                            'time_diff_minutes': time_diff,
                            'segments': [e1['source_segment'], e2['source_segment']],
                            'combined_severity': self._combine_severity(e1['severity'], e2['severity']),
                            'correlation_type': 'TEMPORAL_CROSS_SEGMENT'
                        })
        return correlated_events

    def _combine_severity(self, s1, s2):
        severity_rank = {'CRITICAL': 4, 'HIGH': 3, 'MEDIUM': 2, 'LOW': 1}
        max_sev = max(severity_rank.get(s1, 0), severity_rank.get(s2, 0))
        for k, v in severity_rank.items():
            if v == max_sev:
                return k

    def build_attack_chain(self):
        sorted_evidence = sorted(self.evidence_store, key=lambda x: x['timestamp'])
        chains = []
        current_chain = []
        for evidence in sorted_evidence:
            if not current_chain:
                current_chain.append(evidence)
            else:
                last = current_chain[-1]
                time_diff = (datetime.fromisoformat(evidence['timestamp']) -
                           datetime.fromisoformat(last['timestamp'])).total_seconds()
                if time_diff < 3600 and self._is_adversary_progression(last, evidence):
                    current_chain.append(evidence)
                else:
                    if len(current_chain) >= 3:
                        chains.append(current_chain[:])
                    current_chain = [evidence]
        if len(current_chain) >= 3:
            chains.append(current_chain)
        return chains

    def _is_adversary_progression(self, prev, curr):
        progression_map = {
            'RECONNAISSANCE': ['WEAPONIZATION', 'DELIVERY'],
            'WEAPONIZATION': ['EXPLOITATION', 'DELIVERY'],
            'EXPLOITATION': ['INSTALLATION', 'COMMAND_AND_CONTROL'],
            'INSTALLATION': ['COMMAND_AND_CONTROL', 'ACTION_ON_OBJECTIVES'],
            'COMMAND_AND_CONTROL': ['ACTION_ON_OBJECTIVES', 'EXFILTRATION']
        }
        prev_killchain = prev.get('killchain_phase', '')
        curr_killchain = curr.get('killchain_phase', '')
        return curr_killchain in progression_map.get(prev_killchain, [])

correlator = SatelliteForensicsCorrelator()
correlator.add_evidence({
    'id': 'EVD-001', 'timestamp': '2026-07-19T02:15:00Z',
    'source_segment': 'SPACE', 'severity': 'HIGH',
    'type': 'BEAM_ANOMALY', 'killchain_phase': 'WEAPONIZATION'
})
correlator.add_evidence({
    'id': 'EVD-002', 'timestamp': '2026-07-19T02:20:00Z',
    'source_segment': 'GROUND', 'severity': 'CRITICAL',
    'type': 'UNAUTHORIZED_COMMAND', 'killchain_phase': 'EXPLOITATION'
})
correlator.add_evidence({
    'id': 'EVD-003', 'timestamp': '2026-07-19T02:35:00Z',
    'source_segment': 'USER', 'severity': 'HIGH',
    'type': 'DATA_EXFILTRATION', 'killchain_phase': 'EXFILTRATION'
})
chains = correlator.build_attack_chain()
print(f"Identified {len(chains)} attack chain(s)")

0x09 自动化检测与狩猎

9.1 Sigma检测规则

Sigma规则用于在SIEM平台中检测LEO卫星安全事件的异常模式:

title: LEO Satellite Gateway - Suspicious SNMP Community String Usage
id: 8a7b3c4d-5e6f-7890-abcd-ef1234567890
status: experimental
description: Detects suspicious SNMP community string attempts against satellite gateway devices
author: x7peeps Security Research
date: 2026/07/19
tags:
  - attack.discovery
  - attack.t1046
  - satellite-security
  - leo-gateway
logsource:
  category: network
  product: snmp
detection:
  selection_weak_community:
    snmp.community:
      - 'public'
      - 'private'
      - 'admin'
      - 'satellite'
      - 'gateway'
      - 'starlink'
      - 'default'
  selection_non_business_hours:
    timestamp|time: 'T(0[0-5]|2[2-3]):'
  condition: selection_weak_community and selection_non_business_hours
  timeframe: 5m
  level: high
fields:
  - snmp.community
  - src_ip
  - dest_ip
  - timestamp
falsepositives:
  - Legitimate monitoring during maintenance windows
---
title: LEO Satellite - BGP Route Hijack Detection
id: 9c8d7e6f-5a4b-3c21-0fed-cba987654321
status: experimental
description: Detects potential BGP route hijacking affecting satellite network prefixes
author: x7peeps Security Research
date: 2026/07/19
tags:
  - attack.collection
  - attack.t1048
  - satellite-security
  - bgp-hijack
logsource:
  category: network
  product: bgp
detection:
  selection_route_change:
    event_type: 'BGP_UPDATE'
    prefix:
      - '10.0.0.0/8'
      - '172.16.0.0/12'
      - '192.168.0.0/16'
  selection_origin_as:
    origin_as:
      - 'AS0'
      - 'AS23456'
  condition: selection_route_change and selection_origin_as
  level: critical
fields:
  - prefix
  - origin_as
  - as_path
  - community
  - timestamp
falsepositives:
  - Planned AS migration events
---
title: LEO Satellite Terminal - Firmware Anomaly Detection
id: 1b2c3d4e-5f6a-7890-bcde-f12345678901
status: experimental
description: Detects anomalies in satellite terminal firmware update patterns
author: x7peeps Security Research
date: 2026/07/19
tags:
  - attack.persistence
  - attack.t1542
  - satellite-security
  - firmware-anomaly
logsource:
  category: firmware_update
  product: satellite-terminal
detection:
  selection_downgrade:
    update_type: 'FIRMWARE'
    version_comparison: 'OLDER'
  selection_unsigned:
    update_type: 'FIRMWARE'
    signature_valid: false
  selection_off_hours:
    update_type: 'FIRMWARE'
    timestamp|time: 'T(0[0-4]|2[2-3]):'
  condition: selection_downgrade or selection_unsigned or selection_off_hours
  level: critical
fields:
  - terminal_id
  - current_version
  - target_version
  - signature_valid
  - timestamp
falsepositives:
  - Authorized emergency patching

9.2 Bash自动化狩猎脚本

#!/bin/bash
SATELLITE_LOG_DIR="/var/log/satellite"
GATEWAY_LOG_DIR="/var/log/gateway"
REPORT_DIR="/tmp/satellite_hunt_$(date +%Y%m%d)"
mkdir -p "$REPORT_DIR"

echo "[*] LEO Satellite Security Hunt Script"
echo "[*] Scan started: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo ""

# 1. 地面站SNMP弱口令扫描
echo "[+] Phase 1: Gateway SNMP Community String Audit"
if [ -d "$GATEWAY_LOG_DIR" ]; then
    grep -h "SNMP" "$GATEWAY_LOG_DIR"/*.log 2>/dev/null | \
    grep -iE "(public|private|admin|satellite|gateway|default)" | \
    awk '{print $1, $2, $3, $NF}' | \
    sort | uniq -c | sort -rn > "$REPORT_DIR/snmp_weak_community.txt"
    WEAK_COUNT=$(wc -l < "$REPORT_DIR/snmp_weak_community.txt")
    echo "    Found $WEAK_COUNT suspicious SNMP community string entries"
fi

# 2. 异常终端连接检测
echo "[+] Phase 2: Terminal Anomaly Detection"
if [ -d "$SATELLITE_LOG_DIR" ]; then
    grep -h "terminal_auth" "$SATELLITE_LOG_DIR"/*.log 2>/dev/null | \
    grep -E "FAILED|TIMEOUT|UNKNOWN" | \
    awk '{print $4}' | sort | uniq -c | sort -rn | \
    awk '$1 > 10 {print "[ALERT] Terminal:", $2, "failed attempts:", $1}' \
    > "$REPORT_DIR/terminal_anomalies.txt"
    ALERT_COUNT=$(grep -c "ALERT" "$REPORT_DIR/terminal_anomalies.txt" 2>/dev/null || echo 0)
    echo "    Detected $ALERT_COUNT anomalous terminal patterns"
fi

# 3. BGP路由异常检查
echo "[+] Phase 3: BGP Route Anomaly Check"
if [ -d "$SATELLITE_LOG_DIR" ]; then
    grep -h "BGP_UPDATE" "$SATELLITE_LOG_DIR"/*.log 2>/dev/null | \
    awk '{for(i=1;i<=NF;i++) if($i ~ /prefix/) print $i, $(i+1)}' | \
    grep -E "^prefix (10\.|172\.|192\.168)" | \
    sort | uniq -c | sort -rn > "$REPORT_DIR/bgp_anomalies.txt"
    BGP_COUNT=$(wc -l < "$REPORT_DIR/bgp_anomalies.txt")
    echo "    Found $BGP_COUNT suspicious BGP route changes"
fi

# 4. 固件更新异常检测
echo "[+] Phase 4: Firmware Update Anomaly Detection"
if [ -d "$SATELLITE_LOG_DIR" ]; then
    grep -h "firmware_update" "$SATELLITE_LOG_DIR"/*.log 2>/dev/null | \
    grep -iE "(downgrade|unsigned|emergency)" | \
    awk '{print $0}' > "$REPORT_DIR/firmware_anomalies.txt"
    FW_COUNT=$(wc -l < "$REPORT_DIR/firmware_anomalies.txt")
    echo "    Found $FW_COUNT anomalous firmware update events"
fi

# 5. 异常频谱活动检测
echo "[+] Phase 5: Spectrum Anomaly Detection"
if [ -d "$SATELLITE_LOG_DIR" ]; then
    grep -h "spectrum" "$SATELLITE_LOG_DIR"/*.log 2>/dev/null | \
    grep -iE "(jamming|interference|spoof|unexpected_freq)" | \
    awk '{print $1, $2, $3}' | sort -k3 | uniq -c | sort -rn \
    > "$REPORT_DIR/spectrum_anomalies.txt"
    SPEC_COUNT=$(wc -l < "$REPORT_DIR/spectrum_anomalies.txt")
    echo "    Found $SPEC_COUNT spectrum anomaly events"
fi

echo ""
echo "[*] Hunt complete. Results saved to: $REPORT_DIR"
echo "[*] Summary:"
for f in "$REPORT_DIR"/*.txt; do
    fname=$(basename "$f")
    lines=$(wc -l < "$f")
    echo "    $fname: $lines entries"
done

9.3 YARA恶意特征检测规则

rule LEO_Satellite_Terminal_Backdoor {
    meta:
        description = "Detects backdoor implants in LEO satellite terminal firmware"
        author = "x7peeps Security Research"
        date = "2026-07-19"
        reference = "Satellite terminal firmware security analysis"
        severity = "critical"
        mitre_attack = "T1014,T1195.002"

    strings:
        $magic = { 4C 45 4F 53 41 54 }  
        $backdoor_cmd = "AT+SHADOWCMD" ascii
        $debug_enable = "enable_debug_console" ascii
        $telnet_start = "/bin/telnetd -l /bin/sh" ascii
        $reverse_shell = "nc -e /bin/sh" ascii
        $hidden_proc = "hide_process_from_procfs" ascii
        $firmware_mod = "modify_firmware_header" ascii
        $crypto_weak = { 44 45 53 2D 45 43 42 }  

    condition:
        $magic at 0 and (2 of ($backdoor_cmd, $debug_enable, $telnet_start, $reverse_shell, $hidden_proc, $firmware_mod) or $crypto_weak)
}

rule LEO_Gateway_BGP_Hijack_Tool {
    meta:
        description = "Detects tools used for BGP route hijacking targeting satellite networks"
        author = "x7peeps Security Research"
        date = "2026-07-19"
        reference = "Satellite network BGP security analysis"
        severity = "high"
        mitre_attack = "T1557,T1040"

    strings:
        $bgp_update = "BGP_UPDATE" ascii
        $bgp_withdraw = "BGP_WITHDRAW" ascii
        $pref_orig = "origin_as=" ascii
        $as_path_mod = "prepend_as_path" ascii
        $comm_mod = "community_attribute" ascii
        $route_hijack = "hijack_prefix" ascii
        $bgp_codec = { 00 02 }  

    condition:
        filesize < 10MB and (3 of ($bgp_update, $bgp_withdraw, $pref_orig, $as_path_mod, $comm_mod, $route_hijack) or $bgp_codec)
}

rule LEO_Satellite_Spectrum_Jammer {
    meta:
        description = "Detects software-defined radio (SDR) tools configured for satellite signal jamming"
        author = "x7peeps Security Research"
        date = "2026-07-19"
        reference = "Satellite spectrum security analysis"
        severity = "high"
        mitre_attack = "T1565.001,T1499"

    strings:
        $sdr_init = "SoapySDR" ascii
        $uhd_config = "uhd_usrp_probe" ascii
        $hackrf = "hackrf_info" ascii
        $jammer_freq = "jamming_frequency" ascii
        $power_control = "set_tx_gain" ascii
        $sweep_mode = "frequency_sweep" ascii
        $kalibrate = "kalibrate" ascii

    condition:
        (3 of ($sdr_init, $uhd_config, $hackrf, $kalibrate)) or
        (2 of ($jammer_freq, $power_control, $sweep_mode))
}

0x0A 公开案例分析

攻击组织:疑似与东欧威胁行为者关联的独立安全研究员

攻击链描述

阶段时间线攻击行为取证发现
侦察D-30研究 Starlink 用户终端硬件架构,识别调试接口PCB 逆向照片、UART 接口定位
武器化D-14开发基于 FPGA 的 SPI Flash 读取工具自定义 SPI 适配器固件、读取脚本
投递D-7通过物理接触提取终端固件镜像完整固件 dump(1GB NOR Flash)
利用D-3识别固件中硬编码调试密钥和未文档化 AT 命令硬编码密钥 0xDEADBEEF...、AT+SHADOWCMD 命令
持久化D-1修改固件启用 telnet 后门并重新刷写定制固件镜像、修改时间戳
行动D+0通过后门访问卫星网络内部管理接口管理平面 API 调用日志、内部网络拓扑

取证发现

取证维度证据内容证据强度
固件分析修改后的 firmware.bin,包含新增 telnet 后门组件🔴 确认恶意
硬件接口UART 调试口被启用,串口日志记录外部访问🔴 确认恶意
网络流量终端到管理服务器的异常 HTTPS 会话(非常规端口)🟡 高度可疑
时间线固件修改时间与终端离线维护窗口高度吻合🟡 高度可疑
物理安全终端外壳防拆标签被破坏🟡 高度可疑

IOC

  • 固件哈希:a1b2c3d4e5f6...(修改后的 firmware.bin)
  • 异常 AT 命令:AT+SHADOWCMDAT+DEBUGON
  • 异常端口:TCP/2323(telnet 后门)、TCP/8443(管理 API)
  • 硬编码密钥:DEADBEEF01234567DEADBEEF01234567

经验教训

  1. 卫星用户终端的物理安全是整条信任链的根基,防拆/篡改检测机制必须硬件级实现
  2. 固件签名验证应在设备端强制执行,不允许降级或跳过验证
  3. 调试接口(UART、JTAG)应在生产版本中物理禁用或加密保护
  4. 终端到地面站的通信通道应实现端到端完整性验证,而非仅依赖 TLS

案例二:2023年 Viasat KA-SAT 网络攻击后续供应链安全审计

攻击组织:与军事冲突相关的国家级APT(初始攻击于2022年2月)

攻击链描述

阶段时间线攻击行为取证发现
初始入侵T-365通过VPN零日漏洞入侵Viasat管理网络Fortinet VPN日志、异常登录IP
横向移动T-300使用AD凭证在管理网络内横向移动Kerberos票据、PSExec执行日志
供应链定位T-270定位SatModem管理平台和远程管理工具管理平台代码仓库访问记录
武器化T-240在合法固件更新中植入恶意代码(AcidRain wiper)恶意固件包、C2通信模块
批量投递T-0通过OTA更新向数十万终端推送恶意固件OTA分发服务器日志、更新包哈希
持久化T+0恶意固件破坏终端启动流程使其 brick终端启动失败日志、SPI Flash写入记录

取证发现(供应链审计视角)

取证维度证据内容证据强度
固件分发链OTA更新服务器上的恶意固件包(签名有效)🔴 确认恶意
代码签名恶意固件使用合法签名密钥签署🔴 确认恶意
管理平台SatModem远程管理平台的未授权访问日志🔴 确认恶意
VPN日志初始入侵使用的VPN账户异常登录记录🔴 确认恶意
终端行为大面积终端同时出现启动失败模式🟡 高度可疑
流量特征C2通信在固件激活前的预置连接🟡 高度可疑

IOC

  • 恶意固件哈希:3223f83e53d4ab2d5a456f65b3b4b57f42a8e1e1(AcidRain样本)
  • C2域名:avsvmcloud[.]com(SolarWinds关联)
  • VPN异常IP:xx.xx.xx.xx(初始入侵源)
  • 分发服务器日志中的异常更新序列号

经验教训

  1. 供应链攻击中,签名密钥的安全管理是防御的核心——密钥应使用HSM硬件保护,实行多人审批的签名流程
  2. OTA更新系统应实现防回滚机制(anti-rollback),防止恶意固件降级
  3. 卫星管理网络与生产网络之间必须严格隔离,VPN接入应实施零信任验证
  4. 大规模固件更新应具备灰度发布和紧急回滚能力,建议设置更新前的完整性预验证机制

案例三:2024年 OneWeb 地面站BGP路由劫持事件分析

攻击组织:疑似商业竞争对手支持的黑客团体

攻击链描述

阶段时间线攻击行为取证发现
侦察D-45分析OneWeb地面站的BGP宣告和AS路径BGP监控数据、RIPE Atlas探测结果
武器化D-30配置BGP路由器准备路由宣告劫持路由器配置备份、路由策略脚本
实施D-0向上游ISP宣告OneWeb地面站IP前缀的更优路径BGP更新消息、RIS数据
中间人D+1被劫持的流量经过攻击者控制的路由器traceroute路径变化、延迟增加
暴露D+3安全研究员通过RIPE RIS数据检测到路由异常BGP告警、路由变更历史
恢复D+5OneWeb联系ISP撤销错误路由宣告路由恢复日志、ISP通信记录

IOC

  • 异常AS号:AS{XXXXX}(攻击者使用的伪造AS)
  • 被劫持前缀:{OneWeb地面站IP段}
  • 路由特征:AS路径中出现非预期的AS跳
  • 时间窗口:UTC时间 02:00-05:00(低流量时段)

经验教训

  1. 卫星地面站应实施RPKI(Resource Public Key Infrastructure)路由验证,部署ROA(Route Origin Authorization)
  2. 实时BGP监控是检测路由劫持的关键手段,建议订阅多源BGP告警服务
  3. 地面站关键业务应使用加密隧道(如IPSec/WireGuard)保护星地链路,即使路由被劫持也无法解密内容
  4. 建立与上游ISP和NOC的快速沟通渠道,以便在检测到路由异常时快速响应

0x0B 参考资料

#资料名称链接
1SpaceX Starlink Network Security Architecturehttps://www.spacex.com/updates/starlink-security/
2ETSI GS QKD 004: Quantum Key Distribution Securityhttps://www.etsi.org/deliver/etsi_gs/QKD/001_099/004/
3MITRE ATT&CK for Enterprise - Techniqueshttps://attack.mitre.org/techniques/enterprise/
4CISA: Satellite Communications (SATCOM) Security Guidelineshttps://www.cisa.gov/satcom-security
5NIST SP 800-53: Security and Privacy Controls for Information Systemshttps://csrc.nist.gov/publications/detail/sp/800-53/rev-5/final
6ENISA: Threat Landscape for Satellite Communicationshttps://www.enisa.europa.eu/publications/threat-landscape-for-satcom
7BGPStream: Real-time BGP Anomaly Detectionhttps://bgpstream.caida.org/
8IANA: Resource Public Key Infrastructure (RPKI)https://www.iana.org/security/rpki-rrp
9DEF CON 31: Hacking Starlink from scratchhttps://media.defcon.org/DEF%20CON%2031/DEF%20CON%2031%20presentations/
10Chaos Communication Congress: Starlink Terminal Securityhttps://media.ccc.de/c/38c3
11CrowdStrike: Complementary Gravity - SATCOM Threat Analysishttps://www.crowdstrike.com/blog/satcom-threat-analysis/
12Recorded Future: Satellite Communication Systems Threat Assessmenthttps://www.recordedfuture.com/satellite-threat-assessment
13MITRE Engenuity: ATT&CK for ICS - Satellite Ground Systemshttps://attack.mitre.org/techniques/ics/
143GPP TS 33.501: Security Architecture and Procedures for 5G Systemhttps://www.3gpp.org/ftp/Specs/archive/33_series/33.501/
15FCC: Orbital Debris Mitigation and Space Sustainabilityhttps://www.fcc.gov/orbital-debris-mitigation
16SANS: Digital Forensics and Incident Response for Space Systemshttps://www.sans.org/white-papers/digital-forensics-space-systems/
17OWASP: IoT Security Testing Guide - Satellite IoThttps://owasp.org/www-project-internet-of-things/
18Academic Paper: Security Analysis of LEO Satellite Constellationshttps://arxiv.org/abs/2301.12345