Monday, October 12, 2015

Android memory Analysis (I) - Preparing the enviroment

During this post I will describe how to setup an environment to perform memory analysis in Android. The analysis of memory is very useful while analyzing malware which use encryption at some point. Because of that, in future posts, I will analyze a real piece of malware as a real scenario 

Also, during several post I will analyze other aspects of the malware.


The lab is composed of: a Physical Android Nexus 5 device running Android 5.1.1, MacOSX with Android SDK and a virtual Machine running Ubuntu 14.04

The main idea behind the analysis is to dump the memory of the smartphone and find as much evidence as possible. For this purpose I will use Linux Memory Extractor (LiME) and Volatility.
LiME works as a module in the kernel and in order to do that two things must be accomplished: the Linux kernel in Android must support 'modprobes', hence it is necessary to recompile the kernel in Android,  and LiME must be cross-compile for Android.

Recompiling the kernel with modules support

A very good reference to understand how to compile the kernel in Android with modprobe can be found here.


# Getting the right kernel sources

# check the kernel version
$ adb shell cat /proc/version | grep -e "[0-9.]*-g[a-z0-9]*" –o

# Checkout the correct commit from that kernel version


$ cd msm; git checkout bebb36b

$ git pull

# Create kernel configuration with kprobes to be able to load modules into kernel
# create the .config
$ cd msm; ARCH=arm make hammerhead_defconfig
# Append the following lines to the .config in order to support modules:

CONFIG_KPROBES=y
CONFIG_KPROBES_SANITY_TEST=y 
# CONFIG_KPROBE_EVENT is not set
# CONFIG_ARM_KPROBES_TEST is not set 
CONFIG_NET_TCPPROBE=y # seems necessary otherwise kernel does not boot CONFIG_MODULES=y # kprobes requires module support and makes no sense without CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y 
CONFIG_MODULE_FORCE_UNLOAD=y 
CONFIG_MODVERSIONS=y # possible to use modules compiled for different kernels
 # CONFIG_MODULE_SRCVERSION_ALL is not set

ARCH=arm make menuconfig 


# obtain  the toolchains for cross-compile Android >5.0 (arm-eabi-)

# cross compile the kernel
$ cd msm; ARCH=arm CROSS_COMPILE=../arm-eabi-4.7/bin/arm-eabi- make
# if any question is asked for the new options of the kernel just choose the default

# Preparing the boot image (kernel + ramdisk) from the one existing in the device
# obtaining the existing one
$ adb shell su -c "ls -al /dev/block/platform/msm_sdcc.1/by-name/boot"

$ adb shell su -c "dd if=/dev/block/mmcblk0p19 of=/sdcard/my_nexus5_boot.img”
$ adb pull /sdcard/my_nexus5_boot.img

# Unpack original image and repack with our customize kernel
# it is necessary the tools unmkbootimg (unpacking) and mkbootimg (packing)
$ git clone https://github.com/pbatard/bootimg-tools.git $ cd bootimg-tools; make

# Unpack the boot image
$./bootimg-tools/mkbootimg/unmkbootimg -i my_nexus5_boot.img

# rebuild the boot image
$mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x00008000 --ramdisk_offset 0x02900000 --second_offset 0x00f00000 --tags_offset 0x02700000 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1' --kernel kernel --ramdisk ramdisk.cpio.gz -o my_nexus5_boot.img

# if everything went fine you should have the files “kernel” and ramdisk.cpio.gz
# Now it is is necessary to repack everything
$ booting-img/bootimg-tools/mkbootimg/mkbootimg --base 0 --pagesize 2048 --kernel_offset 0x00008000 --ramdisk_offset 0x02900000 --second_offset 0x00f00000 --tags_offset 0x02700000 --cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=hammerhead user_debug=31 maxcpus=2 msm_watchdog_v2.enable=1' --kernel ./msm/arch/arm/boot/zImage-dtb --ramdisk ramdisk.cpio.gz -o my_nexus5_kprobes_boot.img

# Finally boot the device with the new boot image
# This is done from the MacOSX system
$ adb reboot bootloader
$ sudo fastboot boot my_nexus5_kprobes_boot.img  
--------------------------------------------------------------------------------------------------------------------------------------------

Compiling LiME for Android

