发布
社区首页 >问答首页 >一个简单的flush reload侧信道攻击复现,永远检测失败是为什么?

一个简单的flush reload侧信道攻击复现,永远检测失败是为什么?

提问于 2024-10-25 14:58:54
回答 1关注 0查看 35

这是我的代码,靠flush+reload来读取secret,但是输出一直都是array2[0],这是为什么

代码语言:txt
复制
#include <cstdint>
#include <cstring>
#include <iostream>
#include <x86intrin.h>

using namespace std;

class Exp1 {

public:
    unsigned int junk = 0;
    uint8_t array2[4096 * 256]{};  // 用于存储不同字符的数组
    uint8_t array3[256]{};          // 结果存储数组

    uint64_t CACHE_HIT_THRESHOLD = 80; // 缓存命中阈值

    const char *secret = "exp1{flush_reload_attack}"; // 要读取的秘密

    // 用于计算 CACHE_HIT_THRESHOLD 的方法
    void cal_threshold() {
        uint64_t sum_hit = 0;
        uint64_t sum_miss = 0;
        uint64_t time;
        //volatile uint8_t *addr;

        // 计算缓未存命中时间
       // addr = &array3[0];
        for (int i = 0; i < 1000; i++) {
            _mm_mfence();
            _mm_lfence();
            _mm_clflush(&array3[0]);                // Flush 缓存

            _mm_mfence();
            _mm_lfence();
            uint64_t start = __rdtscp(&junk); // 开始计时
            _mm_lfence();
            junk = array3[0];      
            _mm_lfence();              // 访问地址
            uint64_t end = __rdtscp(&junk); // 结束计时
            sum_miss += (end - start);
        }

        // 计算缓存命中时间
        for (int i = 0; i < 1000; i++) {
            _mm_mfence();
            _mm_lfence();
            uint64_t start = __rdtscp(&junk); // 开始计时
            _mm_lfence();
            junk = array3[0];                     // 访问地址
            _mm_lfence();
            uint64_t end = __rdtscp(&junk);   // 结束计时
            sum_hit += (end - start);
        }

        // 平均时间计算
        uint64_t avg_miss = sum_miss / 1000;
        uint64_t avg_hit = sum_hit / 1000;
        cout << "sum_miss: " << avg_miss << endl;
        cout << "sum_hit: " << avg_hit << endl;

        // 设定阈值
        CACHE_HIT_THRESHOLD = (2*avg_hit + avg_miss) / 3;
       // CACHE_HIT_THRESHOLD = avg_hit;
        cout << "Calculated CACHE_HIT_THRESHOLD: " << CACHE_HIT_THRESHOLD << endl;
    }

    // 读取一个字节的内存值
   void readMemoryByte(int malicious_x, uint8_t &value, int &score) {
    int count = 1000;
    int results[256] = {0};  // 统计每个字节的计数

    // 预加载一个与攻击无关的数据地址
    volatile uint8_t temp = 0;
    for (int i = 0; i < 256; i++) {
        _mm_mfence();
        _mm_lfence();
        _mm_clflush(&array3[i]); // 清除无关数据
    }

    for (int t = 0; t < count; t++) {
        // 1. Flush 所有的 array2 缓存
        for (int i = 0; i < 256; i++) {
            _mm_mfence();
            _mm_lfence();
            _mm_clflush(&array2[i * 4096]);
        }

        // 访问一些不相关的内存地址
        temp ^= array3[0];

        // 2. Encode: 依据秘密信息访问 array2
        _mm_mfence();
        junk &= array2[secret[malicious_x] * 4096]; // 利用 secret 进行访问
        _mm_mfence();

        // 3. Reload: 通过访问时间判断哪个 array2 的位置在缓存中
        for (int i = 0; i < 256; i++) {
            _mm_mfence();
            _mm_lfence();
            uint64_t start = __rdtscp(&junk); // 计时开始
            _mm_lfence();
            junk = array2[i * 4096];          // 访问 array2
            _mm_lfence();
            uint64_t end = __rdtscp(&junk);   // 计时结束

            // 如果访问时间小于阈值,则认为该位置在缓存中
            if ((end - start) < CACHE_HIT_THRESHOLD) {
                results[i]++;
            }
        }
    }

    // 找出出现次数最多的字节
    int max = -1;
    int max_idx = -1;
    for (int i = 0; i < 256; i++) {
        if (results[i] > max) {
            max = results[i];
            max_idx = i;  // 猜测的字节值
        }
    }
    value = max_idx; // 将最有可能的字节值赋给 value
    score = max;     // 将命中次数赋给 score
}


    // 构造函数:逐字节读取 secret
    Exp1() {
        int len = 0;
        int score = 0;
        uint8_t value = 0;

        // 计算缓存命中和未命中的阈值
        cal_threshold();

        // 逐字节读取 secret
        while (len < (int)strlen(secret)) {
            readMemoryByte(len, value, score);
            cout << "Reading secret value at secret[" << len << "] = " << value
                 << " with a score of " << score << endl;
            len++;
        }
    }
};

int main() {
    Exp1 exp;  // 实例化类,执行攻击
    return 0;
}
相关文章

相似问题

相关问答用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档