볼라틸리티(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 는 다양한 파일 포맷 형식을 지원하고 이러한 포맷 형식 간에 전환이 가능합니다.

  - Raw linear sample (dd)

  - Hibernation file (from Windows 7 and earlier)

  - Crash dump file

  - VirtualBox ELF64 core dump

  - VMware saved state and snapshot files

  - EWF format (E01) 

  - LiME format

  - Mach-O file format

  - QEMU virtual machine dumps

  - Firewire 

  - HPAK (FDPro)


[요구사항]

Python 2.6 또는 이후 버전(3.0 불가).

Web:

http://www.python.org


[관련 홈페이지]

For information or requests, contact:

Volatility Foundation


Web:

http://www.volatilityfoundation.org

http://volatility-labs.blogspot.com

http://volatility.tumblr.com

https://github.com/volatilityfoundation/volatility

VMware 주요 확장자에 대한 설명

.log – 가상 머신(Virtual Machine)에 대한 일반적인 활동 기록 파일

.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 파일을 복사하면 됩니다.

VMware 이미지는 메모리덤프를 위해 별도의 유틸리티가 필요 없네요.

[Windows] 메모리 덤프 형식(Memory Dump Format)
[Windows] 메모리 덤프#01
[Windows] 메모리 덤프#02
[Windows] 메모리 덤프#03

[Linux] 메모리 덤프(Memory Dump)#02

 

[Memory Dump 란?]

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 을 다운로드하고 컴파일을 합니다.

make 전에는 리눅스 개발 환경에서 컴파일, 링크, 빌드 등에 필요한 필수적인 도구들을 모아놓은 build-essential 패키지가 설치 되어있어야 합니다.

[root@vmtest ~]# apt-get install build-essential

 

폴더를 만들고 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]# LiME-master
[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

 

방법1. 로컬 시스템에 Memory 를 추출합니다.

추출된 결과파일을 저장할 경로와 이름, 파일형식을 지정해줍니다.

[root@vmtest ~]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=/tmp/mem.img format=raw"

"File exists"에러가 발생하면 "rmmod lime"을 입력하여 모듈을 언로드 후 다시 실행하면 동작합니다.

 

:: 옵션 ::

path 를 이용하여 물리 메모리 이미지를 파일로 저장할 수 있으며 또한 원격지 서버로 전송할 수 있습니다. 

ex. 파일경로와 파일이름 혹은 tcp:<port>

format 은 메모리 이미지의 포맷을 결정하는 옵션입니다. 

ex. raw : RAW 포맷 이미지, lime : LiME 포맷 이미지

 

방법2-1. 원격 시스템에 Memory 를 추출합니다.

LiME의 가장 큰 장점은 로컬 디스크 또는 실제 파일에 대한 출력에만 국한되지 않는다는 것입니다. 로컬 시스템에 path=/tmp/mem.img 와 같이 출력 경로를 지정하는것 대신 path=tcp:4444 와 같이 TCP 서비스를 작성합니다.

[root@vmtest ~]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=tcp:4444 format=lime"

 

그리고 netcat을 사용하여 원격 시스템에 연결하여 메모리 이미지를 조사용 랩톱으로 전송할 수 있습니다. 

[User@laptop ~]# nc target.server.com 4444 > /tmp/mem.img

 

방법2-2. 원격 시스템에 Memory 를 추출합니다.

조사용 랩톱에서 netcat 을 이용해 포트 80 포트를 오픈합니다.

[User@laptop ~]# nc –l 80 > /tmp/mem.img

 

원격 시스템에 LiME LKM을 실행하고 포트 4444에서 TCP 연결을 대기하도록 구성합니다.

[root@vmtest ~]# insmod lime-2.6.32-431.5.1.el6.x86_64.ko "path=tcp:4444 format=lime"

 

원격 시스템의 다른 셸에서 netcat 을 이용하여 조사용 랩톱 (60.70.80.90은 랩톱 IP 주소)의 80 포트로  메모리 이미지를 전송합니다.

[root@vmtest ~]# nc localhost 4444 | nc 60.70.80.90 80

 

Memory Dump 정보를 확인합니다.

[root@vmtest ~]# ls -lah /tmp/mem.img 
-r--r--r--. 1 root root 1.0G Mar 9 08:11 /tmp/mem.img
[root@vmtest ~]# strings /tmp/mem.img | head -n 3
EMiL
root (hd0,0)
kernel /vmlinuz-2.6.32-431.5.1.el6.x86_64 ro root=/dev/mapper/vg_livecd-lv_root rd_NO_LUKS 

 

Memory Dump 가 완료되었으면 커널 모듈을 제거합니다.

[root@vmtest ~]# rmmod lime

 

Memory Dump 분석 전 복사본을 생성하여 분석작업을 진행하도록 합니다. 이때 빠지지않고 해야되는 중요한 것은 해시값을 계산하는 것입니다. md5sum 이나 shasum 을 사용해서 해시값을 계산하면 됩니다.

[root@vmtest ~]# md5sum mem.img
db5fd6e1dabb055f8bc77fd67d95b588 mem.img


[root@vmtest ~]# sha1sum mem.img
0a67af1d5fdc59bf42f4ae93d97580135786fe3c mem.img


[root@vmtest ~]# sha256sum mem.img
63e5814134a140691b452ac6e353bab73458263709da4cebd2fd6484d33b8954 mem.img

 

이렇게 얻은 Memory Dump 파일은 Volatility 등의 분석툴을 사용하여 분석할 수 있습니다.

 

 

[별첨]

LiME Github에서 2020년 8월 26일 이후 더 이상 유지 관리되고 있지 않다고 해서 우분투 24.04에서 테스트 해봤습니다.

[root@vmtest ~]# uname -a
Linux swordfish 6.11.0-25-generic #25~24.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 17:20:50 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

 

경고가 뜨긴 하지만 커널 모듈 빌드는 완료됩니다.

[root@vmtest src]# make
make -C /lib/modules/6.11.0-25-generic/build M="/root/lime/LiME-master/src" modules
make[1]: Entering directory '/usr/src/linux-headers-6.11.0-25-generic'
warning: the compiler differs from the one used to build the kernel
  The kernel was built by: x86_64-linux-gnu-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
  You are using:           gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
  CC [M]  /root/lime/LiME-master/src/disk.o
/root/lime/LiME-master/src/disk.c:45:5: warning: no previous prototype for ‘setup_disk’ [-Wmissing-prototypes]
   45 | int setup_disk(char *path, int dio) {
      |     ^~~~~~~~~~
/root/lime/LiME-master/src/disk.c:77:6: warning: no previous prototype for ‘cleanup_disk’ [-Wmissing-prototypes]
   77 | void cleanup_disk(void) {
      |      ^~~~~~~~~~~~
  CC [M]  /root/lime/LiME-master/src/hash.o
/root/lime/LiME-master/src/hash.c:53:5: warning: no previous prototype for ‘ldigest_init’ [-Wmissing-prototypes]
   53 | int ldigest_init(void) {
      |     ^~~~~~~~~~~~
/root/lime/LiME-master/src/hash.c:97:5: warning: no previous prototype for ‘ldigest_update’ [-Wmissing-prototypes]
   97 | int ldigest_update(void *v, size_t is) {
      |     ^~~~~~~~~~~~~~
/root/lime/LiME-master/src/hash.c:142:5: warning: no previous prototype for ‘ldigest_final’ [-Wmissing-prototypes]
  142 | int ldigest_final(void) {
      |     ^~~~~~~~~~~~~
/root/lime/LiME-master/src/hash.c:172:5: warning: no previous prototype for ‘ldigest_write_tcp’ [-Wmissing-prototypes]
  172 | int ldigest_write_tcp(void) {
      |     ^~~~~~~~~~~~~~~~~
/root/lime/LiME-master/src/hash.c:189:5: warning: no previous prototype for ‘ldigest_write_disk’ [-Wmissing-prototypes]
  189 | int ldigest_write_disk(void) {
      |     ^~~~~~~~~~~~~~~~~~
/root/lime/LiME-master/src/hash.c:215:6: warning: no previous prototype for ‘ldigest_clean’ [-Wmissing-prototypes]
  215 | void ldigest_clean(void) {
      |      ^~~~~~~~~~~~~
  LD [M]  /root/lime/LiME-master/src/lime.o
  MODPOST /root/lime/LiME-master/src/Module.symvers
  CC [M]  /root/lime/LiME-master/src/lime.mod.o
  LD [M]  /root/lime/LiME-master/src/lime.ko
  BTF [M] /root/lime/LiME-master/src/lime.ko
Skipping BTF generation for /root/lime/LiME-master/src/lime.ko due to unavailability of vmlinux
make[1]: Leaving directory '/usr/src/linux-headers-6.11.0-25-generic'
strip --strip-unneeded lime.ko
mv lime.ko lime-6.11.0-25-generic.ko

 

경고를 해결해 보겠습니다.

lime.h에 아래 선언들을 추가하세요

[root@vmtest src]# vi lime.c
...
#ifndef _LIME_DISK_H
#define _LIME_DISK_H

#include <linux/types.h>

int setup_disk(char *path, int dio);
void cleanup_disk(void);
ssize_t write_vaddr_disk(void *v, size_t is);

#endif

// hash
int ldigest_init(void);
int ldigest_update(void *v, size_t is);
int ldigest_final(void);
int ldigest_write_tcp(void);
int ldigest_write_disk(void);
void ldigest_clean(void);

// deflate
int deflate_begin_stream(void *out, size_t outlen);
int deflate_end_stream(void);
ssize_t deflate(const void *in, size_t inlen);
...

 

다음 줄을 main.c에서 수정하세요.

extern int ldigest_clean(void); // 수정 전
extern void ldigest_clean(void); // 수정 후

[root@vmtest src]# vi main.c
...
extern void ldigest_clean(void);
...

 

build.sh을 별도로 만드세요.

[root@vmtest src]# vi build.sh
#!/bin/bash

# build
make -C /lib/modules/$(uname -r)/build M="$(pwd)" CC=x86_64-linux-gnu-gcc-13 modules

# processing
if [ -f lime.ko ]; then
  strip --strip-unneeded lime.ko
  mv lime.ko lime-$(uname -r).ko
  echo "Done: lime-$(uname -r).ko created"
else
  echo "Error: lime.ko not found"
fi

[root@vmtest src]# chmod +x build.sh
[root@vmtest src]# ./build.sh
make: Entering directory '/usr/src/linux-headers-6.11.0-25-generic'
  LD [M]  /root/lime/LiME-master/src/lime.ko
  BTF [M] /root/lime/LiME-master/src/lime.ko
Skipping BTF generation for /root/lime/LiME-master/src/lime.ko due to unavailability of vmlinux
make: Leaving directory '/usr/src/linux-headers-6.11.0-25-generic'
Done: lime-6.11.0-25-generic.ko created

 

정상적으로 메모리가 덤프됩니다.(2025.05.20)

[root@vmtest src]# insmod lime-6.11.0-25-generic.ko "path=/tmp/mem.img format=raw"
[root@vmtest src]# ls -la /tmp/mem.img
-r--r--r-- 1 root root 4294367232 May 20 23:35 /tmp/mem.img

 

 

+ Recent posts