본문으로 바로가기


2018년 새해 벽두부터 인텔 CPU의 중대한 취약점 때문에 보안업계가 호들갑이다.


하지만 이 두 버그에 대한 설명은 매우 부족하거나 너무 어려운 경우가 대부분이다. 왜냐하면 이 버그에 대해 제대로 이해하기 위해서는 운영체제의 커널과 CPU의 동작 체계에 대한 깊은 이해는 물론 리버싱에 필요한 어셈블리어에 대한 지식도 필요하기 때문이다. 사실 나도 이 버그에 대해 완벽하게 이해하고 있지는 못하다. 다만 운영체제와 CPU에 대해 조금이나마 이해하고 있는 부분이 있어 뉴스 기사에서 소개하는 내용보다는 조금 더 들어가 보고자 한다.


사전 지식


멜트다운 버그와 스펙트라 버그에 대해 이해하기 위해서는 CPU와 운영체제에 대한 몇가지 사전 지식이 필요하다. 

먼저 CPU에 대해 설명하자면 다음의 몇가지를 알고 있어야 한다.


C-1. 프로그램은 순차적으로 실행되는 CPU만 이해할 수 있는 명령어의 집합이다. (쉽게 말해 기계어(어셈블리와 1대1 매핑)로 써있다.)

C-2. 여러개의 프로그램은 실행되면 메모리를 할당받고 코드영역과 데이터영역에 적재된다. (이때부터 프로세스라고 부른다.)

C-3. CPU는 프로세스의 코드영역에서 명령어를, 데이터 영역에서 데이터를 CPU내로 읽어와 하나씩 순차적으로 실행한다.

C-4. CPU는 여러개의 프로세스를 교대로(컨텍스트 스위칭이라고 부름) 바꿔가며 실행해 준다.


다음은 운영체제다.


O-1. 운영체제는 메모리를 커널메모리와 유저메모리로 구분한다.

O-2. 커널메모리는 유저메모리에 적재되는 프로세스를 관리하기 위한 정보를 저장하고 있다.

O-3. 프로세스는 커널모드와 유저모드에서 실행되며 유저모드로 실행되다가 특별한 작업(예, 파일I/O)을 할 때만 커널모드로 진입한다.

O-4. 프로세스는 유저모드에서 커널메모리 및 다른 프로세스에게 할당된 메모리에 접근할 수 없다.(접근을 시도하면 오류를 발생시키며 대부분 자동 종료된다.)


이정도의 상식(?)은 이해하고 있어야 멜트다운 버그와 스펙트라 버그를 조금은 이해할 수 있다.


멜트다운(Meltdown) 버그 및 스펙트라(Spectre) 버그 취약점에 대한 이해

멜트다운과 스펙트라 버그는 CPU의 처리 효율을 높여 시스템의 전반적인 성능을 높이기 위해 적용된 "비 순차적 실행(Out of Order Excution)"과 "추측 실행(Speculative Execution)" 의 사이드 이펙트로 발생하는 버그다. 조금 쉽게 설명하면...


앞에서 CPU는 프로세스의 명령목록에서 하나씩 CPU 내부로 읽어와 실행한다고 했다. 이때 수행되는 작업에 따라 CPU는 "놀고" 주변장치(DISK, 메모리 등)만 일하는 시간이 생긴다. 이 시간을 활용하기 위해 CPU는 다음에 실행할 명령어를 미리 읽어와 실행하고 그 결과를 저장해 두었다가 이어서 실행될 때 그 결과를 활용해 속도를 높이는 기술이 바로 비 순차적 실행(OoOE)이다. 그리고 특정 명령어의 실행 시 결과를 여러가지 알고리즘을 통해 미리 예측해 속도를 높이는 기술이 추측 실행(Spectre)이다. 


그렇다면 이 두 기술의 어떤 점이 문제를 일으키는 것일까? 


CPU는 OoOE(비 순차적 실행) 기술에 의해 현재 시점에서 실행하지 않아도 되는 명령어를 미리 가져와 실행하는데 그 과정에서 유저모드의 프로세스가 커널모드에서만 접근할 수 있는 커널메모리와 다른 프로세스의 메모리에 접근할 수 있는 권한을 얻는 것이 멜트다운 버그다. 이 버그에 의해 커널메모리에 접근할 수 있는 권한을 얻게 되면 다른 프로세스들이 할당받은 메모리의 시작주소를 관리하는 테이블에 접근할 수 있게되며 이 시작주소를 기준으로 상대주소를 분석해 개인정보가 담겨있는 메모리에 접근할 수 있게 되는 것이다. 


스펙트라 버그는 추측 실행을 통해 미리 결과를 예측해 해당 명령어를 실행하고 그 결과를 보관하고 있는데 예측이 틀렸을 경우 해당 명령어의 실행과 그 결과를 취소하여야 한다. 하지만 그 취소 과정에서의 문제로 인해 다른 프로세스의 메모리에 접근할 수 있는 권한을 얻게 된다고 한다. (너무 어렵다.. -.-) 