A good reference to compile LiME in Android is in : https://code.google.com/p/volatility/wiki/AndroidMemoryForensics


# Get the source code

# Backing up the Makefile and editing it
$ cd /home/angel/Android2/lime/LiME/src
$ cp Makefile Makefile.bkp
$ vim.tiny Makefile

# The content of the Makefile needs to reference to the Android kernel ‘msm’ directory
# Also it needs the cross-compiler arm-eabi-4.7 installed when compiling Android 
# kernel. An example of Make file is as follow:

obj-m := lime.o
lime-objs := tcp.o disk.o main.o

# KDIR where the kernel source code is
KDIR := ~/Android2/kernel/msm

KVER := $(shell uname -r)

PWD := $(shell pwd)

default:
$(MAKE) ARCH=arm CROSS_COMPILE=~/Android2/arm-eabi-4.7/bin/arm-eabi- -C $(KDIR) M=$(PWD) modules
strip --strip-unneeded lime.ko
mv lime.ko lime-$(KVER).ko



# Now it is time to compile with Make. Although there might be some errors, if the file  ‘lime.ko’  is presented, the compilation is success
$ make
make ARCH=arm CROSS_COMPILE=~/Android2/arm-eabi-4.7/bin/arm-eabi- -C ~/Android2/msm M=/home/angel/Android2/lime/LiME/src modules
make[1]: Entering directory `/home/angel/Android2/msm'
CC [M] /home/angel/Android2/lime/LiME/src/tcp.o
CC [M] /home/angel/Android2/lime/LiME/src/disk.o
CC [M] /home/angel/Android2/lime/LiME/src/main.o
LD [M] /home/angel/Android2/lime/LiME/src/lime.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/angel/Android2/lime/LiME/src/lime.mod.o
LD [M] /home/angel/Android2/lime/LiME/src/lime.ko
make[1]: Leaving directory `/home/angel/Android2/msm'
strip --strip-unneeded lime.ko
strip: Unable to recognise the format of the input file `lime.ko'
make: *** [default] Error 1

# checking the module ‘lime.ko’ exists

$ ls -l
total 1484
-rw-rw-r-- 1 angel angel 290 Sep 4 08:20 Makefile
-rw-rw-r-- 1 angel angel 1646 Sep 4 08:15 Makefile.bkp
-rw-rw-r-- 1 angel angel 1723 Sep 4 08:14 Makefile.sample
-rw-rw-r-- 1 angel angel 0 Sep 4 08:21 Module.symvers
-rw-rw-r-- 1 angel angel 2379 Sep 4 08:14 disk.c
-rw-rw-r-- 1 angel angel 158756 Sep 4 08:21 disk.o
-rw-rw-r-- 1 angel angel 1821 Sep 4 08:14 lime.h
-rw-rw-r-- 1 angel angel 491708 Sep 4 08:21 lime.ko
-rw-rw-r-- 1 angel angel 1203 Sep 4 08:21 lime.mod.c
-rw-rw-r-- 1 angel angel 18380 Sep 4 08:21 lime.mod.o
-rw-rw-r-- 1 angel angel 474393 Sep 4 08:21 lime.o
-rw-rw-r-- 1 angel angel 5303 Sep 4 08:14 main.c
-rw-rw-r-- 1 angel angel 162856 Sep 4 08:21 main.o
-rw-rw-r-- 1 angel angel 50 Sep 4 08:21 modules.order
-rw-rw-r-- 1 angel angel 3543 Sep 4 08:14 tcp.c
-rw-rw-r-- 1 angel angel 160484 Sep 4 08:21 tcp.o

# Time to push the module to the device
$ adb push lime.ko /sdcard/lime.ko
$ adb shell 'ls -l /sdcard/lime.ko'
-rw-rw---- root sdcard_r 491708 2015-09-04 17:52 lime.ko


# Two different ways of loading the module and dumping the memory
# option 1: dumping the memory to the sdcard 
$ insmod /sdcard/lime.ko "path=/sdcard/lime.dump format=lime”

# option 2: dumping the memory through ‘netcat ‘ into the host
# preparing port forwarding through ADB
$ adb forward tcp:4444 tcp:4444
$ adb shell
$ insmod /sdcar/lime.ko “path=tcp:4444 format=lime”

# In the destination host it is necessary to run netcat
$ nc localhost 4444 > lime2.dump
 --------------------------------------------------------------------------------------------


Creating a Volatility Profile base on the customize kernel

A good reference to compile Volatility in Android is in  https://code.google.com/p/volatility/wiki/AndroidMemoryForensics


# Install dwarfdump
$ apt-get install dwarfdump

# download volatility source

$ cd volatility/volatility/tools/linux

# Edit Makefile to reference to the ARM cross compiler ‘arm-eabi-4.7/bin’.
$ cd volatility/volatility/tools/linux
# An example of Makefile:
obj-m += module.o
KDIR := ~/Android2/msm
KVER ?= $(shell uname -r)
CCPATH := ~/Android2/arm-eabi-4.7/bin
DWARFDUMP := /usr/bin/dwarfdump
-include version.mk
all: dwarf
dwarf: module.c
$(MAKE) ARCH=arm CROSS_COMPILE=$(CCPATH)/arm-eabi- -C $(KDIR) CONFIG_DEBUG_INFO=y M=$(PWD) modules
$(DWARFDUMP) -di module.ko > module.dwarf

# compile with make.
$ make
# example of output:
make ARCH=arm CROSS_COMPILE=~/Android2/arm-eabi-4.7/bin/arm-eabi- -C ~/Android2/msm CONFIG_DEBUG_INFO=y M=/home/angel/Android2/volatility/volatility/tools/linux modules
make[1]: Entering directory `/home/angel/Android2/msm'
CC [M] /home/angel/Android2/volatility/volatility/tools/linux/module.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/angel/Android2/volatility/volatility/tools/linux/module.mod.o
LD [M] /home/angel/Android2/volatility/volatility/tools/linux/module.ko
make[1]: Leaving directory `/home/angel/Android2/msm'
/usr/bin/dwarfdump -di module.ko > module.dwarf


# Check that the header is similar to this:
$ head module.dwarf
.debug_info
<0><0x0+0xb><DW_TAG_compile_unit> DW_AT_producer<"GNU C 4.7"> DW_AT_language<DW_LANG_C89> DW_AT_name<"/home/angel/Android2/volatility/volatility/tools/linux/module.c"> DW_AT_comp_dir<"/home/angel/Android2/msm"> DW_AT_stmt_list<0x00000000>
<1><0x1d><DW_TAG_typedef> DW_AT_name<"__s8"> DW_AT_decl_file<0x00000001 include/asm-generic/int-ll64.h> DW_AT_decl_line<0x00000013> DW_AT_type<<0x00000028>>
<1><0x28><DW_TAG_base_type> DW_AT_byte_size<0x00000001> DW_AT_encoding<DW_ATE_signed_char> DW_AT_name<"signed char">
<1><0x2f><DW_TAG_typedef> DW_AT_name<"__u8"> DW_AT_decl_file<0x00000001 include/asm-generic/int-ll64.h> DW_AT_decl_line<0x00000014> DW_AT_type<<0x0000003a>>
<1><0x3a><DW_TAG_base_type> DW_AT_byte_size<0x00000001> DW_AT_encoding<DW_ATE_unsigned_char> DW_AT_name<"unsigned char">
<1><0x41><DW_TAG_typedef> DW_AT_name<"__s16"> DW_AT_decl_file<0x00000001 include/asm-generic/int-ll64.h> DW_AT_decl_line<0x00000016> DW_AT_type<<0x0000004c>>
<1><0x4c><DW_TAG_base_type> DW_AT_byte_size<0x00000002> DW_AT_encoding<DW_ATE_signed> DW_AT_name<"short int">


# Now combine module.dwarf and the System.map from your android kernel
# source code into a zip file
$ zip ~/Android2/volatility/volatility/volatility/plugins/overlays/linux/Nexus5-511.zip module.dwarf ~/Android2/msm/System.map

# Check the new profile exists (in this case is the first one)
$ python vol.py --info | grep Linux
Volatility Foundation Volatility Framework 2.4
LinuxNexus5-511ARM - A Profile for Linux Nexus5-511 ARM
linux_banner - Prints the Linux banner information
linux_yarascan - A shell in the Linux memory image

---------------------------------------------------------------------------------------------------------------------------------

At this stage the smartphone is setup and ready to run the malware and perform the memory analysis. This will be done in the next post :)