볼라틸리티(Volatility)는 최초 2006년 컴퓨터 공학자이자 기업가인 아론 월터스(Aaron Walters)에 의해 메모리 포렌식(memory forensics)관련 FATKit 프로젝트에서 출발하여 볼라툴즈 프로젝트(Volatools Project)로 발전했습니다.
그 이후 2007년 아론 월터스에 의해 볼라틸리티 프레임워크(Volatility Framework)개발팀인 볼라틸 시스템즈(http://volatilesystems.blogspot.kr/)가 만들어지고 현재는 아론 월터스가 회장으로 있는 볼러틸리티 재단(Volatility Foundation)의 사고조사 및 멀웨어 분석을 위한 오픈소스(OpenSource) 소프트웨어로 자리잡았습니다.
플러그인(Plugin)을 자신이 직접 만들어 사용이 가능한 이유로 메모리 분석과 관련된 다양한 기능을 가진 공개용 Plugin 파일이 개발되고 있습니다.
또한 침투 테스트(Pentest)를 목적으로 개발된 데비안 기반 운영체제인 칼리 리눅스(Kali Linux, http://www.kali.org/downloads)에도 포함되어 있습니다.
Volatility 는 파이썬(Python) 프로그래밍 언어로 작성되었고 Microsoft Windows, MacOSX 및 Linux 를 지원합니다.(버전 2.6기준)
[지원 포맷 형식]
Volatility 는 다양한 파일 포맷 형식을 지원하고 이러한 포맷 형식 간에 전환이 가능합니다.
.vmdk – 게스트 운영체제(Guest OS)에 대한 실질적인 가상 하드 드라이브(Virtual Hard Drive)
.vmem – 게스트 운영체제에 대한 실질적인 가상 페이징 파일(Virtual Paging File)
.vmsn – VMware에서 생성하는 스냅샷(Snapshot) 파일로, 게스트 운영체제에 대한 상태 저장
.vmsd – VMware에서 생성한 스냅샷 파일에 대한 메타데이터(Metadata) 기록 파일
.nvram – 게스트 운영체제에 대한 바이오스(BIOS) 정보 기록 파일
.vmx – 게스트 운영체제에 대한 설정 기록 파일
.vmss – 게스트 운영체제를 일시 중지(Suspend) 상태로 변경할 경우, 당시의 게스트 운영체제 상태를 저장한 파일
VMware 가 가지고 있는 위와 같은 주요 확장자 파일들 중 메모리 덤프 파일은 .vmem 확장자를 가진 파일입니다. VMware 이미지에서 .vmem 확장자 파일을 추출하기 위해서는 현재 메모리 상태를 저장해야 됩니다. 실행 중인 이미지를 일시 중지(Suspend) 시키면 .vmem 파일이 생성되는데 해당 폴더에서 .vmem 파일을 복사하면 됩니다.
ELF statifier 는 동적 링크된 실행 파일과 공유 라이브러리를 하나의 파일로 합치기 위한 툴로 동적 실행 파일에서 정적 실행 파일을 생성합니다. 침해사고 시스템을 분석할 때는 라이브러리에 의존하지 않기 위해 정적 실행 파일을 사용해야 하지만 정적 컴파일 된 파일은 사이즈가 크다는 단점이 존재합니다.
동적으로 링크 된 공유 라이브러리는 정적으로 링크 된 공유 라이브러리보다 디스크 공간을 효율적으로 사용하며, 보다 효율적인 방식으로 보안 업데이트를 수행 할 수 있습니다. 그리고 동적 라이브러리의 특정 버전으로 컴파일 된 실행 파일은 해당 버전의 공유 라이브러리가 실행중인 시스템에서만 사용이 가능합니다.
Fedora 9 와 openSUSE 11 를 각각 실행해 보면 일부 공유 라이브러리의 버전이 다른 것을 볼 수 있으며 이러한 버전 차이로 인해 컴퓨터간에 실행 파일을 복사하더라도 파일을 실행할 수 없습니다. 하지만 ELF Statifier 를 이용하면 동적 라이브러리를 찾는 실행 파일 대신에 공유 라이브러리를 포함한 정적으로 링크 된 실행 파일을 만들 수 있으며 Fedora 컴퓨터에서 컴파일 한 실행 파일을 다시 컴파일하지 않고도 openSUSE 시스템에서 실행할 수 있습니다. 물론 실행 파일을 복사하는 시스템과 실행 파일을 복사하려는 시스템은 동일한 아키텍처를 가져야합니다.
물론 이렇게하려면 정적 실행 파일에 필요한 공유 라이브러리 복사본이 포함되어 있기 때문에 일부 디스크 공간을 희생해야하지만 요즘에는 디스크 공간이 크기 때문에 중요하지 않습니다. 실행 파일이 libfoo 라는 공유 라이브러리에 동적으로 링크되어 있고 libfoo 에 대한 보안 업데이트가 있는 경우 어떻게 될지 고려해 보십시오. 응용 프로그램이 동적으로 링크되어 있다면 libfoo 의 공유 사본을 업데이트 할 수 있으며 응용 프로그램은 더 이상 이전 libfoo 의 보안 문제로 취약하지 않습니다. 반면에 정적으로 링크 된 실행 파일의 경우 이전 libfoo 라는 공유 라이브러리 복사본이 포함되어 있기 때문에 최신 libfoo 및 보안 업데이트를 적용하려면 정적으로 링크 된 실행 파일을 다시 만들어야 합니다.
[Statifier설치]
ELF Statifier 는 openSUSE 10.3 에서는 1-Click 으로 설치되지만 Ubuntu 나 Fedora 에서는 1-Click 으로 설치되지 않습니다. 여기서는 ELF Statifier 1.6.14 버전을 사용했으며 ELF Statifier 는 자동 도구를 사용하지 않으므로 간단하게 호출하여 컴파일 할 수 있습니다. make 컴파일과 설치는 아래와 같습니다.
# tar xzvf statifier-1.6.14.tar.gz # cd ./statifier-* # make # make install
[ASLR 해제]
정적 실행 파일을 만들기 전 메모리상의 공격을 방어하기 위해 주소 공간배치를 난수화 시키는 기법(ASLR : Address Space Layout Randomization) 은 비활성화해야 합니다. 주소 공간배치를 난수화하면 실행 파일을 실행할 때마다 libc 함수의 위치가 항상 바뀌기 때문에 return-to-libc 공격과 같은 BOF 공격으로부터 메모리를 보호하게 됩니다. 하지만 정상적인 정적 실행 파일 또한 실행이 불가합니다.
아래와 같이 randomize_va_space 매개 변수를 변경하여 보안을 해제합니다. randomize_va_space 변경은 실행 파일 자체에 대한 공격뿐만 아니라 버퍼 오버 플로우에 의존하여 시스템을 손상시키는 공격 시도에도 영향을 미칩니다. 주소 공간배치 난수화가 없으면 두 공격에 더 취약 해집니다.
아래와 같이 randomize_va_space를 0으로 설정하고 정적 실행 파일을 만들면 됩니다.
sysctl 명령은 커널 변수의 값을 제어하여 시스템을 최적화 할 수 있는 명령으로 시스템의 /proc/sys 디렉토리 밑에 있는 매개변수를 제어합니다. echo 명령을 사용하거나 sysctl 명령을 이용하여 /proc 디렉토리 밑에 있는 항목을 직접 편집하거나 설정할 수 있습니다.
sysctl 옵션 -a : 현재 커널 매개변수와 값을 보여줍니다 -p : sysctl 환경변수파일(기본값은 /etc/sysctl.conf)의 설정상태를 보여줍니다 -n : 특정키에 대한 값을 보여줍니다. -w variable=value : 변수에 값을 설정합니다. -A : 테이블형재로 설정가능한 파라미터를 보여줍니다. -a 와 같습니다.
sysctl 명령을 이용하여 ASLR(Address Space Layout Randomization) 설정 값과 DEP / NX(Not Excutable) 설정 값을 확인합니다.
# sysctl -a | grep -E "exec-|randomi" kernel.exec-shield=1 kernel.randomize_va_space=2
sysctl 명령을 이용하여 ASLR(Address Space Layout Randomization) 설정 값을 변경합니다. 임시로 변경하는 방법이기 때문에 재부팅되면 설정 값이 기본 값(2)으로 변경됩니다.
Memory Dump 는 System의 물리 Memory 를 File 형태로 저장하는 방법으로, 해당 File 의 구조는 실제 물리 Memory 구조와 동일합니다. 침해사고 분석 시 침해 시스템에 실시간 분석을 수행하면 해당 명령어로 인해 Memory 의 상태 및 Data 가 변경됩니다.
이는 Memory 로부터 얻을 수 있는 중요한 정보를 놓칠 수 있는 가능성이 존재하므로 분석에 불리하게 작용할 수 있습니다. 이 같은 실시간 분석의 단점으로 인해 침해사고 시점의 휘발성 Data 를 File 로 간직하여 Memory 에 변화를 주지 않으면서 분석을 하기위해 Memory Dump 를 수행합니다.
[Linux 에서 Memory Dump]
Linux는 운영체제의 모든 Resource 를 File 형태로 다룹니다. Linux 에서 Memory 접근은 장치 File 을 통해 이루어집니다.
과거에는 /dev/mem과 /dev/kmem 통해 직접적으로 리눅스 시스템에서 Memory 를 확보 할 수 있었으나, 보안상의 이유로 최신 커널에서는 이 액세스가 제한되거나 제거되었습니다. 하지만 fmem 이나 LiME 과 같은 프로젝트에서 로드 가능한 커널 모듈이 개발되어 Memory Dump 가 가능하게 되었습니다 .
Linux 는 Kernel 과 함께 동작하는 많은 기능을 Module 의 형태로 제공합니다. 현재 Load 된 Module 을 확인하려면 lsmod 명령을 이용하면 됩니다. Module 은 insmod 명령으로 운영체제가 동작 중인 상태에서 쉽게 Load 할 수 있고, rmmod 로 쉽게 제거할 수 있습니다.
Kernel 은 Version 에 따라 구조가 달라질 수 있습니다. Kernel 은 운영체제의 핵심이므로 Kernel 동작을 방해하지 않으려면 Kernel Module 은 이러한 구조와 운영체제 환경에 잘 맞아야 합니다. Kernel 을 직접 다룰 수 있기 때문에 잘못하면 Kernel 의 기능을 오동작시키거나 정지시킬 수도 있습니다. 그래서 보통 Linux Kernel Module 은 Load 시킬 운영체제 환경에서 직접 Compile 합니다.
[LiME]
LiME 은 Joe Sylve 가 만든 툴이며 리눅스뿐만 아니라 안드로이드와 같은 리눅스 기반 디바이스의 Memory 를 덤프 할 수 있습니다. 안드로이드의 Memory 를 처음으로 Full Dump 를 한 도구이며 TCP 를 통해서도 Memory 를 덤프할 수 있습니다. Memory 를 획득하는 과정에서 Kernel 과 User 간의 상호작용을 최소화하여 획득 도구에 의한 Memory 의 훼손을 최소화 시켰습니다. LiME 은 다음의 웹페이지 (https://github.com/504ensicsLabs/LiME) 에서 다운로드 할 수 있습니다.
LiME 은 바이너리없이 소스로 배포되므로 직접 Compile 해야합니다. 먼저 미리 Compile 된 LKM 이 있는지 확인하거나 가상 컴퓨터에서 컴파일 및 테스트를 먼저 수행하는 것이 좋습니다. LiME 이 미리 Compile 한 LKM 를 확인할 수 있는 평판이 좋은 사이트 중 하나는 Cert.org 의 Linux Forensics Tools Repository(https://forensics.cert.org/) 입니다. Red Hat Enterprise Linux, CentOS 및 Fedora 를 위한 사이버포렌식 도구의 RPM 정보를 제공합니다.
:: 장점 ::
LKM 에 컴파일 된 LiME 은 크기가 작습니다.
프로세스를 다시 시작할 필요가 없습니다.
LKM 에 신속하게 추가/제거 할 수 있습니다.
Memory Dump 를 로컬 디스크에 쓰지 않고 네트워크를 통해 전송할 수 있습니다.
Memory Dump 는 Volatility 와 호환됩니다.
:: 단점 ::
실행파일이 아닌 컴파일방식으로 Memory Dump 를 수행하는 부분은 시스템이 변조되기 때문에 무결성이 손실될 수 있습니다.
[사용방법]
LiME 을 다운로드하고 컴파일을 합니다.
[root@vmtest ~]# mkdir lime; cd lime [root@vmtest lime]# wget https://github.com/504ensicsLabs/LiME/archive/master.zip [root@vmtest lime]# upzip master.zip [root@vmtest lime]# cd src [root@vmtest src]# make …. make -C /lib/modules/2.6.32-431.5.1.el6.x86_64/build M=/root/lime/src modules … [root@vmtest src]# ls lime*.ko lime-2.6.32-431.5.1.el6.x86_64.ko
-o : compat, backing_file, backing_fmt, encryption, cluster_size, preallocation, lazy_refcounts 등 관련 옵션이 굉장히 많은 듯 싶은데 정확한 설명을 찾아보기가 어렵네요. 특정 옵션의 경우 지원 가능한 포맷이 정해져 있습니다.
-O : 변환될 포맷을 지정합니다.
-p : 진행 상태 바를 표시합니다. (compare, convert, rebase 커맨드 한정) -p 옵션을 지원하지 않는 커맨드의 경우, 진행상황은 프로세스가 SIGUSR1 신호를 받았을 때 보고됩니다.
-q : 침묵 모드로 오류를 제외한 다른 메세지들을 출력하지 않습니다. -q와 -p를 동시에 사용하면 진행 상태 바가 표시되지 않습니다.
Command parameters: 'filename' is a disk image filename 'fmt' is the disk image format. It is guessed automatically in most cases 'cache' is the cache mode used to write the output disk image, the valid options are: 'none', 'writeback' (default, except for convert), 'writethrough', 'directsync' and 'unsafe' (default for convert) 'size' is the disk image size in bytes. Optional suffixes 'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M), 'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 1024P) are supported. 'b' is ignored. 'output_filename' is the destination disk image filename 'output_fmt' is the destination format 'options' is a comma separated list of format specific options in a name=value format. Use -o ? for an overview of the options supported by the used format 'snapshot_param' is param used for internal snapshot, format is 'snapshot.id=[ID],snapshot.name=[NAME]', or '[ID_OR_NAME]' 'snapshot_id_or_name' is deprecated, use 'snapshot_param' instead '-c' indicates that target image must be compressed (qcow format only) '-u' enables unsafe rebasing. It is assumed that old and new backing file match exactly. The image doesn't need a working backing file before rebasing in this case (useful for renaming the backing file) '-h' with or without a command shows this help and lists the supported formats '-p' show progress of command (only certain commands) '-q' use Quiet mode - do not print any output (except errors) '-S' indicates the consecutive number of bytes (defaults to 4k) that must contain only zeros for qemu-img to create a sparse image during conversion. If the number of bytes is 0, the source will not be scanned for unallocated or zero sectors, and the destination image will always be fully allocated '--output' takes the format in which the output must be done (human or json) '-n' skips the target volume creation (useful if the volume is created prior to running qemu-img)
Parameters to check subcommand: '-r' tries to repair any inconsistencies that are found during the check. '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all kinds of errors, with a higher risk of choosing the wrong fix or hiding corruption that has already occurred.
Parameters to snapshot subcommand: 'snapshot' is the name of the snapshot to create, apply or delete '-a' applies a snapshot (revert disk to saved state) '-c' creates a snapshot '-d' deletes a snapshot '-l' lists all snapshots in the given image
Parameters to compare subcommand: '-f' first image format '-F' second image format '-s' run in Strict mode - fail on different image size or sector allocation Supported formats: vvfat vpc vmdk vhdx vdi sheepdog sheepdog sheepdog raw host_device file qed qcow2 qcow parallels nbd nbd nbd dmg tftp ftps ftp https http cow cloop bochs blkverify blkdebug
VMware의 가상 하드 디스크 타입은 고정 크기 (Preallocated)나 가변 크기 (Growable; Dynamically Expanding) 로 설정할 수 있는데, 고정 크기의 경우 성능면에서는 가변 크기에 비해 우수하지만 사이즈가 크기 때문에 다른매체로 옮길 때는 상당히 불편합니다. 그래서 필요 시 타입을 변경할 수 있습니다.
가상 디스크의 타입을 변환하기 위해선 vmware-vdiskmanager 명령어에 -r 옵션을 사용하면 됩니다. 이 옵션을 사용하면 원본 가상 디스크 이미지 파일을 바탕으로 원하는 타입의 새로운 가상 디스크 이미지 파일이 만들어집니다.