작년에부터 Black Hat Asia의 리뷰보드로 활동하면서 제출된 발표자료를 살펴볼 일이 생겼습니다. 그중에서도 독보적이었던 것이 캐시와 TLB(Translation Look-aside Buffer)를 이용한 부채널 공격(Cache Side-Channel Attack)과 관련된 발표자료였는데요, IEEE Security and Privacy(S&P)와 ACM Conference on Computer and Communications Security(CCS) 등을 거쳐와서 내용 자체는 더할나위가 없는 수준이었습니다. 다만... 제가 부채널 공격을 전혀 모르고 있는 상태였기 때문에, 이 기회에 주요 공격 기법을 정리해봤습니다.

캐시를 이용한 부채널 공격 기법

캐시(Cache)를 이용한 부채널 공격의 요점은 캐시에 데이터가 존재하면 해당 데이터를 DRAM에서 읽어오는 것보다 빠르기 때문에 해상도(Resolution)이 아주 좋은 카운터가 있으면 데이터 접근 시간(Data Access Time)을 측정함으로써 이를 확인할 수 있다는 겁니다. 최근까지 사용된 캐시 부채널 공격 기법은 아래와 같습니다.

Evict + Time 기법

Evict + Time 기법은 공격자가 공격 대상이 접근하는 메모리 영역을 확인하기 위해 시도하는 기법입니다. Evict에서 추측할 수 있는 것처럼 공격 대상이 접근하는 메모리 영역을 모두 캐시에서 제거하고, 공격 대상을 실행해서 특정 동작, 예를 들면 암호 연산(Cryptographic Algorithm)을 수행하고 그에 걸린 시간을 측정하는 것이지요. 만일 Evict된 캐시에 접근한다면 캐시에 존재하는 데이터에 접근하는 것보다 실행 시간이 더 길어지니 이로써 실제로 수행되는 함수나 실제로 접근하는 데이터를 알 수 있습니다. 실제로 OpenSSL AES 알고리즘을 공격하는데 사용되었습니다.

Prime + Probe 기법

Prime + Probe 기법 역시 암호 연산을 공격하는데 사용되었는데요, 시나리오는 아래와 같습니다.

  • 먼저 공격자가 캐시를 기준값(Prime)으로 채워두고,
  • 공격자가 공격 대상을 실행합니다. 이때, 공격대상이 어떤 데이터를 읽었다면 그 데이터가 캐시에 없기 때문에 메모리에서 읽고 공격자가 채워넣은 기준값(Prime)을 Evict한 후에 해당 데이터를 채워 놓습니다.
  • 공격 대상의 실행이 완료된 후에, 공격자가 다시 캐시의 정보를 순차적으로 읽습니다. 이때, 특정 위치에서 시간이 많이 걸린다면, 해당 데이터는 공격 대상에 의해 Evict 되었기 때문입니다. 이를 바탕으로 해당 캐시의 위치를 파악하여 공격 대상이 접근한 메모리의 위치를 확인할 수 있습니다.

Prime + Probe는 공유 메모리가 필요치 않기 때문에, Intel SGX와 같이 고립된 환경도 공격이 가능한 장점이 있습니다. 부채널 공격으로 유명한 Michael Schwarz의 논문에 보면 아래와 같이 표현되어 있습니다.

Prime + Probe Attack - 출처: Software-based Side-Channel Attacks and Defenses in Restricted Environments

Flush + Reload 기법

Flush + Reload 기법은 x86 명령어 중에 clflush를 이용하는 공격 기법인데요, clflush가 논리적 주소(Logical Address)를 기반으로 해당 영역만 캐시에서 Flush할 수 있는 특성을 이용합니다. 공격 시나리오는 아래와 같습니다.

  • 암호 알고리즘이 들어있는 공유 라이브러리(Shared Library)를 clflush로 캐시에서 제거하고,
  • 공격 대상을 실행하여 암호 연산을 실행합니다.
  • 공격자가 공유 라이브러리가 있는 영역에 순차적으로 접근합니다. 이때, 공격 대상이 해당 영역에 접근한 경우, 이미 캐시에 존재하므로 그렇지 않은 영역과 접근 시간의 차이가 발생합니다. 이를 이용하면 접근 시간의 차이를 이용하여 암호 알고리즘이 수행된 실행 흐름이나 접근된 데이터를 확인할 수 있습니다.

Flush + Reload 기법은 물리 주소(Physical Address)를 알 필요가 없는 장점이 있습니다. 아래 그림은 Michal Schwarz의 논문에서 가져온 Flush + Reload 기법과 관련된 그림입니다.

Flush + Reload - 출처: Software-based Side-Channel Attacks and Defenses in Restricted Environments

Flush + Flush 기법

Flush + Flush 기법 역시 clflush를 이용한 기법입니다. Flush + Reload 기법과 차이점은 공격 대상을 실행한 뒤에 캐시에 순차적으로 접근하여 접근 시간을 보는 것이 아니라 순차적으로 clflush를 다시 수행해서 flush 시간을 측정하는 겁니다. 캐시에 데이터가 존재하면 clflush에 걸리는 시간이 길고, 캐시에 데이터가 존재하지 않으면 clflush에 걸리는 시간이 짧은 특성을 이용한 것입니다.

Evict + Reload 기법

Evict + Reload 기법은 clflush가 없는 경우, 캐시에서 알아내길 원하는 정보를 모두 제거하는 Evict를 사용하는 Flush + Evict 기법의 변형입니다. clflush를 직접 쓸 수 없는 Javascript나 clflush 명령어가 없는 ARM 프로세서 등에서 사용할 목적으로 변형된 것이지요.

TLB(Translation Look-aside Buffer)를 이용한 공격 기법

TLB를 이용한 공격 기법 역시 캐시를 이용한 공격 기법과 비슷한데요, 캐시 대신에 TLB를 이용하는 점이 차이점이고 역시나 TLB에 해당 영역의 (논리적 주소->물리적 주소) 맵핑 정보가 저장되어 있으면 접근 시간이 짧다는 특성을 이용합니다. Michal Schwarz가 쓴 Store-to-Leak Forwarding: Leaking Data on Meltdown-resistant CPUs논문에서 Store-to-Load Forwarding과 TLB를 이용하여 주요 정보를 유출하는 예를 보여줬습니다.

Microarchitecture가 그동안 많이 숨겨져 있었고 성능 최적화에 중점을 두고 발전하다보니 보안적인 문제가 다소 있는 것 같군요.

그럼 좋은 하루 되세요. ^^

+ Recent posts