MadRadar:mmWave 汽车雷达”幻觉攻击”——ISO 21434 雷达安全防御与座舱 CPD 安全启示

事件背景

Duke 大学 Miroslav Pajic 和 Tingjun Chen 团队开发了 MadRadar 系统——一个黑盒物理层攻击框架,能在不到 0.25 秒内检测并欺骗汽车 mmWave FMCW 雷达,使其”看到”不存在的幻影车、忽略真实车辆、或误判车辆轨迹。

要素 详情
研究机构 Duke University, ECE Department
发表 NDSS 2024 (Network and Distributed System Security Symposium)
arXiv MadRadar: A Black-Box Physical Layer Attack Framework
攻击类型 黑盒(无需知道目标雷达参数)
检测参数时间 <0.25 秒
演示场景 真实车辆 + 真实道路速度
资助 ONR, AFOSR, NSF

1. 三种攻击类型

攻击 1:幻影车辆创建

攻击 2:真实车辆隐藏

攻击 3:轨迹篡改

攻击对比

攻击类型 难度 危险等级 技术要求 检测难度
幻影创建 中 高(急刹/追尾) 参数检测+信号合成 中
真实隐藏 高 极高(碰撞) 精密掩蔽信号 难
轨迹篡改 高 极高(误判加速) 混合攻击 难

2. FMCW 雷达信号分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""
FMCW (Frequency Modulated Continuous Wave) 雷达信号分析
理解 MadRadar 攻击的物理基础

FMCW 雷达原理:
1. 发射线性调频信号(chirp)
2. 接收反射信号
3. 混频得到拍频(beat frequency)
4. 拍频 ∝ 距离
5. 多普勒频移 ∝ 速度
"""

import numpy as np
from scipy import signal as sig
from typing import Tuple

class FMCWRadar:
"""FMCW 雷达信号模拟"""

def __init__(self, fc: float = 77e9, bw: float = 4e9,
chirp_duration: float = 50e-6, sample_rate: float = 20e6):
self.fc = fc # 中心频率 77 GHz
self.bw = bw # 带宽 4 GHz
self.Tc = chirp_duration # chirp 持续时间
self.fs = sample_rate # 采样率

# 距离和速度分辨率
self.range_res = 3e8 / (2 * bw) # ~3.75 cm
self.vel_res = 3e8 / (2 * fc * chirp_duration * 2) # 简化

def generate_chirp(self, n_samples: int = 1024) -> np.ndarray:
"""生成发射 chirp 信号"""
t = np.arange(n_samples) / self.fs
# 线性调频:f(t) = fc + (bw/Tc) * t
k = self.bw / self.Tc # 调频率
chirp_tx = np.exp(1j * 2 * np.pi * (self.fc * t + 0.5 * k * t**2))
return chirp_tx

def simulate_target(self, tx_chirp: np.ndarray,
range_m: float, velocity_ms: float,
rcs: float = 1.0) -> np.ndarray:
"""
模拟目标反射信号

Args:
tx_chirp: 发射信号
range_m: 目标距离(米)
velocity_ms: 目标相对速度(米/秒)
rcs: 雷达截面积
"""
n = len(tx_chirp)
t = np.arange(n) / self.fs

# 时间延迟
tau = 2 * range_m / 3e8 # 双程延迟

# 多普勒频移
fd = 2 * velocity_ms * self.fc / 3e8

# 延迟+多普勒+衰减
delay_samples = int(tau * self.fs)
rx = np.zeros(n, dtype=complex)

if delay_samples < n:
attenuation = rcs / (range_m**4 + 1) # 简化衰减
rx[delay_samples:] = attenuation * tx_chirp[:n-delay_samples] * \
np.exp(1j * 2 * np.pi * fd * t[:n-delay_samples])

return rx

def range_doppler_map(self, tx_chirp: np.ndarray,
rx_signal: np.ndarray) -> np.ndarray:
"""
距离-多普勒图

核心处理:
1. 混频(tx * conj(rx))得到拍频
2. FFT 得到距离剖面
3. 多 chirp FFT 得到多普勒
"""
# 混频
beat = tx_chirp * np.conj(rx_signal)

# 距离 FFT
range_profile = np.fft.fft(beat)

return range_profile

def spoof_signal(self, tx_chirp: np.ndarray,
fake_range: float, fake_velocity: float) -> np.ndarray:
"""
MadRadar 欺骗信号生成

