Mac Hibernation Image Analysis – Part I

처음 제가 Mac OS X 메모리 분석을 할 때만 해도 분석이 가능한 수집 방법은 선형 주소 방식의 메모리 이미지인 Firewire를 이용한 수집이나 VMWare Memory Image 뿐이였습니다.
최근에 hajime Inoue의 Mac Memory Reader(MMR)의 컨버터를 volafox에 추가하면서 이젠 하드웨어 및 소프트웨어 방식의 메모리 수집 결과를 분석할 수 있게 되었습니다.
하지만 제 발표자료를 보셨다거나 윈도우 메모리 수집 방법에 대해 조사를 해보신 분이라면 윈도우에선 하이버네이션 이미지를 이용한 분석방법이 존재한다는 사실을 아실겁니다. 윈도우에는 hiberfil.sys가 하이버네이션 이미지를 가지고 있으며, 이를 크래시덤프 형태로 변형해서 Windbg를 통해 분석이 가능 합니다.
사실 volafox project를 처음 개발했을 때부터 하이버네이션 이미지에 대한 분석을 고려했었습니다만, 취업과 더불어 여러가지 일이 생기면서 계속 뒤로 미루고 있었습니다. 그런데 최근에 몇몇 세미나 인원들과 얘기하면서 아는 동생의 논문 주제에 대해 얘기하다가 ‘하이버네이션 이미지 컨버터’를 만들면 충분히 논문으로 쓸만하겠다는 생각이 들어서, 그 동생에게도 알려줄겸, 지금까지 된 상황에 대해 적어보려 합니다.
일단 Mac OS X의 하이버네이션 이미지는 애플의 휴대용 장비인 맥북, 맥북프로, 맥북에어에 기본적으로 존재하며, ‘/private/var/vm/’에 sleepimage라는 파일로 되어 있습니다. 만약 해킨토시나 맥프로, 아이맥, 맥미니에서 하이버네이션 이미지를 수집하고 싶다면, pmset 명령을 이용하여 현재 메모리의 이미지를 생성할 수 있습니다.

VMware-Lion:vm administrator$ ls -al
total 262144
drwxr-xr-x   4 root  wheel       136 Nov  5 23:09 .
drwxr-xr-x  29 root  wheel       986 Sep 25 12:40 ..
-rw-------   1 root  wheel  67108864 Nov  5 22:34 swapfile0
-rw-------   1 root  wheel  67108864 Nov  5 23:08 swapfile1
VMware-Lion:vm administrator$ sudo pmset hibernatemode 3
VMware-Lion:vm administrator$ ls -al
total 4456448
drwxr-xr-x   5 root  wheel         170 Nov  5 23:09 .
drwxr-xr-x  29 root  wheel         986 Sep 25 12:40 ..
-rw------T   1 root  wheel  2147483648 Nov  5 23:09 sleepimage-rw-------   1 root  wheel    67108864 Nov  5 22:34 swapfile0
-rw-------   1 root  wheel    67108864 Nov  5 23:08 swapfile1

pmset의 ‘hibernatemode’ 옵션을 주고 3을 설정하면 됩니다. 아래 표는 각 인자 값에 따른 메모리 이미지 처리를 설명하고 있습니다.

hibernatemode = 0 (binary 0000) by default on supported desktops. The system will not back memory up to persistent storage. The system must wake from the contents of memory; the system will lose context on power loss. This is, historically, plain old sleep.
hibernatemode = 3 (binary 0011) by default on supported portables. The system will store a copy of memory to persistent storage (the disk), and will power memory during sleep. The system will wake from memory, unless a power loss forces it to restore from disk image.
hibernatemode = 25 (binary 0001 1001) is only settable via pmset. The system will store a copy of memory to persistent storage (the disk), and will remove power to memory. The system will restore from disk image. If you want "hibernation" - slower sleeps, slower wakes, and better battery life, you should use this setting.</p>

