본문 바로가기
정보보호

LiME: 리눅스 및 안드로이드 메모리 획득 도구

by 공돌이티티 2024. 3. 11.
반응형

이 글은 LiME의 메뉴얼 내용을 토대로 설치방법부터 사용방법까지 정리한 글로, 실제 운용 환경에는 맞지 않을 수 있으니 LiME 공식 개발 페이지의 가이드를 참고하시기 바랍니다.

 

1. LiME이란?

LiME(과거 명칭 DMD)은 안드로이드 기반 장치를 포함한 리눅스 시스템의 휘발성 메모리 취득을 가능하게 하는 Loadable Kernel Module (LKM)입니다. 이 도구는 장치의 파일 시스템이나 네트워크를 통해 메모리를 획득할 수 있는 기능을 지원합니다. LiME은 안드로이드 장치로부터 전체 메모리 캡처를 할 수 있는 최초의 도구로서, 취득 과정에서 사용자 공간과 커널 공간 프로세스 간의 상호작용을 최소화함으로써 다른 리눅스 메모리 취득 도구들보다 더 포렌식적으로 안정된 메모리 덤프를 생성합니다.

 

2. LiME 다운로드

LiME을 다운로드하려면 LiME Forensics 페이지의 지침을 따르세요.

 

3. LiME 컴파일하기

3.1 리눅스용 LiME 컴파일

LiME은 대부분의 현대 리눅스 시스템에서 컴파일이 가능한 기본 Makefile과 함께 제공됩니다. LKM 사용에 대한 자세한 지침은 리눅스 소스와 함께 제공되는 Documentation/kbuild/modules.txt 파일을 참조하세요.

3.2 안드로이드용 LiME 크로스-컴파일

안드로이드 장치용 LiME을 크로스-컴파일하기 위해서는 추가 단계가 필요합니다.

 

- 환경 설정하기

프로세스를 간소화하기 위해, 먼저 몇 가지 환경 변수를 설정합니다. 터미널에서 다음 명령을 입력하세요.

export SDK_PATH=/path/to/android-sdk-linux/
export NDK_PATH=/path/to/android-ndk/
export KSRC_PATH=/path/to/kernel-source/
export CC_PATH=$NDK_PATH/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/
export LIME_SRC=/path/to/lime/src

 

- 커널 소스 준비하기

우리는 우리의 장치로부터 커널 설정을 검색하고 복사해야 합니다.

cd $SDK_PATH/platform-tools
./adb pull /proc/config.gz
gunzip ./config.gz
cp config $KSRC_PATH/.config

 

이후 모듈을 위한 커널 소스를 준비합니다.

cd $KSRC_PATH
make ARCH=arm CROSS_COMPILE=$CC_PATH/arm-eabi- modules_prepare

 

모듈 컴파일 준비하기

크로스-컴파일을 위한 Makefile을 생성해야 합니다. LiME 소스와 함께 제공되는 샘플 Makefile을 사용하세요. Makefile 내용은 다음과 비슷해야 합니다.

obj-m := lime.o
lime-objs := main.o tcp.o disk.o
KDIR := /path/to/kernel-source
PWD := $(shell pwd)
CCPATH := /path/to/android-ndk/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/
default:
$(MAKE) ARCH=arm CROSS_COMPILE=$(CCPATH)/arm-eabi- -C $(KDIR) M=$(PWD) modules

 

모듈 컴파일하기

cd $LIME_SRC
make

 

4. LiME 사용하기

LiME 사용법을 설명하기 위해, 안드로이드 장치에서 메모리를 취득하는 두 가지 예를 살펴보겠습니다. 먼저 TCP 연결을 통한 메모리 취득에 대해 논의한 다음, 장치의 SD 카드를 통해 메모리 덤프를 취득하는 방법에 대해 설명합니다. 다른 리눅스 장치에서의 LiME 사용법은 비슷하지만, Android debug bridge (adb)의 사용이 필요하지 않습니다.

 

4.1 LiME 파라미터

LiME 1.1 버전부터 LiME은 여러 출력 포맷을 지원하며, Volatility의 새로운 lime 주소 공간과 통합되는 맞춤형 lime 포맷도 지원합니다. 이는 LiME 커널 모듈을 설치할 때 추가 파라미터가 필요하다는 것을 의미합니다.

4.2 TCP를 통한 메모리 취득

과정의 첫 단계는 Android Debug Bridge (adb)를 사용하여 커널 모듈을 장치의 SD 카드로 복사하는 것입니다. 이어서 adb를 사용하여 장치의 TCP 포트에서 로컬 호스트의 TCP 포트로 포트 포워딩 터널을 설정합니다. adb를 통한 네트워크 전송은 장치의 네트워킹 구성을 변경하거나 무선 피어를 도입할 필요 없이 모든 네트워크 데이터를 USB를 통해 전송합니다. 다음으로 adb와 su를 사용하여 장치에서 루트 쉘을 획득합니다. 다음 명령을 실행하여, 디바이스가 컴퓨터에 연결되고 디바이스에서 디버깅이 활성화된 상태에서 진행합니다.

