상세 컨텐츠

본문 제목

인텔 CPU 취약점(Meltdown & Spectre) 상세분석

악성코드 분석 리포트

by 알약(Alyac) 2018. 1. 10. 16:34

본문

이스트시큐리티에서는 인텔 취약점 (Meltdown&Spectre)에 대해 1차분석을 진행한 적이 있었습니다. 

(▶ 인텔 CPU 취약점(Meltdown&Spectre) 분석 및 이스트시큐리티 대응상황)


하지만, 취약점에 대한 난이도나 그 위험도가 높은만큼, 인텔 취약점 (Meltdown&Spectre)에 대해 상세분석을 진행하였습니다. 



개요 


이번에 공개 된 Meltdown & Spectre 관련 취약점은 아래 3개입니다.


Variant 1: bounds check bypass (CVE-2017-5753)

Variant 2: branch target injection (CVE-2017-5715)

Variant 3: rogue data cache load (CVE-2017-5754)


Variant 1, 2는 Spectre 취약점이며 Variant 3은 Meltdown 취약점 입니다. 




동작 분석

Variant 1: bounds check bypass (CVE-2017-5753)

해당 취약점은 CPU의 추측에 의한 코드가 미리 실행되는 최적화 기술(Speculative execution)의 맹점을 이용, 캐시된 상태를 추론하는 방법으로 비인가된 메모리 영역의 값을 유추합니다.

예를 들어, 아래 ‘취약한 코드 예시[1]’ 같은 배열의 크기를 넘어서는 인덱스를 참조하려는 경우 조건에 의해 논리적으로는 해당 메모리 공간은 접근되지 않습니다.

그러나 표현된 코드의 의도와는 다르게, 최신 프로세서는 빠른 실행을 위해 조건 검사 시점에서 병렬 프로세싱으로 조건문 내부의 코드를 미리 실행하여 준비해두고, 만약 조건이 맞지 않을 경우 미리 실행된 상태를 버리는 방식으로 동작하게 됩니다.

다만 이 과정에서 프로세서는 미리 실행된 상태만 버릴 뿐, 빠른 메모리 재접근을 위한 캐시 상태는 그대로 두게 되는데, 만약 악의적인 목적으로 배열의 인덱스를 비인가 메모리 영역으로 참조하게끔 구성한다면 비록 코드는 실행되지 않더라도 비인가된 메모리 영역이 캐시 상태에 남게 됩니다.

이 때 본 취약점의 원리는 메모리 접근 명령어를 실행하는데에 걸리는 시간을 측정하여 대상 주소가 캐시된 상태인지 추론하는 아이디어를 이용, 지정한 비인가 메모리 영역의 값을 추론하는 방법을 이용합니다.

Figure 1. 취약한 코드 예시[1]

<출처 : https://spectreattack.com/spectre.pdf>



Variant 2: branch target injection (CVE-2017-5715)

해당 취약점은 프로세서 예측 실행 기능 중 간접 분기 예측기를 이용합니다. 

이 예측기는 간접 분기문을 해석하기 전 실행 된 분기문의 주소와 목적지 주소로의 매핑을 유지해주는 프로세서 분기 대상 버퍼(BTB)를 사용해 간접 분기문의 목적지 주소를 예측 실행합니다. 이 때 동일한 프로세서에서 실행되는 프로세스들은 BTB가 공유되기 때문에 BTB를 사용한 예측 실행 시 프로세스들 간 영향이 발생 될 수 있습니다.

공격자는 자기 프로세스 간접 분기문의 목적지 주소를 희생자 프로세스 내부 가젯 주소로 분기하도록 변경하고 실행시켜 분기 예측 실패를 통해 프로세서의 BTB를 수정시키게 됩니다. 이렇게 수정 된 BTB는 공격자 프로세스 간접 분기문과 동일한 위치에 있는 희생자 프로세스 간접 분기문이 예측 실행 될 때 영향을 주게 됩니다. 추가적으로 설명하면 공격자 프로세스 간접 분기문에서 예측 실패 시 캐시는 버려지지만 BTB에 미쳤던 영향은 제거되지 않기 때문에 이런 문제가 발생하는 것 입니다.

