Ram-Git-Account/cache-side-channel-attack-demo
GitHub: Ram-Git-Account/cache-side-channel-attack-demo
通过C++原生Flush+Reload和浏览器Prime+Probe两种实现,直观演示CPU缓存侧信道攻击原理及现代浏览器的防御机制。
Stars: 0 | Forks: 0
# 缓存侧信道攻击演示 (Flush+Reload vs 浏览器 Prime+Probe)
## 概述
本项目在两种环境中演示了**缓存侧信道攻击**:
1. **原生实现 (C++)** – 使用共享内存和 CPU 缓存指令进行的可靠 **Flush+Reload** 攻击。
2. **浏览器实验 (JavaScript)** – 概念性的 **Prime+Probe 风格攻击**,由于现代浏览器的防御措施,噪声显著。
目的是展示 **CPU 缓存的微架构行为如何泄露机密信息**,以及浏览器为何实施针对此类攻击的强缓解措施。
# 概念
现代 CPU 使用多级缓存 (L1, L2, L3) 来加速内存访问。
典型的访问延迟:
| 内存层级 | 大约延迟 |
| ------------ | -------------- |
| L1 缓存 | ~4 个时钟周期 |
| L2 缓存 | ~12 个时钟周期 |
| L3 缓存 | ~40 个时钟周期 |
| 主内存 | ~200+ 个时钟周期 |
如果攻击者能测量**内存访问所需的时间**,就能推断数据是否已存在于缓存中。
这种时间差异构成了**缓存侧信道攻击**的基础。
# 演示的攻击类型
## 1. Flush+Reload (原生 C++)
当两个进程共享**同一物理内存页**时,Flush+Reload 生效。
攻击循环:
```
Attacker flushes cache line
Victim runs and may access the line
Attacker reloads and measures latency
```
解释:
```
Fast reload → Victim accessed the line
Slow reload → Victim did not access it
```
# 项目结构
```
project/
│
├── attacker.cpp
├── victim.cpp
└── shared_mem.bin
```
# 受害者程序
受害者重复访问一个依赖于机密的内存位置。
```
volatile unsigned char *addr = &shared[secret * STRIDE];
*addr;
```
这将把缓存行加载到 CPU 缓存中。
# 攻击者程序
攻击者:
1. 刷新所有候选缓存行
2. 短暂等待受害者执行
3. 重新加载每个缓存行
4. 测量延迟
5. 推断受害者访问了哪一行
关键攻击逻辑:
```
_mm_clflush(&shared[i * STRIDE]);
```
紧接着是
```
uint64_t t = measure(&shared[mix_i * STRIDE]);
```
如果重新加载时间**低于阈值**,则该行很可能被受害者访问过。
# 阈值校准
攻击者自动测量:
* **缓存命中访问延迟**
* **未缓存访问延迟**
```
CACHE_HIT_THRESHOLD = (cached + uncached) / 2;
```
这将区分缓存命中和未命中。
# 随机化探测顺序
攻击者以**混合顺序**探测缓存行:
```
mix_i = ((i * 167) + 13) & (NUM_LINES - 1);
```
这可以防止 CPU **硬件预取器**检测到顺序模式。
# 运行演示
编译:
```
g++ attacker.cpp -O2 -march=native -o attacker
g++ victim.cpp -O2 -march=native -o victim
```
运行受害者:
```
./victim
```
在另一个终端运行攻击者:
```
./attacker
```
示例输出:
```
Cached latency: 40
Uncached latency: 210
Threshold: 125
Most likely index: 60 hits: 990
```
攻击者成功推断出受害者的机密索引。
# 浏览器版本 (JavaScript)
我们还使用 JavaScript 实现了基于浏览器的攻击版本。
浏览器不支持 Flush+Reload,因此需要一种 **Prime+Probe 风格的攻击**。
攻击循环:
```
Prime cache with attacker data
Victim executes
Probe cache and measure timing
```
然而,浏览器攻击的噪声要大得多。
# 为什么浏览器攻击较弱
现代浏览器有意削弱微架构侧信道。
主要防御措施包括:
### 1. 定时器精度降低
JavaScript 定时器非常粗糙。
典型的分辨率:
| API | 精度 |
| ----------------- | ------------- |
| performance.now() | ~100µs – 1ms |
缓存时间差异是**纳秒级**的,因此信号被严重削弱。
### 2. SharedArrayBuffer 限制
使用 `SharedArrayBuffer` 的高分辨率定时器仅在**跨域隔离**下启用。
这防止攻击者轻易构建精确的定时器。
### 3. 站点隔离
浏览器将网站隔离到单独的进程中。
这减少了跨站点缓存共享。
### 4. Spectre 缓解措施
在发现**推测执行攻击**后,浏览器增加了保护措施,例如:
* 推测屏障
* 边界检查
* JIT 加固
### 5. 预取器干扰
当内存访问可预测时,硬件预取器可以隐藏缓存未命中。
需要随机探测顺序来缓解这个问题。
### 6. 浏览器噪声
额外的噪声来源包括:
* 操作系统调度
* 垃圾回收
* JIT 编译
* 后台标签页
* 其他使用缓存的进程
# 对比:原生 vs 浏览器攻击
| 特性 | 原生 Flush+Reload | 浏览器 Prime+Probe |
| -------------- | ---------------------- | ------------------- |
| 缓存驱逐 | 精确 (`clflush`) | 间接 |
| 计时 | 纳秒 (`rdtsc`) | 微秒 |
| 信号质量 | 非常强 | 嘈杂 |
| 粒度 | 单个缓存行 | 缓存组 |
| 攻击难度 | 较容易 | 难得多 |
# 教育价值
本项目演示了:
* CPU 缓存如何泄露信息
* 微架构侧信道如何工作
* 现代浏览器为何引入防御措施
* **原生和浏览器攻击模型**之间的差异
# 免责声明
本项目仅用于**教育和研究目的**。
它演示了学术安全研究中使用的已知侧信道技术。
# 参考资料
* Flush+Reload: A High Resolution Cache Side-Channel Attack
* Prime+Probe Cache Attacks
* Spectre and Meltdown 研究论文
* 现代浏览器安全文档
标签:C++, CMS安全, CPU安全, Flush+Reload, JavaScript, L3缓存, POC验证, Prime+Probe, Spectre/Meltdown原理, 主机安全, 侧信道攻击, 共享内存, 微架构攻击, 性能分析, 恶意防范, 数据可视化, 数据擦除, 时序攻击, 消息认证码, 漏洞演示, 缓存攻击, 网络安全, 计算机体系结构, 隐私保护