模拟攻击者发送伪造反射信号
使雷达"看到"不存在的幻影目标
"""
return self.simulate_target(tx_chirp, fake_range, fake_velocity, rcs=2.0)

def hide_signal(self, tx_chirp: np.ndarray, rx_real: np.ndarray,
real_range: float) -> np.ndarray:
"""
MadRadar 隐藏攻击

在真实目标反射周围添加掩蔽信号
使雷达"看不到"真实目标
"""
n = len(tx_chirp)
t = np.arange(n) / self.fs

# 真实目标的拍频
beat_real = tx_chirp * np.conj(rx_real)

# 生成反向掩蔽信号
tau_real = 2 * real_range / 3e8
mask_freq = self.bw * tau_real / self.Tc # 真实目标的拍频

# 创建干扰:在真实目标频率附近注入宽带噪声
noise = np.random.randn(n) * 0.5
mask_signal = noise * np.exp(1j * 2 * np.pi * mask_freq * t)

# 叠加到接收信号
rx_spoofed = rx_real + mask_signal * 0.3

return rx_spoofed


# 测试
if __name__ == "__main__":
radar = FMCWRadar()

print(f"=== FMCW 雷达参数 ===")
print(f"中心频率: {radar.fc/1e9} GHz")
print(f"带宽: {radar.bw/1e9} GHz")
print(f"距离分辨率: {radar.range_res*100:.2f} cm")
print(f"Chirp 持续: {radar.Tc*1e6:.0f} μs")

# 正常场景:30米外有车
tx = radar.generate_chirp()
rx = radar.simulate_target(tx, range_m=30, velocity_ms=-5)
rdm = radar.range_doppler_map(tx, rx)
real_peak = np.argmax(np.abs(rdm))
print(f"\n正常检测:目标在 30m,峰值在 bin {real_peak}")

# 欺骗场景:注入幻影目标(50米)
spoof = radar.spoof_signal(tx, fake_range=50, fake_velocity=-10)
rdm_spoof = radar.range_doppler_map(tx, rx + spoof)
spoof_peak = np.argmax(np.abs(rdm_spoof))
print(f"欺骗后:幻影目标在 50m,峰值在 bin {spoof_peak}")
print(f" → 雷达误判前方有更远的车(可能导致 ACC 误操作)")

3. ISO 21434 雷达安全防御

3.1 风险评估

威胁场景 可能性 影响度 风险等级 建议措施
幻影车辆导致急刹 中 高 🔴 高 参数随机化+异常检测
真实车辆隐藏导致碰撞 低 极高 🟡 中 多传感器交叉验证
轨迹篡改导致误加速 低 极高 🟡 中 行为合理性检查
CPD 雷达被欺骗 低 中 🟢 低 CPD 结果+座位传感器融合

3.2 防御机制实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
"""
ISO 21434 雷达安全防御机制

三层防御:
1. 参数随机化 — 随机改变 chirp 参数
2. 信号异常检测 — 检测不自然的回波模式
3. 多传感器交叉验证 — 雷达+摄像头+激光雷达一致性
"""

import numpy as np
from typing import Tuple, List

class RadarDefenseSystem:
"""雷达安全防御系统"""

def __init__(self):
# 参数随机化
self.chirp_params = {
'fc_base': 77e9,
'bw_base': 4e9,
'Tc_base': 50e-6,
'randomization_active': True,
}
self.param_history = []
self.anomaly_threshold = 3.0 # 标准差倍数
self.consistency_check_enabled = True

def randomize_params(self) -> dict:
"""
防御1:随机化雷达参数

MadRadar 需要在 0.25s 内检测参数,
随机化使其检测到的参数很快失效
"""
if not self.chirp_params['randomization_active']:
return self.chirp_params

# 每 0.1s 随机改变参数(比攻击检测更快)
params = {
'fc': self.chirp_params['fc_base'] + np.random.uniform(-100e6, 100e6),
'bw': self.chirp_params['bw_base'] + np.random.uniform(-200e6, 200e6),
'Tc': self.chirp_params['Tc_base'] * np.random.uniform(0.8, 1.2),
'chirp_pattern': np.random.choice(['up', 'down', 'triangular']),
}

self.param_history.append(params)
return params

def detect_anomaly(self, range_doppler: np.ndarray,
baseline: np.ndarray) -> Tuple[bool, float]:
"""
防御2:信号异常检测