그 후, 희생자 프로세스 간접 분기문이 예측 실행 될 때 BTB에 저장 된 목적지 주소는 가젯 주소이기 때문에 실제 목적지 코드가 아닌 가젯 코드를 예측 실행하게 됩니다. 예측 실행 된 가젯 코드는 공격자가 원하는 메모리 값을 캐시로 가져오게 되며, 그 이후엔 Variant 1에서 사용 된 기술과 유사한 CLFLUSH 명령어를 사용하는 Flush+Reload 기술로 공격자가 원하는 위치의 희생자 프로세스 메모리 값을 알 수 있게 되는 것 입니다.


Variant 3: rogue data cache load (CVE-2017-5754)

멜트다운은 인텔 microarchitectural을 타겟으로 하는 공격으로서, 비순차적인 실행 방법을 이용하는 사용자의 커널 메모리를 유출시킬 수 있습니다.

공격자는 멜트다운 취약점을 이용해 프로세서에 있는 권한 상승 취약점을 공격합니다. CPU의 예측 실행 기능을 이용하면 공격자가 메모리 보호를 우회할 수 있기 때문입니다

해당 취약점을 이용하면 사용자 공간에서 커널 메모리에 접근하도록 허용합니다. 이는 즉 사용자가 시스템 내부에 존재하는 보안 매커니즘(심지어 커널에 포함되어 있는 내용)과 관련된 다양한 코드 등에 접근할 수 있도록 허용하여 다양한 정보들이 유출될 가능성이 있습니다. 


Mitigation 방안

이번 CPU결함과 관련되어 운영체제 커널에서 패치가 어떻게 이뤄졌는지 분석해보았습니다. 리눅스는 커널 소스가 공개되어 있기 때문에 쉽게 확인할 수 있으나, 윈도우는 소스코드가 공개되어 있지 않기 때문에 윈도우를 살펴보았습니다. 분석 방법은 패치가 이루어진 뒤의 커널 바이너리를 확보하여 주요 핵심 포인트를 짚어보는 방식으로 진행했습니다. 또한 데스크탑에서 주로 사용되는 Intel과 AMD CPU를 중점으로 확인했습니다.

결론부터 말하면 Windows는 유저모드에서 커널모드로 진입하는 부분에 대해서 패치를 진행했고, 패치 내용은 크게 3가지로 볼 수 있습니다.

약점 

해결법 

해당되는 Desktop CPU 벤더 

 Meltdown Variant 3

(Rogue Data Cache Load)

 KPTI

(Kernel Page Table Isolation)

 Intel

(MS는 AMD에도 패치를 시행하였음)

 Spectre Variant 1

(Bounds Check Bypass)

 LFENCE instruction

 Intel, AMD

 Spectre Variant 2

(Branch Target Injection)

- Enable Intel IBRS 

(Indirect Branch Restricted Speculation)

- Enable Intel IBPB 

(Indirect Branch Predictor Barrier)

- Enable Intel STIBP 

(Single Thread Indirect Branch Predictors)

- Return trampoline


 Intel




KPTI (Kernel Page Table Isolation) mitigation for Meltdown Variant 3

윈도우는 원래 64비트에서 KiSystemCall64와 KiSystemCall32를 시스템 콜 핸들러로 사용하고 있습니다. 그런데 이번 meltdown에 대응하기 위하여 윈도우 운영체제가 부팅될 때 KPTI가 필요한 CPU일 경우 아래와 같이 조건부로 커널 시스템 콜 핸들러가 사용될 수 있도록 했습니다.


 
인텔 CPU의 경우 아래의 시스템 콜 핸들러가 사용됩니다.

KiSystemCall32Shadow
KiSystemCall64Shadow

