Mac OS X memory analysis with Volafox

Kyeong-Sik Lee and the Korean Digital Forensic Research Center have released Volafox, a free and open-source tool to analyze Mac OS X memory images. Volafox is based on work by Matthieu Suiche (paper and slides) and the Volatility memory analysis framework.

Volafox is written in pure Python and requires Python 2.5 or later. You simply download and unzip the archive. The tool's usage is straight forward:

$ python
Memory analyzer for OS X 0.5 - n0fate
this program need to physical memory image, kernel image(mach_kernel)
and it support to Intel x86 Architecture only :(
os_version	 Dawin kernel detail version
machine_info	 Kernel version, cpu, memory information
mount_info	 Mount information
kern_kext_info	 Kernel KEXT(Kernel Extensions) information
kext_info	 KEXT(Kernel Extensions) information
proc_info	 Process list
syscall_info	 Kernel systemcall information

The memory image needs to be in plain format. So, it can not process images that were obtained by ATC-NY's Mac Memory Reader without further format conversion. Having a Mach-O Address Space for this would be a nice addition.

While it should be possible to find the kernel in the memory dump, this has not been implemented (yet) and Volafox requires a separate kernel image.

For starters, I suggest to go with the sample files that were provided by the author: a memory image and the proper Mach kernel. Now let's find out about the OS version first:

$ python -i MemoryImage.mem -s mach_kernel -o os_version
Memory Image: MemoryImage.mem
Kernel Image: mach_kernel
Information: os_version
Detail dawin kernel version: 10A432

This command displays the ProductBuildVersion that you can also find in /System/Library/CoreServices/SystemVersion.plist.

Here is some more information about the machine:

$ python -i MemoryImage.mem -s mach_kernel -o machine_info
Memory Image: MemoryImage.mem
Kernel Image: mach_kernel
Information: machine_info
-= Mac OS X Basic Information =-
Major Version: 10
Minor Version: 0
Number of Physical CPUs: 2
Size of memory in bytes: 536870912 bytes
Size of physical memory: 536870912 bytes
Number of physical CPUs now available: 2
Max number of physical CPUs now possible: 2
Number of logical CPUs now available: 2
Max number of logical CPUs now possible: 2

Volafox can traverse the list of mounted file systems:

$ python -i MemoryImage.mem -s mach_kernel -o mount_info
Memory Image: MemoryImage.mem
Kernel Image: mach_kernel
Information: mount_info
-= Mount List =-
list entry	fstypename	mount on name	mount from name
0304a290	hfs	/	/dev/disk0s2
03049948	devfs	/dev	devfs
03049000	autofs	/net	map -hosts
0403d520	autofs	/home	map auto_home
00000000	vmhgfs	/Volumes/VMware Shared Folders	.host:/

OS X maintains a doubly-linked list of processes; the list head is reachable via the kernproc symbol (see Mattieu Suiche's paper).

$ python -i MemoryImage.mem -s mach_kernel -o proc_info
Memory Image: MemoryImage.mem
Kernel Image: mach_kernel
Information: proc_info
-= process list =-
list_entry_next	pid	ppid	process name	username
03290d20	0	0	kernel_task		
03290a80	1	0	launchdask	n0fate	
032902a0	2	1	launchctlk	root	
032907e0	10	1	kextddask	root	
03290540	11	1	DirectoryService	root	
03290000	12	1	notifydask	root	
0359bd20	13	1	diskarbitrationd	root	
0359ba80	14	1	configdask	root	
0359b7e0	15	1	syslogdask	root	
0359b540	16	1	distnotedk	root	
0359b000	17	1	mDNSResponder	_mdnsresponder	
0359b2a0	19	1	securitydk	_mdnsresponder	
03a5a7e0	24	1	ntpdhdask	_mdnsresponder	
03bc7d20	26	1	usbmuxdask	_usbmuxd	
03bc7a80	30	1	mdschdask	_mdnsresponder	
03bc77e0	31	1	loginwindow	n0fate	
03bc72a0	32	1	KernelEventAgent	_mdnsresponder	
03bc7000	34	1	hiddhdask	_mdnsresponder	
03bdaa80	35	1	fseventsdk	_mdnsresponder	
03befd20	37	1	dynamic_pager	_mdnsresponder	
03bef7e0	42	1	autofsdask	_mdnsresponder	
03a5a2a0	53	1	taskgatedk	_usbmuxd	
03bdad20	54	1	coreservicesd	root	
03a5a540	55	1	WindowServer	root	
03bda540	57	1	vmware-tools-dae	_mdnsresponder	
03a5a000	74	1	airportdsk	_atsserver	
03befa80	78	1	coreaudiod	_coreaudiod	
03bda2a0	79	1	launchdask	n0fate	
03bef000	83	79	Dockhdask	n0fate	
03bc7540	84	79	SystemUIServer	n0fate	
04166d20	85	79	Finderask	n0fate	
03bef2a0	92	79	fontddask	n0fate	
041667e0	95	79	pboardask	n0fate	
04166000	96	79	quicklookd	n0fate	
044ddd20	99	79	UserEventAgent	n0fate	
044dd000	100	79	ServerScanner	n0fate	
044fed20	105	79	AirPort Base Sta	n0fate	
044dd7e0	106	79	vmware-tools-use	n0fate	
044dd540	108	79	CCacheServer	n0fate	
03bda000	110	79	TISwitcher	n0fate	
0085e758	120	1	backupdask	n0fate

A process can be selected by its PID in order to display a few more details:

$ python -i MemoryImage.mem -s mach_kernel -o proc_info -x 120
Memory Image: MemoryImage.mem
Kernel Image: mach_kernel
Information: proc_info
Dump PID: 120
-= process: 120=-
list_entry_next	pid	ppid	process name		username
0085e758	120	1	backupdask	n0fate
task_ptr: 3bd81f4
vm_map_t: 41b2520
prev: 46145d8
next: 461402c
start: 100000000
end: 7fffffe00000
neutries: 3a
entries_pageable: 1
pmap_t: 3bf59f8
page directory pointer: 3bf5828
phys.address of dirbase: 4705c2400000000
object to pde: 1
ref count: 1
nx_enabled: 2
task_map: 0
pm_cr3: 0
pm_pdpt: 25c00000259
pm_pml4: 127df00000000000

Volafox also enumerates lists of kernel extensions and system calls. It will raise a flag if a syscall appears to be hooked.



This blog is a project of:
Andreas Schuster
Im Äuelchen 45
D-53177 Bonn

Copyright © 2005-2012 by
Andreas Schuster
All rights reserved.