플런더볼트(PlunderVolt)는 CPU에 전압을 적게 가할 때 발생하는 불안정성을 활용하여 Intel SGX(Software Guard Extension)를 공격하는 보안문제의 애칭입니다. 2019년 12월에 발표되었고, 기글에도 소개된 바가 있습니다. ( https://gigglehd.com/gg/hard/6206037 )
이 공격을 통해서 특정 명령어의 실행을 뛰어넘게 만드는 등 잘못된 행동을 할 수 있으며, 이 문제는 다른 소프트웨어 결함이나 권한에 의존하지 않고, 값 비싼 실험실용 장비가 필요하지도 않다는 점이 강점이라고 언급하고 있습니다. 특히 암호화 키, 생체정보와 같은 데이터를 쌩판 다른 프로세스가 접근하지 못하도록, 보호된 영역을 만들어주는 SGX 체계를 무너뜨리고, 그곳에서 정보를 추출할 수 있게 만들어 주는 것이 문제였을 겁니다.
인텔은 이 보안 문제를 해결하기 위해 BIOS와 마이크로코드 업데이트를 통해 전압 조절을 수행할 수 있는 인터페이스를 막아버리는 방식으로 대응했습니다. 원래 인텔 CPU는 충분한 사용자 권한(=MS Windows로 따지면 관리자 권한)으로 동작하는 소프트웨어에서 접근 가능한 MSR(Model-Specific Register) 0x150을 통해 전압 오프셋을 수정할 수 있었는데, 이걸 사용하지 못하게 막아버린 것이죠.
물론 뛰어난 엔지니어들이 고심 끝에 만들어 낸 효과적인 방안이었겠지만, 단순 사용자인 저에게는 너무 순진한(naive) 방법이 아닌가 하는 생각이 들었습니다. 이러한 해결 방법으로 인해, 상당수의 인텔 유저들은 그들의 10세대 CPU에서 언더볼팅을 할 수 없게 되었지요. BIOS에서 별도의 전압 설정이 포함되지 않기도 하고, 발열에 신경쓰는 랩톱 사용자에게는 더욱 치명적일 것입니다.
사실 SGX는 그 사용처가 일반 사용자에게는 그리 많지 않습니다. 가장 활용도가 큰 것은
1. 지문인식 등 생체 정보 활용 소프트웨어
2. Ultra-HD 블루레이의 DRM
정도를 꼽을 수 있습니다.
때문에, 플런더볼트를 통해서 발생하는 직접적인 위협은 단일 호스트에서 다중 사용자를 받아들이거나, 하드웨어 기반의 가상화 솔루션을 사용하는 퍼블릭 클라우드 서비스의 사용자들에게 있었을 것입니다. 같은 시스템을 사용하고, 누군지도 알 수 없는 다른 가상 머신 사용자가 보호된 영역의 데이터를 읽을 수 있게 된다는 건 꽤나 치명적인 문제라고 할 수 있습니다.
이미 해결책이 나름대로 주어진 플런더볼트와 관련된 주제를 언급한 이유는, 사실 그냥 호기심에 살펴본 글이 재밌길래 공부하는 셈 치고 같이 정리해봤습니다. 참고로 저는 하드웨어는 쥐뿔도 모르는 일반인이라 제가 잘못 읽거나 잘못 이해한 부분이 있을 수 있습니다. 적극적인 지적은 언제나 환영입니다.
이제 이 이야기의 시작을 살펴볼까요.
2021년에 열릴 Usenix에 이 언더볼팅을 사용해서 SGX를 공격하는 새로운 기법에 대한 논문이 발표되었습니다:
영국 버밍험대에 박사과정으로 재학중인 Zitai Chen과, Flavio Garcia 교수 연구팀이 발표한 논문으로,
"VoltPillager: Hardware-based fault injection attacks against Intel SGX Enclaves using the SVID voltage scaling interface" 라는 제목으로 공개되었습니다. (참고-링크를 클릭하여, Read Paper를 눌러 논문 전문을 보실 수 있습니다.)
소프트웨어로 접근할 수 있는 채널을 막아버렸는데 어떻게 가능하냐구요?
이 논문은 $30 짜리 "하드웨어"를 사용해서 인텔 SGX의 Enclave 영역을 공격하는 방법을 담고 있습니다.
이제 제가 호기심이 가던 순서대로, 논문의 내용을 인용해서 끄적여보겠습니다.
* 초록
논문의 초록은 아래와 같이 적혀있네요. 얼마나 호기심을 자극할지 모르겠습니다만, 초록을 읽는다는 것은 그 논문의 반을 보는 것과 같(거꾸로 뒤집으면, 반을 했다는 것은 이제 시작이라는 뜻입니다.)으니, 한번 간단하게 번역을 해 보았습니다:
전압이나 클럭 글리칭과 같은 하드웨어 기반의 결함 주입(Fault-Injection) 공격은 그동안 임베디드 기기를 위해 철저히 연구되어 왔습니다. 이런 공격들은 주로 스마트 카드(smartcards)나, IoT 장치에 사용되는 저전력 마이크로 컨트롤러를 대상으로 삼았습니다.
(하지만) 이 논문은, 완전히 발달한 인텔 CPU를 대상으로 하드웨어 기반의 글리칭 공격을 다룹니다. 이렇게 복잡한 CPU로의 전환은 복잡한 운영 체제, 큰 전력 소모량, 멀티 스레딩, 그리고 높은 클럭 스피드와 같은 여러가지 인자들로 인해 쉽게 접근 가능한 문제가 아니라고 볼 수 있습니다.
이 때문에, 우리는 CPU와 메인보드의 전압 레귤레이터 사이를 연결하는 SVID(Serial Voltage IDentification) 버스에 메시지를 주입할 수 있는 저렴한 도구인 VoltPillager(Pillager: 약탈자)를 만들었고, 이것은 CPU의 코어 전압을 정밀하게 컨트롤하게 해 줄 것입니다.
이 강력한 도구를 통해, 인텔 SGX Enclave의 무결성과 기밀성을 깨트릴 결함 주입 공격을 선보입니다. SGX 안에서 동작하는 암호화 알고리즘을 대상으로 암호 키 복원(Key-recovery) 공격을 전개하여 우리가 제시한 개념을 증명할 것 입니다. 더불어, 소프트웨어 언더볼팅 문제에 대응되는 모든 방법을 패치한 시스템을 대상으로 삼아, VoltPillager를 통한 공격이 SGX를 대상으로하는 소프트웨어-단독 언더볼팅 공격(CVE-2019-11157)보다 훨씬 강력하다는 것을 보여드릴 겁니다.
덧붙여, 우리는 메모리의 쓰기 동작을 지연시킴으로, 보안-필수(*security-critical) 명령을 실패하게 만들 수 있었습니다. 본 연구에서 제시된 VoltPillager의 완화책은 그리 간단하지 않을 것이고, 신뢰하기 어려운 클라우드 제공자가 하드웨어에 물리적으로 접근할 수 있는 환경과 같은 SGX-적대적 모델을 재고해야 할 것입니다.
* 실험에 사용된 환경 소개
연구팀은 인텔 7세대~9세대 사이의 CPU와, 이를 지원하는 메인보드를 가지고, 플런더볼트 취약점을 해소하는 패치를 모두 적용한 시스템을 대상으로 실험을 진행했습니다. 아래 표 1은, 실험에 사용된 CPU와 베인보드, 그리고 마이크로코드 버전, 전압 레귤레이터 IC, 그리고 SMBus에 연결된 전압 레귤레이터의 주소를 나타내고 있습니다.
초기에는 4대의 시스템으로 세팅했는데, Gigabyte Z170X Gaming 3 메인보드와 i3-7100을 사용한 녀석은 실험중 부주의로 SVID 라인을 쇼트시키는 바람에, 메인 실험으로는 쓰지 못하고 SVID의 리버스 엔지니어링 용도로 사용했다고 합니다.
* 인텔은 어떻게 CVE-2019-11157(=플런더볼트)를 해결했었나
본 논문에서, 인텔은 다음의 두가지를 통해 2019년도에 나온 플런더볼트 보안 문제를 해결했다고 밝히고 있습니다:
(1) BIOS 제공 업체가 부팅 시점에 언더볼팅을 사용할 수 없도록 막는 기능을 추가
(2) 마이크로코드 업데이트를 통해서, 소프트웨어 언더볼팅이 활성화 되어 있을 경우 SGX가 동작하지 않도록 원격 증명 절차를 추가. 언더볼팅이 활성화 되어 있으면, SGX를 초기화하는 시점에 오류에 속하는 반환 값인 CONFIGURATION_NEEDED(구성 설정 필요)를 반환시켜 SGX를 사용하는 소프트웨어가 동작하지 않게 만들었습니다.
문제는 (1)인데, BIOS 수준에서 이걸 못쓰게 만드는건 상세 구현이 회사마다 제각기 달라서 어디는 여전히 언더볼팅이 가능했고, 어디는 BIOS에서 수동으로 설정할 수 있게 했으며, 또 어디는 수정할 수 있는 구석이 없이 완전 다 막았(... 대표적으로 DE-_-LL이 있습니다)습니다. 이처럼, 메인보드/노트북 제조사마다 전압 조정 여부가 판이하게 나뉘게 되었습니다.
핵심은 이미 (2)로 어느정도 보완이 된 셈이었지만, 그렇다고 있는 기능을 못쓰게 만들어서는 안되니 (1)이 필요하기도 하다는 것을 알 수 있습니다만.. 대체 뭐가 문제였을까요.
* CPU의 전압 조정은 어떻게 이루어지나/SVID에 대한 이해 (논문 3, 3.1)
저 말고는 다 알고계시는 사항이겠지만, 메인보드와 CPU 사이는 한개 이상의 전압 레귤레이터(이하 VR로 지칭)와 연결되어 있다고 합니다. 그리고 코어 전압을 바꿔가면서 성능과 전력 소모 사이를 줄타기하고 있지요. 일이 없을 때는 VR에게 전압을 낮추라고 명령을 내리고, 일이 많을 때는 반대로 VR에게 전압을 더 주라고 이야기를 하게 됩니다. 우리가 주로 사용하는 x86 시스템은 아래와 같은 형태로 전압을 공급하게 됩니다:
위의 그림의 왼쪽이 CPU, 오른쪽이 VR입니다. 직접적으로는 SVID 인터페이스를 통해서 연결되어 있고, 보조적으로 (대충 메인보드 제조사에 따라 다르다는 뜻) SMBus를 통해서 연결되기도 합니다. VR은 아래의 펄스 폭 변조(PWM) 드라이버를 통해 CPU의 코어 전압을 조정하는 것이지요.
그럼 SVID(Serial Voltage Identification)는 뭘까요?
CPU는 VR 직접회로에 "내가 얼마의 전압이 필요한지" 명령을 내리기 위해 SVID 인터페이스를 사용합니다. 해당 연구진은, 인텔 CPU의 데이터시트로부터 3개의 핀을 사용하여 통신을 한다는 것을 확인하였습니다. 하나는 클럭 신호를 줄 VLCK, 다른 하나는 통신할 데이터를 주고받을 VDIO이고, 마지막 하나는 ALERT#가 됩니다. 여기서 VLCK/VDIO는 일종의 회로간 직렬 통신(I2C) 형태로 통신하는 전이중 방식의 연결 인터페이스고, ALERT#이 전압 변경의 완료를 알리는 인터럽트 같은 역할과 행동을 하는 것으로 확인했습니다. VLCK/VDIO는 25MHz 클럭으로, 0~1볼트 사이의 전압을 사용해 메시지를 전달한다고 합니다.
25Mhz라고 해서 띠용 이렇게 빠르게... 라고 생각했는데 잠깐 코어가 기가 단위의 클럭을 쓴다는 걸 잊고 있었습니다. 암튼...
* 메인보드에서 전압 레귤레이터를 찾는 방법 (논문 3.1), 리버스 엔지니어링
이제 메인보드에서 CPU와 연결되는 전압 레귤레이터(다시, 줄여서 VR로 기재) IC가 어디있는지를 알아야 추가적인 연구가 가능할 것입니다. 가능하면 메인보드 업체가 도식(schematic)을 만들어놓고 막 주고 그러면 좋을텐데, 킹반인인 연구자들 입장에서는 그런 문서가 아마 있어도 구할 수 없었을 것입니다. 암튼 없는 와중이지만, 연구자들은 경험상 VR이 CPU 근처에 가깝게 붙어 있을 것이고, 육안으로 살펴보고 프로브로 쉽게 찍어볼 수 있게 근처에 커다란 스위칭 트랜지스터와 인덕터가 있을 것이라고 생각했다 합니다. 추가로, SVID 역시 분석이나 테스트 편의를 위해 쉽게 붙일 수 있도록 작은 저항으로 연결되어 있는 경우가 많았다고 합니다.
위의 Figure 2가 그렇게 찾아낸 VR IC라고 합니다. CPU는 전압 레귤레이터의 오른쪽에 있었다고...
암튼 이제 핀까지 확인했으니 연구진들은 SVID를 어떻게 조정했는지 프로토콜 역분석을 수행하게 됩니다.
연구자들은 오실로스코프와 로직 애널라이저를 사용하여 SVID 버스를 통해 전달되는 내용을 파악했고,
Zeroplus의 SVID 로직 애널라이저의 스크린샷(!)을 참고하여 최종적으로 SVID 프로토콜 중 전압 출력을 조절할 수 있는 방법을 알아내게 됩니다.
아래의 사진이 바로 연구팀이 참고한 Zeroplus의 로직 애널라이저 스크린 샷입니다. 저는 저걸 보고 <저놈들은 저걸로 저런 생각이 나냐...> 라는 생각이 먼저 들었습니다.
* 일부 메인보드에서 전압 조정을 위해 사용되는 SMBus (PMBus; Power Management Bus)를 통한 접근 방법 분석
주로 서버/게이밍 메인보드(실험에서는 애즈락, MSI 보드)에서 SMBus를 사용하여 전압을 조정하는 방법이 있었다고 합니다. SMBus는 1MHz의 클럭으로 동작하고, SVID에서 내린 명령을 무시하게 할 수 있었다고 합니다.
대개 메인보드 제조사에서 제공하는 전압 조정 소프트웨어와 SMBus에 프로브를 대고 분석하는 방법으로 알아낼 수 있었다고 하네요. 그렇지만, SVID에 비해 클럭 주기가 기니 속도가 느려 정확하게 Fault를 주입하기 어렵고, 전압 레귤레이터 마다 다른 명령어를 사용해서 범용적으로 쓰기가 어렵기 때문에 SVID를 사용하는 방법을 최종적으로 사용하게 되었습니다.
* SVID 명령어를 주입할 때 쓸 하드웨어의 구성과 공격의 상세
1) Teensy 4.0 개발 보드 = $22
2) 버스 드라이버 / 버퍼 * 2 = $1
3) SOT IC 어댑터 * 2 = 6개에 $13
도합 $36 되겠습니다.
연구팀은 초기에 GPIO 핀을 사용해서 프로토콜을 구현하려고 했는데, SVID가 생각보다 빠른 클럭(25Mhz)을 사용해서, 600MHz로 동작하는 ARM Cortex-M7으로는 어렵다는 결론에 도달합니다. 이를 해결하기 위해 Teensy 4.0에서 제공하는 SPI(직렬 주변기기 인터페이스) MODE 2를 사용했고, 마침내 SVID 버스에 메시지를 주입할 수 있게 되었다고 합니다.
대충 어떻게 붙였냐면..
솔직히 저는 아무것도 모르겠습니다. 아아...
아무튼, 사진의 메인보드는 분석에 사용한 기가바이트 Z170X 게이밍 3에 i3-7100이 붙어 있는 것입니다. 프로그램의 구현은 아두이노 IDE에 기본적인 SPI 기능을 제공하는 Teensyduino 라이브러리를 사용했다고 하네요. 여기에 명령을 내릴 컴퓨터를 따로 연결하고, 전압 강하 명령을 내려서 글리칭을 시도합니다.
위의 그림은 Fault를 일으킬 수 있도록 언더볼팅을 걸때 발생하는 파형입니다. V_cc/V_p/V_n이 평소의 정상적인 CPU 코어 전압이고, V_f가 오류를 일으킬 목표전압입니다. 전압을 강하시켰을 때, 오류가 발생하는 구간은 시간 축에서 T_f에 해당합니다. 저 T_f 구간에 필요한 부분의 연산이 걸리기를 희망하는 셈입니다. 논문에서, 실험에 성공한 T_f 구간이 대충 35마이크로초, 그러니까 7/200,000 초 군요.
게다가 V_f의 설정이 까다로운 건 코어가 얼마나 잘뽑히냐에 따라서도 달려있겠군요. 너무 낮으면 공격을 하기도전에 시스템이 뻗거나 재부팅이 일어날 거고, 너무 높으면 오류가 잘 안 생길거구요.
암튼 i3-9100 + MSI Z370-A Pro 보드에서는, V_p = V_n = V_cc 가 보두 1.05볼트고, 언더볼팅 오류를 일으키는 전압 V_f가 0.810V 였다고 하네요. -240mV는 좀 과한 전압 오프셋이긴 하지요? 안 뻗은게 신기할 정도..
여기서 플런더볼트를 증명할 때 사용했던 테스트 방법과, AES-CBC 암호화 간에 오류를 일으켜 16코어 CPU에서 2분정도의 계산을 통해 키를 복원하는 공격을 성공했다고 밝히고 있습니다.
뭐 유튜브의 동영상에서는 그냥 fault만 일으키는 것을 보여주고 있습니다. 요 실험은 정상 전압인 0.7V를 30 마이크로초 간, 오류를 일으킬 V_f를 0.64V를 가했다고 하는군요.
보시고 싶으신 분은 아래의 URL로 보실 수 있습니다.
https://www.youtube.com/watch?v=8BL5UREpWCE
* 연구자들이 해당 보안 문제를 완화할 수 있는 방법으로 생각한 것들과 논문의 결론
해당 논문의 연구자들은 이 보안문제를 완화하기 위해 다음의 방법들을 생각해보았다고 합니다:
1) SVID 프로토콜 수준에서 암호화나 다른 인증 체계를 포함시키는 것
--> 이건 전압 레귤레이터를 직접 가져다 붙여서 제어하는 방법으로 우회가 가능
2) CPU 하드웨어나 마이크로코드 수준에서 완화 방법
가. CPU 수준에서 SVID 패킷 인젝션을 탐지, 강제로 실행을 중단시키는 메커니즘을 추가
--> 논문에서도 잠깐 밝히고 있는데, 패킷을 주입하는 대신 아예 FPGA를 붙여서 SVID 신호를 가로채서 통제하는 man-in-the-middle 공격까지 탐지하는건 불가능 할 것이라 이야기하고 있습니다. 비록 자기네들은 실험하다가 SVID 신호 클럭에 맞춰서 잘 동작하는걸 못 만들어서 도중에 그만두었다고 하지만요.
나. CPU가 스스로 전압을 체크하고, 기준선 이하로 떨어질 경우 실행을 중단시키는 방법
--> 평균 전력 제한 인터페이스와 MSR 0x198을 사용할 수 있을 법한데, 문제는 이게 끽해봐야 1kHz.. 그러니까 0.001초, 앞서 이야기한 Fault 유도 시간을 T_f = 7/200,000 초 = 35us라고 생각한다면 샘플러가 이 구간을 감지하기 어렵다는 문제가 있습니다.
그래서 이후의 CPU는 스마트카드에서 종종 볼 수 있는 전압 모니터링 회로가 부가될 수도 있을거라고 이야기하네요. 4세대 인텔 CPU처럼 전압 레귤레이터를 통합.. 그러니까 FIVR을 쓰는 옵션도 있긴한데, 요건 FIVR에 가하는 전압은 여전히 밖에서 악의적으로 변조를 가할 수 있을테니 좀 더 고민할 거리가 있다고 이야기하고 있습니다.
3) Enclave 코드 상에서의 완화방법
이건 SGX를 사용하는 어플리케이션 레벨에서의 완화방법인데, 앞서 이야기한 바 대로 샘플링해서 T_f 구간에 해당 코드가 걸릴 때까지 돌리고 기도하는 방식이니, 컴파일러 수준에서 자동으로 2번 이상의 명령어 중복 생성과 비교 루틴을 포함하는 방식으로 완화하는 것을 생각해볼 수 있다고 합니다.
읽다보니, 인텔 SGX의 보안 모델 자체가 BIOS나 외부 하드웨어를 믿지 않기 때문에, 앞서 언급한 대로 단순히 언더볼팅을 차단하는 것 말고는 방법이 없었을 듯 싶기도 하다는 생각이 들었네요. 암튼 제 수준은 여기까지.
이제 해당 연구자들이 결론에서 이야기하는 주장을 번반역하면서, 이 글을 마치고자 합니다.
" ... 이런 유형의 공격을 완화하지 않기로 한 제조업체(인텔)의 결정과 함께, 이 논문의 결과를 통해서 우리는 "Enclave된 실행 방법"이 신뢰할 수 없는 원격 플랫폼에서 민감한 컴퓨팅을 아웃소싱할 수 있게 만드는 수단이라는 약속과, 그에 대한 믿음이 여전히 유효한 것 인지 다시 생각해봐야 할 것이라고 생각합니다."
(원문: The results in this paper, together with the manufacturer’s decision to not mitigate this type of attack, prompt us to reconsider whether the widely believed enclaved execution promise of outsourcing sensitive computations to an untrusted, remote platform is still viable.)
* 참고: 논문의 발표에 대하여
2020년 3월 13일, 연구팀은 인텔에 해당 문제를 보고한 바 있습니다. 그리고 5월 5일에 다음과 같은 응답을 받았습니다:
" ... SGX를 위태롭게 만들기 위해 케이스를 열어서 내부 하드웨어를 변경하는 것은 SGX 위협 모델 밖의 것입니다. CVE-2019-11157(PlunderVolt)를 위한 패치는 이러한 위협 모델을 근거로, 하드웨어 기반의 공격을 방어하도록 디자인되어 있지 않습니다. "
(원문: " ... opening the case and tampering of internal hardware to compromise SGX is out of scope for SGX threat model. Patches for CVE-2019-11157(Plundervolt) were not designed to protect against hardware-based attacks as per the threat model")
이러한 이유로, 인텔은 이 문제를 더 이상 고심하지 않을 것이라고 논문에서는 이야기 하고 있습니다. 또한, 별도로 엠바고를 요청하지도 않은 터라, 이 논문이 밖으로 나올 수 있었던 것으로 보입니다.
* 마치며/사견
대충 같이 보신바와 같이 믿을만한 클라우드 사업자나 호스팅 업체라면 걱정하지 않아도 될 문제일 성 싶기도 합니다. 게다가, 이 문제가 해결되지 않는다고 해서, 당장 사용자에게는 치명적이지는 않을 것이라 생각합니다. 하지만, 읍읍과 같이 믿을 수 없는 지역에 실제 머신이 배치되어 있고, 이에 접근할 수 있다고 생각하면 어음... 혹시 알아요? 전력을 싸게 공급할 테니 데이터 센터 막 유치... 이러면 음... 괜한 기우이긴 하지만 대충 상상가능한 범주에 속하긴 하네요.
침소봉대할 그런 아이템은 아닌듯 싶고, 그냥 재미삼아서 보시고 앞으로 인텔이나 다른 칩 설계사들이 어떤 방식으로 해소해 나갈 것인지를 관전자 시점에서 보면 괜찮지 않을까 싶습니다.
개인적으로는, 다른 자료를 찾다가 호기심에 읽기 시작했는데, 우연하게 CPU의 전압 조정에 대한 이해와 함께 저렇게 외적인 방법으로 공격을 수행하는 벡터가 있다는 것 대한 생각을 좀 더 넓힐 수 있었던 기회를 받았다는 생각이 드는 논문이었습니다.
긴 글 읽어주셔서 고맙습니다.