AMD CPU의 경우 아래의 시스템 콜 핸들러가 사용됩니다.

KiSystemCall32AmdShadow
KiSystemCall64AmdShadow

Meltdown 취약점은 인텔CPU에만 발생하는 것으로 알려져 있고, AMD측은 Meltdown 취약점은 AMD CPU에서 재현되지 않았다고 발표했습니다. 

그러나 실제 윈도우 커널 내부를 살펴보면 AMD CPU에 대응해서도 패치를 진행했다는 사실을 확인할 수 있습니다. 이것이 AMD CPU에서도 Meltdown 이 발생한다는 것을 증명하는 것은 아니나, MS는 결론적으로 AMD CPU를 사용하는 시스템을 위해서도 강제로 패치를 단행한 것으로 판단됩니다. (MS가 AMD CPU를 대상으로 해서 패치를 단행한 이유는 내부 사정이라 알 수 없습니다) 

따라서 AMD CPU에서도 커널 시스템 콜을 많이 호출하는 작업일수록 일부 성능 저하가 예상됩니다.

MS는 시스템 콜뿐만이 아니라 인터럽트나 예외 핸들러 등 커널로 진입하는 모든 핸들러에 대해서도 KPTI 패치를 단행하였는데, 이번 CPU취약점과 관련된 코드는 모두 KVASCODE라는 섹션에 따로 두어서 관리하고 있는 모습을 확인할 수 있습니다.

 



시스템 콜, 예외처리 핸들러, 인터럽트 핸들러 등 유저모드에서 커널로 진입하는 코드들을 살펴보면 아래와 같이 공통적인 부분을 발견할 수 있습니다.


Figure 2. 인텔 CPU를 위한 시스템 콜 진입점 코드의 일부

 


Figure 3. AMD CPU를 위한 시스템 콜 진입점 코드의 일부




Figure 4. 페이지 폴트가 발생했을 때 호출되는 페이지 폴트 핸들러 코드의 일부



Figure 5. NMI 인터럽트가 발생했을 때 호출되는 인터럽트 핸들러 코드의 일부


위 코드들의 공통점을 살펴보면, 특정 조건이 만족될 경우 GS:7000h에서 읽어온 값을 CR3 레지스터에 값을 넣고 있는 모습을 확인할 수 있습니다. 

CR3레지스터는 프로세스 페이지 테이블의 물리 주소를 가지고 있는 레지스터입니다. 원래 이번 보안패치가 이뤄지기 전의 윈도우 운영체제는 프로세스마다 페이지 테이블을 가지고 있었고 이것을 유저모드와 커널모드가 같이 사용하고 있었습니다.

이번에는 커널모드에서 유저모드로 되돌아가는 부분의 코드를 보겠습니다.




Figure 6. 커널모드 시스템 콜 호출 후 유저모드로 되돌아가는 부분의 코드


커널모드에서 유저모드로 되돌아갈 때 CR3값을 유저모드 페이지 테이블 주소로 돌려놓는 것을 확인할 수 있었습니다.

따라서 이번 패치가 적용된 이후로 유저모드와 커널모드 페이지 테이블이 서로 따로 관리되고 있음을 확인할 수 있었습니다. 이것은 유저모드 프로그램에서 커널 시스템 콜 호출을 많이 하면 할수록 페이지 테이블 스위칭 과정이 더 많이 이뤄지기 때문에 그만큼 시스템 성능이 저하될 수 있음을 의미합니다. 그러나 업계에서는 그것이 일반 사용자에게는 미미한 정도로 보고 있습니다.


LFENCE instruction mitigation for Spectre Variant 1

인텔과 AMD는 Spectre Variant 1을 막기 위한 조치로 LFENCE 명령어의 사용을 권장했습니다. 먼저 LFENCE명령에 관해서 핵심적인 부분은 아래와 같습니다.

<이미지 출처 : Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2 Instruction Set Reference>

 