하이버네이션 구조체에 대한 정보는 커널 소스에서도 확인할 수 있습니다.
image
해당 소스는 ‘iokit/IOKit/IOHibernatePrivate.h’에 위치한 헤더 파일로 하이버네이션 이미지의 헤더 정보를 가지고 있습니다. 헤더 정보를 보면 aes.h를 인클루드 하고 있으며, aes 키에 대한 정보도 가지고 있습니다. 이는 하이버네이션 이미지를 암호화할 때 AES를 사용함을 유추할 수 있습니다.
그럼 일단 Mac OS X Lion에서 추출한 sleepimage 파일의 최상위 바이트를 확인해보도록 하겠습니다.
image
이미지 맨 처음엔 IOHibernationImageHeader 구조체 형식의 데이터가 존재합니다. 시그너처인 0x7A7A7A7A를 통해 확인할 수 있습니다.
image
근데 이 시그너처가 kIOHibernateHeaderInvalidSignature입니다. 이 Invalid의 의미는 제 추측으론 현재 하이버네이션 이미지가 이전에 시스템이 하이버네이션에 들어갈 때의 이미지이기 때문에 그 때 당시 하이버네이션 이미지를 Restore하는 과정에 해당 시그너처를 0x73696d65에서 0x7a7a7a7a형태로 변경하는 것이라 생각합니다. 이를 증명하려면 시스템을 하이버네이션 상태에 진입시키고 시스템에서 하드디스크를 분리하여 이미징 후 하이버네이션 파일을 추출해서 확인하면 좀더 확실해 질 것 같습니다. 아래 코드는 “iokit/Kernel/IOHibernateIO.cpp”의 IOHibernationSystemSleep()의 내용 중 하나입니다.
image

그리고 추가적으로 스크롤을 하다보면, 가시적인 텍스트를 찾을 수가 없습니다. 이는 라이언이 기본적으로 하이버네이션 이미지를 AES로 암호화하기 때문인 것 같습니다. 아래 그림은 바이트 분포도를 확인한 결과입니다. 0x00과 0xFF를 제외하고 모든 값이 0.3~0.6사이의 퍼센트를 유지하고 있습니다.
image
하이버네이션 이미지는 AES-128로 암호화를 수행하며 IV는 코드에 박혀있습니다. 아래는 ‘iokit/Kernel/IOHibernateInternal.h’에 정의된 키 사이즈입니다.
image

다음은 ‘iokit/Kernel/IOHibernateIO.cpp’에 있는 hibernate_write_image 함수에 있는  IV 정보입니다.
image

이로서 우리가 알 수 있는 사실은 세 가지 입니다.
1. 하이버네이션에 대한 물리메모리 변환 과정은 IOKit에서 수행한다.
1-1. iokit/Kernel/IOHibernateIO.cpp, iokit/Kernel/IOHibernateInternal.h, iokit/Kernel/IOHibernateIO.cpp


2. IOKit에 Hibernation과 관련된 코드는 오픈소스화 되어 있기 때문에 충분히 선형 주소 방식의 메모리 이미지로 변환하는 코드를 작성할 수 있을 것 같다.


3. 하이버네이션 이미지에 실제 메모리 영역은 암호화 되어 있기 때문에 이를 복호화하는 과정이 필요하다.
3-1. 스노우레오파드 땐 많은 양의 명시적 텍스트가 존재하였음.
3-2. 암호화는 AES-128이며 IV는 소스코드에 박혀있다.
3-3. 키는 키체인에 존재하거나 사용자 패스워드를 기준으로 키를 생성하는 코드를 그때그때 실행할 수 있다. 이에 대한 규명과 키를 추출할 수 있는 방안이 필요하다.

이 내용을 기반으로 Part 2에선 좀더 진행해보도록 하겠습니다.(물론 시간이 걸리겠지만…)

n0fate's Forensic Space :)