检测不自然的回波模式:
- 过强的点目标(幻影车通常 RCS 不自然)
- 不存在的速度-距离关联
- 突然出现/消失的目标
"""
# 计算与基线的差异
diff = np.abs(range_doppler - baseline)

# 统计异常检测
mean_diff = np.mean(diff)
std_diff = np.std(diff)

# Z-score 检测
z_scores = (diff - mean_diff) / (std_diff + 1e-10)
max_z = np.max(np.abs(z_scores))

is_anomaly = max_z > self.anomaly_threshold
confidence = min(1.0, max_z / (self.anomaly_threshold * 2))

return is_anomaly, confidence

def cross_validate(self, radar_targets: List[dict],
camera_targets: List[dict],
lidar_targets: List[dict] = None) -> dict:
"""
防御3:多传感器交叉验证

雷达检测到的目标必须与摄像头/激光雷达一致
不一致 → 可能被欺骗
"""
radar_only = []
confirmed = []

for r_target in radar_targets:
matched = False
for c_target in camera_targets:
if self._targets_match(r_target, c_target):
confirmed.append(r_target)
matched = True
break

if not matched:
radar_only.append(r_target)

return {
'confirmed_targets': confirmed,
'radar_only_targets': radar_only,
'spoofing_suspected': len(radar_only) > 0,
'total_radar': len(radar_targets),
'total_confirmed': len(confirmed),
}

def _targets_match(self, t1: dict, t2: dict,
range_tol: float = 2.0,
angle_tol: float = 5.0) -> bool:
"""判断两个目标是否匹配"""
return (abs(t1.get('range', 0) - t2.get('range', 0)) < range_tol and
abs(t1.get('angle', 0) - t2.get('angle', 0)) < angle_tol)


# 测试
if __name__ == "__main__":
defense = RadarDefenseSystem()

# 防御1:参数随机化
for i in range(3):
params = defense.randomize_params()
print(f"随机化 {i}: fc={params['fc']/1e9:.3f} GHz, "
f"bw={params['bw']/1e9:.3f} GHz, "
f"pattern={params['chirp_pattern']}")

# 防御2:异常检测
np.random.seed(42)
baseline = np.random.randn(64, 64) * 0.1
normal_signal = baseline + np.random.randn(64, 64) * 0.05
spoofed_signal = baseline.copy()
spoofed_signal[30, 30] += 5.0 # 注入强点目标

is_an, conf = defense.detect_anomaly(normal_signal, baseline)
print(f"\n正常信号: anomaly={is_an}, confidence={conf:.2f}")

is_an2, conf2 = defense.detect_anomaly(spoofed_signal, baseline)
print(f"欺骗信号: anomaly={is_an2}, confidence={conf2:.2f}")

# 防御3:交叉验证
radar_targets = [
{'range': 30, 'angle': 0, 'velocity': -5},
{'range': 50, 'angle': 5, 'velocity': -10}, # 幻影
]
camera_targets = [
{'range': 31, 'angle': 1, 'velocity': -5},
]

result = defense.cross_validate(radar_targets, camera_targets)
print(f"\n交叉验证: 确认={result['total_confirmed']}, "
f"仅雷达={len(result['radar_only_targets'])}, "
f"疑似欺骗={result['spoofing_suspected']}")

4. 座舱 CPD 雷达安全

MadRadar 对座舱雷达的影响

座舱雷达 被攻击风险 影响 防御
60GHz mmWave CPD 低(车内信号难注入) 误报/漏报 参数随机化
UWB CPD (NCJ29D6) 低 数字钥匙欺骗 已有加密协议
驾驶员 vital signs 雷达 低 伪造生命体征 多传感器验证

判断: 座舱雷达被 MadRadar 攻击的风险远低于外部感知雷达,因为攻击者需要在车内部署欺骗设备。但仍应作为 ISO 21434 威胁分析的一部分。


5. IMS 开发启示

优先级 行动 依据
P2 在 ISO 21434 威胁分析中纳入雷达欺骗 安全合规
P2 评估雷达参数随机化可行性 MadRadar 防御
P3 多传感器交叉验证框架 安全纵深防御
P3 座舱雷达安全评估(低优先级) 风险较低

参考资料

  1. “Engineers develop hack to make automotive radar ‘hallucinate’,” ScienceDaily, 2024-01-31. https://www.sciencedaily.com/releases/2024/01/240131183515.htm
  2. MadRadar: Black-Box Physical Layer Attack on mmWave FMCW Radars, NDSS 2024
  3. ISO/SAE 21434:2021, “Road vehicles — Cybersecurity engineering”
  4. ISO 21434 TARA (Threat Analysis and Risk Assessment)