LFENCE명령 다음의 명령어들이 CPU로 로드 될 수 있지만, LFENCE명령이 실행되기전까지는 그것이 실행되지 않는다는 것입니다. 가령 아래와 같은 코드가 있다고 가정해보겠습니다.

1번 TEST EAX, EAX
2번 JNZ CleanUp
3번 LFENCE
4번 MOV DWORD PTR [EAX], 1

위 코드에서 1번 명령어가 실행될 때 4번의 명령어가 미리 CPU로 로드 될 순 있지만 3번의 LFENCE명령어가 실행되기 전까지는 4번의 코드는 실행되지 않는다는 것입니다.

MS에서는 Spectre Variant 1을 차단하기 위해서 대부분의 커널 진입점 부분에 아래와 같이 LFENCE명령어를 삽입해두었습니다.



Figure 7. LFENCE 명령이 삽입되어 있는 모습

인텔에서는 LFENCE명령어를 주의 깊게 사용할 것을 당부하고 있습니다. 아무렇게나 LFENCE 명령어를 삽입할 경우 성능에 심각한 영향을 준다고 언급하고 있습니다.

IBRS, STIBP, IBPB mitigation for Spectre Variant 2

본 내용은 AMD에 해당하지 않습니다. AMD측은 Spectre Variant 2 취약점에 해당되지 않는다고 발표했습니다.

인텔은 CPU마이크로코드 업데이트와 OS패치를 동시에 적용하여 Spectre Variant 2를 차단할 계획을 가지고 있습니다. 취약점에 노출된 CPU의 마이크로코드 업데이트를 통해서 아래의 기능을 새롭게 추가할 예정입니다. (참고로 아래의 내용은 인텔 CPU매뉴얼에도 아직까지 존재하지 않는 내용이며, 인텔은 추후에 이 내용을 매뉴얼에 업데이트할 것임을 밝혔습니다.)

Indirect Branch Restricted Speculation (IBRS)
Single Thread Indirect Branch Predictors (STIBP)
Indirect Branch Predictor Barrier (IBPB)

마이크로코드 업데이트는 BIOS업데이트를 통해서 이뤄지기 때문에, 사용자는 메인보드 제작사를 통해서 제공되는 최신 BIOS업데이트를 적용할 필요가 있습니다.

이와 함께 윈도우OS에서는 인텔 CPU의 IBRS와 IBPB기능을 활성화하는 패치를 이미 적용한 상태입니다. 이 또한 대부분의 커널 진입점 코드에 패치가 되었으며, 인텔에 의하면 IBRS기능이 켜지면 CPU의 성능이 일부 저하된다고 언급하고 있습니다.


Figure 8. 인텔 IBRS를 활성화 하는 코드가 윈도우 커널레벨에서 적용 된 모습. 
(CPU 마이크로코드 업데이트가 되어 있어야 한다)


 

Figure 9. 인텔 IBPB를 활성화 하는 코드가 윈도우 커널레벨에서 적용 된 모습. 
(CPU 마이크로코드 업데이트가 되어있어야 한다)


STIBP를 활성화 하는 코드는 발견할 수 없었는데, 이는 추후에 적용될 가능성이 있거나 혹은 OS 패치가 필요 없이 CPU마이크로코드 업데이트를 통해서만 활성화될 수도 있습니다.

Return trampoline mitigation for Spectre Variant 2

이것은 구글에서 제시한 Spectre Variant 2의 해결 방법으로써 인텔 문서에서도 이 방법을 권장하고 있습니다.  아래를 보면 Figure10은 전형적인 Indirect Branch의 코드이고, Figure11은 구글에서 제안한 방법입니다.


Figure 10. 일반적인 Indirect Jmp 코드를 개선한 모습
<이미지 출처 : https://support.google.com/faqs/answer/7625886>



Figure 11. 일반적인 Indirect Call 코드를 개선한 모습
<이미지 출처 : https://support.google.com/faqs/answer/7625886>

