Spectre 취약점: 예측 실행과 캐시 부채널이 만나는 지점
Spectre 취약점의 예측 실행 악용 구조, 캐시 부채널 공격 방식, CVE 변형별 특성과 완화 조치를 정리한다.
2026-08-14 · 최초 발행 2025-06-04
예측 실행의 흔적이 정보 유출 경로가 될 때
Spectre는 2018년 초 공개된 하드웨어 수준 보안 취약점이다. 2017년에 발견됐으며, Intel·ARM·AMD를 포함한 현대 프로세서의 예측 실행 메커니즘을 겨냥한다. 공격자는 CPU 캐시의 상태 변화를 부채널로 관찰해 권한이 없는 메모리 영역의 데이터를 추론할 수 있다.
예측 실행은 성능을 높이기 위해 널리 쓰이는 방식이다. 문제는 잘못된 예측으로 실행한 결과를 CPU가 폐기하더라도, 그 과정에서 바뀐 캐시 상태까지 원래대로 되돌리지는 않는다는 점이다.
분기 예측과 투기적 실행이 남기는 상태
CPU는 분기점에서 다음 경로를 예상해 명령을 미리 실행한다. 예측이 맞으면 그 결과를 사용하고, 틀리면 실행 결과를 폐기한 뒤 올바른 경로를 수행한다.
분기 예측기는 과거 실행 패턴을 바탕으로 경로를 정하고, 그 경로의 명령을 앞서 실행한다. Spectre는 이 예측을 공격자가 원하는 방향으로 유도한 뒤, 투기적으로 수행된 메모리 접근이 캐시에 남긴 흔적을 읽어낸다.
공격 흐름은 다음과 같다. 공격자는 분기 예측기를 특정 패턴으로 훈련하고, 경계 검사를 우회하도록 유도한다. CPU가 권한 없는 영역을 투기적으로 접근하면 해당 데이터와 연관된 상태가 캐시에 남는다. 이후 예측 오류가 확인되어 실행 결과가 폐기되더라도, 공격자는 캐시 접근 시간의 차이를 측정해 정보를 얻을 수 있다.
경계 검사와 간접 분기를 겨냥한 변형
Bound Check Bypass — CVE-2017-5753, Variant 1
이 변형은 배열 경계 검사를 우회한다.
if (x < array1_size) {
value = array2[array1[x] * 256];
}
공격자는 x가 array1_size보다 작은 값으로 코드를 반복 실행해 분기 예측기가 if 조건을 참으로 학습하도록 만든다. 이후 배열 범위를 벗어난 값을 x에 넣어도 CPU가 투기적으로 실행할 수 있으며, array1[x]를 통해 접근 제한된 메모리 값을 노출시킬 수 있다. 그 결과 권한 밖 메모리 데이터를 읽을 가능성이 생긴다.
Branch Target Injection — CVE-2017-5715, Variant 2
Variant 2는 간접 분기의 목적지를 조작한다. 공격자는 분기 예측기의 BTB(Branch Target Buffer)를 오염시켜 CPU가 특정 코드를 실행할 것이라고 잘못 예측하게 만든다. 투기적 실행 중 가젯(Gadget) 코드가 실행되면 정보 유출로 이어질 수 있다.
이 방식은 다른 프로세스나 가상 머신의 데이터 탈취 가능성도 가진다. Variant 1보다 완화 조치의 구현이 더 복잡하다.
캐시 시간 차이를 읽는 부채널
Spectre의 정보 유출은 캐시 부채널 공격에 의존한다. 캐시 적중(hit)은 약 20 사이클, 캐시 미스(miss)는 약 200-300 사이클이 걸린다. 이 접근 시간 차이로 공격자는 특정 데이터가 캐시에 존재하는지 판단할 수 있다.
대표적인 기법은 다음과 같다.
- Flush+Reload: 공유 메모리 환경에서 캐시 라인을 플러시한 뒤 재로드 시간을 측정한다. 고정밀 타이밍 정보를 제공한다.
- Prime+Probe: 공유 캐시 세트에 대한 접근 경쟁을 측정한다. 공유 메모리가 필요하지 않으며, Flush+Reload보다 노이즈는 많지만 적용 범위가 넓다.
- Evict+Time: 특정 캐시 라인을 제거한 뒤 대상 프로세스의 실행 시간 변화를 분석한다.
경계 검사 우회 코드의 형태
다음 코드는 Bound Check Bypass 공격에서 분기 예측기를 훈련하고, 배열 범위 밖 접근 뒤 캐시 상태를 확인하는 흐름을 보인다.
// 공격자가 분기 예측기 훈련을 위한 코드
for (i = 0; i < 10; i++) {
_mm_clflush(&array1_size); // 캐시에서 array1_size 제거
victim_function(i); // 유효한 인덱스로 반복 호출
}
// 이후 배열 범위 밖 접근으로 비밀 정보 유출
victim_function(malicious_x); // malicious_x는 배열 범위 밖 값
// 캐시 상태 분석으로 유출된 데이터 확인
for (i = 0; i < 256; i++) {
time = measure_access_time(&array2[i * 4096]);
if (time < threshold) // 캐시 적중 = 접근된 값
printf("유출된 바이트: %d\n", i);
}
브라우저에서는 JavaScript를 이용해 다른 탭의 비밀정보를 노릴 수 있고, 클라우드 환경에서는 가상 머신 간 격리 우회를 통해 다른 테넌트의 데이터에 접근하는 시나리오가 거론된다. 커널 메모리 접근을 통한 권한 상승 시도나 SSL/TLS 개인키 같은 중요 암호 자료의 추출도 위험 범위에 포함된다.
완화 조치와 성능의 교환
대응은 하나의 계층에서 끝나지 않는다. 제조사 펌웨어 패치인 마이크로코드 업데이트, KPTI(Kernel Page Table Isolation)와 IBRS(Indirect Branch Restricted Speculation)를 포함한 커널 수준 완화, Retpoline과 스펙터 감지 명령어 삽입 같은 컴파일러 방어가 함께 사용된다. 브라우저는 Site Isolation과 JavaScript 타이머 정밀도 저하로 공격 조건을 줄인다.
이 조치들은 성능 비용을 수반할 수 있다.
- KPTI 적용 시 5-30% 성능 저하가 발생할 수 있으며 워크로드에 의존적이다.
- Retpoline 적용 시 0-10% 성능 저하가 발생할 수 있다.
- 마이크로코드 업데이트 후 5-15% 성능 저하가 발생할 수 있다.
- 클라우드 환경에서는 더 큰 성능 영향이 발생할 수 있다.
장기적으로는 CPU 설계 자체의 변경이 필요하다. 새 CPU 세대에서 아키텍처 수준의 보호 기능을 구현하고, 컨텍스트 간 격리 메커니즘을 강화해야 한다. 성능 최적화를 무조건적으로 우선하기보다 보안과의 균형을 설계 단계부터 고려하는 방향도 요구된다.
프로세서 보안 모델에 남긴 변화
Spectre는 모든 주요 프로세서 제조사인 Intel, AMD, ARM에 영향을 미치며 클라우드 서비스의 보안 모델 재평가를 촉발했다. 하드웨어 수준 취약점과 마이크로아키텍처 부채널 공격의 중요성이 부각됐고, 소프트웨어만으로 완전한 보안을 달성하기 어렵다는 인식도 커졌다.
30년 이상 사용된 예측 실행의 보안 취약성을 드러낸 사건이기도 하다. 완전한 해결에는 하드웨어 설계 변경이 필요하며, 단기적으로는 성능과 보안 사이의 타협이 불가피하다. 하드웨어·OS·애플리케이션 계층이 함께 방어해야 한다는 점에서 Spectre는 컴퓨터 아키텍처 설계의 가정을 다시 검토하게 만든 전환점이다.