adb push lime.ko /sdcard/lime.ko
adb forward tcp:4444 tcp:4444
adb shell
su


메모리 취득은 두 부분으로 구성됩니다. 먼저 대상 장치가 지정된 TCP 포트에서 수신 대기해야 하며, 그 다음 호스트 컴퓨터에서 장치에 연결해야 합니다. 소켓이 연결되면 커널 모듈은 자동으로 취득한 RAM 이미지를 호스트 장치로 전송합니다.

adb 루트 쉘에서 다음 명령을 사용하여 커널 모듈을 설치합니다. TCP를 통해 메모리를 덤프하도록 하기 위해, path 파라미터를 "tcp"로 설정하고, 콜론과 adb가 포워딩하는 포트 번호를 따라붙입니다. 호스트 컴퓨터에서는 netcat을 연결하여 출력을 파일로 리디렉션합니다. "lime" 포맷 옵션도 선택합니다. 취득 과정이 완료되면, LiME은 TCP 연결을 종료합니다.

대상 안드로이드 장치에서 커널 모듈을 로드하는 명령:

# insmod /sdcard/lime.ko "path=tcp:4444 format=lime"


호스트에서는 다음 명령을 사용하여 TCP 포트 444를 통해 "ram.lime" 파일로 메모리 덤프를 캡처합니다:

nc localhost 4444 > ram.lime

 

4.3 디스크(SD 카드)로 메모리 취득하기

네트워크를 사용하지 않고 메모리 이미지를 직접 장치의 디스크에 쓰고 싶을 경우, LiME은 장치의 파일 시스템에 이미지를 기록하는 옵션을 제공합니다. 안드로이드에서는 일반적으로 SD 카드가 저장 매체로 사용됩니다.

케이스에 중요한 다른 증거가 SD 카드에 존재할 수 있기 때문에, 조사관은 종종 먼저 SD 카드의 이미지를 생성하여 미할당 공간을 보존하고자 합니다. 하지만 일부 안드로이드 폰, 예를 들어 HTC EVO 4G와 Droid 시리즈는 SD 카드를 배터리 아래에 위치시키거나 배터리로 가려져 있어서, 폰의 전원을 끄지 않고는 SD 카드를 제거할 수 없습니다. 따라서 조사관은 먼저 SD 카드의 이미지를 생성한 후, 메모리 이미지를 그 위에 기록해야 합니다. 이 과정은 포렌식 취득에서 일반적으로 '변동성 순서' 규칙을 위반하지만, 모든 증거를 적절히 보존하기 위해 필요합니다.

다행히도 안드로이드 장치에서 라이브 포렌식 분석(메모리 덤프 포함)을 수행할 때 SD 카드를 제거하지 않고도 이미징이 가능합니다. 예를 들어, 장치를 리눅스 기계에 연결하고 USB 스토리지를 활성화시키면 /dev/sd? 장치가 나타나고, 이를 통해 기존 방법(예: 리눅스 박스에서 dd 사용)으로 이미지를 생성할 수 있습니다. USB 스토리지 모드를 활성화하면 안드로이드 장치에서 SD 카드가 마운트 해제되므로, 포렌식적으로 유효한 이미지를 얻을 수 있습니다.

USB 스토리지 모드를 비활성화한 후, 이전 섹션에서 설명한 것과 동일한 단계를 사용하여 LiME 커널 모듈을 장치에 복사합니다. insmod를 사용하여 모듈을 설치할 때, path 파라미터를 /sdcard/ram.lime으로 설정하여 메모리 덤프를 기록할 파일을 지정합니다. 또한 "lime" 포맷 옵션을 선택합니다.

# insmod /sdcard/lime.ko "path=/sdcard/ram.lime format=lime"


취득 과정이 완료되면, 전화기를 종료하고 SD 카드를 제거하여 검사 장비로 메모리 덤프를 전송할 수 있습니다. 만약 전화기를 종료할 수 없는 경우, adb를 사용하여 메모리 덤프를 조사관의 기계로 전송할 수도 있습니다.

 

5. LiME 메모리 범위 헤더 버전 1 명세

메모리 취득에 사용되는 LiME 메모리 범위 헤더의 버전 1 명세를 아래와 같이 정의할 수 있습니다.

typedef struct {
    unsigned int magic; // 항상 0x4C694D45 (LiME)
    unsigned int version; // 헤더 버전 번호
    unsigned long long s_addr; // 물리적 RAM 범위의 시작 주소
    unsigned long long e_addr; // 물리적 RAM 범위의 끝 주소
    unsigned char reserved[8]; // 현재 모두 0
} __attribute__ ((__packed__)) lime_mem_range_header;


이 명세는 메모리 취득 시 각 RAM 범위의 메타데이터를 담아 Volatility 같은 분석 도구와 호환되게 합니다.

반응형

바로가기