바로 점프를 뛰거나 호출하지 않고 중간에 Setup과정을 거친 다음 해당 위치로 Branch함으로써 간접 분기를 예측 실행에서 격리시키는 것이 핵심입니다.



시스템별 상세 패치 방안

CPU 마이크로 코드 업데이트

메인보드 하드웨어 벤더사에서 제공하는 바이오스 업데이트를 수행하여 CPU 마이크로코드를 업데이트 해야합니다. 

제조사별 BIOS 구성이 다르기 때문에, 상세내용은 안내를 못드리는 점 양해부탁드립니다. 

※ BIOS 진입방법 (ASUS 예시)

1) BIOS 진입 (제조사 별로 상이하지만, 대부분 부팅 후 윈도우 로고가 뜨기 전 F2 혹은 DEL 키를 통해 진입가능)

2) Tool 메뉴 클릭



2) ASUS EZ Flash 3 Utility 클릭




3) via Internet 클릭 후 Next 클릭




메인보드 제조사별 안내링크는 여기를 참고해 주시기 바랍니다. 




Windows OS(개인용) 패치

▶ 자동 레지스트리 세팅 프로그램 다운로드 후 윈도우 보안업데이트 진행

* MS에서 제공하는 패치가 일부 시스템에서 호환이 되지 않을수도 있으니, 패치에 대한 위험성을 충분히 인지하신 후 업데이트를 진행해 주시기 바랍니다.


Windows Server


사용자들은 자동 업데이트 기능을 활성화 시켜 자동 업데이트를 진행해 주시기 바랍니다.

MS에서는 일부 SW와 호환이 되지 않을 경우가 있으니, 호환성을 확인 후 업데이트를 진행하기를 권고하고 있습니다더 자세한 내용은 여기를 참고해 주시기 바랍니다



브라우저 패치

※ Chrome

1) 크롬 브라우저를 실행합니다. 


2) 주소창에 chrome://flags/#enable-site-per-process를 입력합니다. 


3) 사이트 격리 옆에있는 ‘활성화’ 버튼을 클릭합니다(해당 버튼이 안보일 경우 크롬 업데이트 필요)


4) 크롬 브라우저를 재시작 합니다.




※ FireFox


57.0.4 버전 이상으로 업데이트


※ Edge/IE 


Windows 패치 중 포함되어 있음




애플 OSX


Mac OSX High Sierra 10.13.2 및 그 이상 버전으로 업데이트



Android & iOS


iOS 11.2.2 및 더 높은 버전으로 업데이트

Android는 일부 ARM CPU에 대해 패치를 진행하였으며, 자세한 내용은 여기를 참고해 주시기 바랍니다. 


 

IDC/클라우드 관리자


현재 일부 IDC/클라우드 업체들은 이미 임시 대응조치를 공개하였습니다. 하지만 패치 후에 발생할 수 있는 충돌이나 기능저하에 대한 내용은 아직 공개되지 않았습니다. 



Linux-Redhat/CentOS 배포버전

 

Redhat 은 이미 패치 방법을 공개하였습니다. 사용자들은 다음을 참고하여 패치를 진행하시면됩니다.


https://access.redhat.com/security/vulnerabilities/speculativeexecution

https://access.redhat.com/articles/3311301#page-table-isolation-pti-6



또한 패치 이후 일부 환경에서는 성능 저하가 발생할 수 있으며, 그에따른 조치 방법은 다음을 참고해주시기 바랍니다.


https://access.redhat.com/articles/3311301#page-table-isolation-pti-6

 


사용자는 다음 명령을 이용하여 KPTI, Indirect Branch Restricted Speculation (ibrs)Indirect Branch Prediction Barriers (ibpb)등의 보안매커니즘을 임시로 차단할 수 있습니다.

 

# echo 0 > /sys/kernel/debug/x86/pti_enabled

# echo 0 > /sys/kernel/debug/x86/ibpb_enabled

# echo 0 > /sys/kernel/debug/x86/ibrs_enabled


