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와 운영체제에 조금만 지식이 있어도 “치명적인 문제를 야기할 수 있는 취약점”임을 알 수 있다.
인텔의 그런 반응은 어찌보면 당연하다고 할 수도 있다. 자칫하면 기업 이미지에 치명적인 손상을 입을 것은 자명하고 해당 취약점이 공격을 당해 피해가 발생할 경우 천문학적인 손해배상(미국은 징벌적 손해배상이 가능함) 소송에 당면할 수도 있기 때문이다.