아래는 멜트다운 버그의 취약점을 공격해 사용자의 비밀번호를 추출해내는 사례다. 유튜브에 공개되어 있다.



위의 사례에서는 서버의 콘솔에서 실행하고 있지만 실제로는 웹사이트에서 입력한 비밀번호도 동일하게 추출해 낼 수 있다. 사용자의 브라우저에서 입력한 비밀번호는 결국은 서버에서 실행되는 IIS, 아파치, 웹로직, 제우스, 웹투비 등의 웹서버 대몬으로 전송되고 전송 시 암호화를 했더라도 웹서버에서 메모리에 저장될 때는 결국 평문으로 저장되기 때문에 2중, 3중으로 설치한 보안sw와 암호화 통신은 무용지물이 된다.

버그 패치


이 두 버그의 영향을 받는 CPU는 1995년 이후 출시된 대부분의 펜티엄과 i시리즈 CPU 및 i시리즈 CPU에 기반한 제온 CPU 모두에 해당된다고 한다. 당연히 운영체제는 이 CPU를 지원하는 모든 운영체제가 해당된다. 맥OS는 물론 리눅스도 모두 동일한 조건이다.


그렇다면 이 버그의 패치를 적용해야 하는데 과연 패치는 어떤 역할을 하는 것일까?


멜트다운 버그와 스펙트라 버그는 CPU의 물리적인 설계상 발생한 취약점이다. 따라서 근본적인 패치는 안전한 CPU로 교체하는 것 뿐이다. 지금 개발하고 배포되는 패치는 그저 임시방편일 뿐이다. 


해커는 이 두 취약점을 공격해 커널모드의 권한을 얻은 뒤 또 다른 작업을 해야만 위의 유투브 동영상 처럼 다른 프로세스의 메모리에 접근하여 원하는 정보를 빼낼 수 있다. 그 작업 중 가장 중요한 것이 원하는 정보를 갖고 있는 프로세스의 메모리 상에서의 시작 주소다. 메모리에 적재되어 실행되는 프로세스의 시작주소는 커널메모리 영역에 있는 프로세스 정보 테이블에 존재한다. 이 프로세스 정보 테이블에 존재하는 프로세스의 시작주소를 난독화해 해커가 추출해내더라도 프로세스가 메모리상의 어디에 존재하는지 알 수 없도록 해주면 해커가 원하는 주소에 접근할 수 없다. 지금만들어 급하게 배포되는 패치들은 대부분 이런 작업을 통해 해커로부터 프로세스의 위치를 감추는 역할을 하는 것으로 보인다.


하지만 이런 패치는 당연히 성능저하를 가져올 수 밖에 없다. 메모리의 I/O 등을 위해 프로세스의 시작주소를 알려면 난독화된 주소를 복호화해야 한다. 하지만 커널과 CPU에서는 1초에도 수백, 수천, 수만번씩 프로세스의 컨텍스트 스위칭이 발생하며 한번의 I/O에 한번의 디코딩만 일어나는 것은 아니다. 따라서 난독화 되어 있는 주소값을 복호화하는 작업이 몇번이나 일어날지는 아무도 쉽게 예측할 수 없다.


지금까지의 보고에 의하면 적게는 10% 많게는 30%까지의 성능저하가 발생한다고 한다.


따라서 해당 버그 패치의 적용은 신중해야할 수 밖에 없다.


인텔의 대응에 대하여


요 몇일 인텔의 대응을 보면 "가관(可觀)"이다. 처음엔 "버그가 아니며 취약하지도 않다"라는 이야기를 서슴치 않더니 이젠 "패치를 내놓았으며 성능의 저하도 미미"하다고 썰을 풀고 있다. 게다가 공식성명에서 아직은 확인되지도 않은 "다른 CPU도 그런데 왜 나만 갖고 그래"를 시전하고 있다. 


하지만 명백하게 이 두 버그는 CPU와 운영체제에 조금만 지식이 있어도 "치명적인 문제를 야기할 수 있는 취약점"임을 알 수 있다.


인텔의 그런 반응은 어찌보면 당연하다고 할 수도 있다. 자칫하면 기업 이미지에 치명적인 손상을 입을 것은 자명하고 해당 취약점이 공격을 당해 피해가 발생할 경우 천문학적인 손해배상(미국은 징벌적 손해배상이 가능함) 소송에 당면할 수도 있기 때문이다.


댓글을 달아 주세요

  1. BlogIcon 영양듬뿍호두 2018.02.22 20:19 신고

    CPU 취약점 관련하여 이해하는데 많은 도움이 되었습니다.
    감사합니다.