해당 매커니즘은 debugfs 파일 시스템을 사용해야하는데, RHEL7에서는 기본적으로 활성화가 되어 있으며, RHEL6에서는 하기 명령을 통하여 활성화 시켜야 합니다.

 

# mount -t debugfs nodev /sys/kernel/debug

 

사용자는 다음 명령을 통하여 현재 보안 매커니즘의 활성화 여부를 확인할 수 있습니다.

 

# cat /sys/kernel/debug/x86/pti_enabled

# cat /sys/kernel/debug/x86/ibpb_enabled

# cat /sys/kernel/debug/x86/ibrs_enabled

 

3개의 tunables는 부팅할 때 자동으로 활성화 됩니다.

 

Intel Defaults:

 

pti 1 ibrs 1 ibpb 1 -> fix variant#1 #2 #3

pti 1 ibrs 0 ibpb 0 -> fix variant#1 #3 (for older Intel systems with no microcode update available)

 

AMD x86variant #3에 취약하지 않으며, 부팅 시퀀스 과정중 동적 체크를 통하여 올바른 기본값이 AMD 에 설정됩니다.


pti 0 ibrs 0 ibpb 2 -> fix variant #1 #2 if the microcode update is applied

pti 0 ibrs 2 ibpb 1 -> fix variant #1 #2 on older processors that can disable indirect branch prediction without microcode updates

 

마이크로코드 패치를 진행하지 않은 상태


# cat /sys/kernel/debug/x86/pti_enabled

1

# cat /sys/kernel/debug/x86/ibpb_enabled

0

# cat /sys/kernel/debug/x86/ibrs_enabled

0


* Redhat등 제조사들은 직접적으로 CPU제조사들의 마이크로 패치를 제공하지 않기 때문에사용자들은 관련된 하드웨어 OEM 제조사에 문의 필요


더욱 자세한 내용은 여기를 참고해 주시기 바랍니다.




Linux-Ubuntu 배포버전


현재 Ubuntu x86_64 플랫폼에서meltdown(CVE-2017-5754) 취약점패치만 지원합니다.

더 상세한 내용은 여기를 참고해주시기 바랍니다.

 


Linux-Debian 배포버전


현재 DebianMeltdown(CVE-2017-5754)에 대한 취약점 패치를 완료하였습니다.

CVE-2017-5715 CVE-2017-5753에 대한 상세한 내용은 다음을 참고해주시기 바랍니다.

https://security-tracker.debian.org/tracker/CVE-2017-5753

https://security-tracker.debian.org/tracker/CVE-2017-5715




Xen VM


현재 Xen 그룹은 Meltdown, Spectre취약점에 대한 패치를 진행중입니다.

자세한 내용은 여기를 참고하시기 바랍니다.

 


QEMU-KVM


AEMU 그룹은 guesthost OS 시스템 패치를 통하여 Meltdown 취약점을 패치할 수 있다고 밝혔습니다.

Spectre 취약점CVE-2017-5715에 대해서는 KVM업데이트 이후 패치를 진행할 것이라고 밝혔습니다


하지만, 핫 마이그레이션으로는 CVE-2017-5715취약점을 해결하지 못하며, KVMcpu의 새로운 특성인 exposeguest커널로 사용해야 하기 때문에 guest는 재부팅이 필요합니다.


더 자세한 내용은 아래 링크를 참고해 주시기 바랍니다.

https://www.qemu.org/2018/01/04/spectre/

https://marc.info/?l=kvm&m=151543506500957&w=2




참고 : 

https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)

https://spectreattack.com/spectre.pdf

https://support.google.com/faqs/answer/7625886

https://security.googleblog.com/2018/01/more-details-about-mitigations-for-cpu_4.html

https://googleprojectzero.blogspot.kr/2018/01/reading-privileged-memory-with-side.html

https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/Intel-Analysis-of-Speculative-Execution-Side-Channels.pdf






관련글 더보기

댓글 영역