
目录
现代计算系统通常具有紧密集成的 CPU 和 GPU 组件,并共享内存和微架构资源。虽然这种集成带来了巨大的性能提升,但也带来了显著的风险,例如边信道和隐蔽通道。这些允许攻击者通过传统的进程隔离泄露信息跨组件。
本文提供了对集成 CPU 上的跨组件隐蔽通道的深入技术审查,尤其关注那些利用共享微架构组件—缓存、分支预测器及其他的隐蔽通道。我们将探索理论背景、现实可行性、代码演示和当前的缓解策略。不论您是安全初学者还是高级研究人员,本指南将涵盖威胁模型、实用的概念验证(PoCs)以及最佳防御实践。
隐蔽通道是指未被设计用于信息传输的通信路径。在计算中,该术语通常用于描述一个进程(发送者或“高等级”进程)故意以某种违反安全政策的方式向另一个进程(接收者或“低等级”进程)传输信息的场景。
隐蔽通道不限于网络流量。许多存在于较低的系统层,包括存储通道(使用文件、内存时间等)和时间通道(资源可用性差异)。
现代 CPU 和 GPU 为了提高效率使用共享资源:
当两个进程共享这些资源时,即使不允许直接通信,它们也可以通过变化共享硬件的状态或时间信号传递信息。
最为臭名昭著的隐蔽通道是基于缓存的:
这两种攻击都利用了多级 CPU 缓存的共享特性,尤其是最后一级缓存 (LLC)。
现代 CPU 使用分支预测器来加速执行。这些预测器是共享的,可能在进程间甚至跨核使用。如果发送者训练了预测器,接收者可以探测并观察预测变化,从而实现数据传输。
集成 CPU-GPU 系统共享 DRAM,甚至有时更细粒度的组件(如 LLC、系统总线)。这种跨组件资源共享打开了新的、尚未充分探索的攻击面:
学术研究研究了 CPU 和 GPU 或其上运行的各个进程,通过共享缓存行或内存带宽形成隐蔽通道的攻击(Leaky Buddies)。
clflush 指令)。要点:时间差异揭示发送者的操作。
主要用于云环境中,可能不存在共享内存。
参见《通过分支预测器的隐蔽通道:可行性研究》了解攻击演示。
首先收集 CPU 缓存和分支预测器信息。
# 列出 CPU 缓存详细信息
lscpu | grep -i cache
# 高级:直接解析 CPU 缓存大小
cat /proc/cpuinfo | grep -E 'cache size|model name'
# 列出由进程映射的共享库
pidof firefox # 例如
cat /proc/<pid>/maps | grep r-xp | grep 'lib'
# Python:解析以寻找共享对象区域
import os
pid = <your_pid>
with open(f"/proc/{pid}/maps") as f:
for line in f:
if 'lib' in line and 'r-xp' in line:
print(line.strip())
// gcc -O2 -o flush_reload flush_reload.c
#include <stdio.h>
#include <stdint.h>
#include <x86intrin.h>
uint64_t measure_access_time(volatile char *addr) {
uint64_t start = __rdtscp(&start);
*(volatile char *)addr;
uint64_t end = __rdtscp(&end);
return end - start;
}
int main() {
char *ptr = ...; // 映射到共享对象
while (1) {
_mm_clflush(ptr); // 发送者:或跳过以供接收者使用
uint64_t t = measure_access_time(ptr);
printf("访问时间:%lu\n", t);
}
}
import ctypes
import time
# 映射共享库/文件,例如通过 mmap
libc = ctypes.CDLL("libc.so.6")
address = ctypes.c_void_p(...)
def measure_access_time(addr):
t1 = time.perf_counter_ns()
dummy = ctypes.c_char.from_address(addr.value)
val = dummy.value
t2 = time.perf_counter_ns()
return t2 - t1
while True:
t = measure_access_time(address)
print(f"访问时间:{t}ns")
// 分支预测攻击中发送者和接收者的伪代码
// 要传输的数据位:0 或 1
// 发送者:“训练”分支预测器
if (bit_to_send == 1) {
for (int i = 0; i < 1000; i++) { if (cond) foo(); }
} else {
for (int i = 0; i < 1000; i++) { if (!cond) foo(); }
}
// 接收者:测量分支误预测计时
uint64_t t1 = rdtscp();
if (cond) foo();
uint64_t t2 = rdtscp();
uint64_t elapsed = t2 - t1;
if (elapsed > THRESHOLD) decode as bit 1 else 0;
注: 没有缓解措施是完美的—权衡包括性能/安全性。
这些攻击是侧信道/隐蔽通道的超集,利用推测执行(Spectre,Meltdown)和其他瞬态执行的指令通过微架构通道泄露状态:
参见《侧信道和瞬态执行》课件系列,获取视图/时间细分。
perf stat ...)# 监控缓存未命中和分支未预测
sudo perf stat -e cache-misses,branch-misses ./your_app
import psutil
# 随时间监控每个进程的缓存和 CPU 使用
for proc in psutil.process_iter(['pid', 'name', 'cpu_percent']):
print(proc.info)
跨组件隐蔽通道突显了微架构安全领域中一个关键且持续的风险。随着 CPU 和 GPU 越来越紧密地集成,潜在泄露秘密数据的边界从共享 CPU 缓存扩展到复杂的分支预测器以及跨 CPU-GPU 资源。
防御需要硬件、操作系统和软件的协调努力——并且始终伴随着性能成本。攻击越深入,选择的难度越大。
对于研究人员而言,识别、建模和缓解新的跨组件隐蔽通道技术是一个持续的过程。对于各个组织,威胁建模和态势意识至关重要。
欲知最新研究和漏洞披露,请经常监控可信的学术会议站点和 CVE 公告。