Wednesday, June 5, 2013

MOVP II - 4.1 - Leveraging Process Cross-View Analysis for Mac Rootkit Detection

In our final week of Month of Volatility Plugins II we will analyze the wide range of memory forensics capabilities against Mac OS X systems that are included in the latest release of Volatility (version 2.3). These capabilities span 38 different builds including 32- and 64-bit 10.5.x through 10.8.3, which is the latest version at the time of writing.

Our post today will cover finding processes in a number of places in kernel memory and analyzing information about them. In the end we will discuss the mac_psxview plugin, which is a powerful plugin for detecting hidden processes.

mac_pslist

This plugin enumerates processes by walking the allproc list. It then prints the virtual address, name, PID, user and group ID, and architecture of the process (32 or 64 bit). Read our post tomorrow on process memory for the importance of accurately determining the per-process architecture.

$ python vol.py --profile=MacMountainLion_10_8_3_AMDx64 -f 10.8.3.mmr.macho mac_pslist
Volatile Systems Volatility Framework 2.3_alpha
Offset             Name                 Pid      Uid      Gid   PGID     Bits         DTB                Start Time
------------------ -------------------- -------- -------- ----- --------
0xffffff8032be4ea0 image              4175     0        0        4167     64BIT        0x317e7e000 2013-03-29 12:16:20 UTC+0000
0xffffff803dfdea40 coresymbolicatio   4173     0        0        4173     64BIT        0x4114c0000 2013-03-29 12:16:18 UTC+0000
0xffffff8032498d20 MacMemoryReader    4168     0        0        4167     64BIT        0x3f94a8000 2013-03-29 12:16:17 UTC+0000
0xffffff803dfe0020 sudo               4167     0        20       4167     64BIT        0x414a34000 2013-03-29 12:16:15 UTC+0000
0xffffff803dfe1a60 mdworker           4164     89       89       4164     64BIT        0x3f70cf000 2013-03-29 12:15:32 UTC+0000
0xffffff80370af760 DashboardClient    4160     501      20       275      64BIT        0x3e5bd9000 2013-03-29 12:14:36 UTC+0000
0xffffff803634ba60 CVMCompiler        4127     501      20       4127     64BIT        0x16692b000 2013-03-29 12:10:58 UTC+0000
0xffffff80370b11a0 cookied            4126     501      20       4126     64BIT        0x3137cc000 2013-03-29 12:10:58 UTC+0000
0xffffff803dfe1600 WebProcess         4124     501      20       4121     64BIT        0x3f235a000 2013-03-29 12:10:57 UTC+0000
0xffffff803249c600 taskgated          4122     0        0        4122     64BIT        0x3f3038000 2013-03-29 12:10:57 UTC+0000
0xffffff80314a9d40 Safari             4121     501      20       4121     64BIT        0x3f616c000 2013-03-29 12:10:57 UTC+0000
[snip]

Note:
Our testing of Mac memory acquisition tools showed that at some point every tool smeared the process list and would throw the plugin into an endless loop on a process that was exiting/had exited after the acquisition began. These processes would have invalid "next" pointers due to their being out of sync with the rest of the acquired processes. Due to the frequency in which we saw this issue, we added a check in the plugin and once this condition is detected, the following is printed and the plugin exits:

"Recursive process list detected (a result of non-atomic acquisition). Use mac_tasks or mac_psxview"

mac_psaux

This plugin enumerates processes, but instead of printing the name from the kernel buffer, it reads the command line arguments from process memory.  Knowing the arguments is very useful

mac_pstree

The pstree plugin shows the parent/child relationship between processes. This is very helpful when trying to find the source of a process, such as user vs daemon, user vs malware, and so on. In general, there will be a kernel_task process with PID 0 followed by a launchd process with PID 1. All other processes will then be the child of this initial PID 1 process.  As can be seen in the following output, this relationship is shown by the number of dots before each process name.

$ python vol.py --profile=MacMountainLion_10_8_2_AMDx64 -f Mac-10.8.2.vmem mac_pstree
Volatile Systems Volatility Framework 2.3_beta
Name                 Pid             Uid
kernel_task          0               0
.launchd             1               0
..com.apple.dock.e   208             501
..IMRemoteURLConne   206             501
..filecoordination   205             0
..launchd            200             88
...cfprefsd          203             88
..xpcd               172             501
..coreaudiod         166             202
..apsd               154             0
..locationd          143             205
..launchd            128             92
...CVMCompiler       130             92
..CVMServer          127             0
..launchd            117             501

mac_tasks

mac_tasks enumerates processes by walking the "tasks" list in the kernel and then using the "bsd_info" member of each task to determine the associated process. Due to the smearing issues with mac_pslist, the tasks plugin is used to generate a list of processes for the per-process information plugins we will learn about throughout the week.


$ python vol.py --profile=MacMountainLion_10_8_3_AMDx64 -f ~/10.8.3.mmr.macho mac_tasks
Volatile Systems Volatility Framework 2.3_alpha
Offset             Name                 Pid      Uid      Gid      PGID     Bits         DTB           Start Time
------------------ -------------------- -------- -------- -------- ------   ----         ------------  --------------------   
0xffffff800fada2d0 kernel_task          0        0        0        0        64BIT        0x11e9f000    2013-03-29 01:08:47 UTC+0000
0xffffff80314aaa60 launchd              1        0        0        1        64BIT        0x11234000    2013-03-29 01:08:47 UTC+0000
0xffffff80314a98e0 UserEventAgent       11       0        0        11       64BIT        0xbe18000     2013-03-29 01:08:49 UTC+0000
0xffffff80314aa1a0 kextd                12       0        0        12       64BIT        0xbecb000     2013-03-29 01:08:49 UTC+0000
0xffffff80314a9480 notifyd              14       0        0        14       64BIT        0x23b9b000    2013-03-29 01:08:49 UTC+0000
0xffffff80314a9020 securityd            15       0        0        15       64BIT        0x1dd43000    2013-03-29 01:08:49 UTC+0000
[snip]

As shown in the output, mac_tasks uses the same rendering (print) function as mac_pslist.

mac_pgrp_hash_table

This plugin enumerates processes by walking the process group hash table, pgrphashtbl. It uses the same rendering function as mac_pslist and mac_tasks.

mac_pid_hash_table

This plugin enumerates processes by walking the process ID hash table, pidhashtbl.  It uses the same rendering function as mac_pslist and mac_tasks.

mac_psxview

The process cross view function is used to find hidden processes by comparing the set of processes found from each source. If we look at the output of the plugin, we see the offset, name, and PID for each process along with a True or False if it was found in each source:

$ python vol.py --profile=MacMountainLion_10_8_3_AMDx64 -f ~/Desktop/Storage/memory/Mac/10.8.3/10.8.3.mmr.macho mac_psxview
Volatile Systems Volatility Framework 2.3_alpha
Offset(P)          Name                    PID pslist parents pid_hash pgrp_hash_table session leaders task processes
------------------ -------------------- ------ ------ ------- -------- --------------- --------------- --------------
0xffffff800fada2d0 kernel_task               0 True   True    False    True            True            True          
0xffffff80314aaa60 launchd                   1 True   True    True     True            True            True          
0xffffff80314a98e0 UserEventAgent           11 True   False   True     True            True            True          
0xffffff80314aa1a0 kextd                    12 True   False   True     True            True            True          
0xffffff80314a9480 notifyd                  14 True   False   True     True            True            True          
0xffffff80314a9020 securityd                15 True   False   True     True            True            True          
0xffffff80314a8bc0 diskarbitrationd         16 True   False   True     True            True            True          
0xffffff80314a8760 configd                  17 True   False   True     True            True            True 

The columns that map directly to plugins we previously discussed are pslist, pid_hash, pgrp_hash_table, and task processes. The two columns that were not discussed are parents and 'session leaders'. Parents gathers tasks by walking the process list and retrieving the parent process pointer for each process. This would detect rootkits that unlink a process that has active children. 'Session leaders' leverages the mac_list_sessions plugin and gathers the process that is the leader of each session.

Note: As with the Windows and Linux versions of psxview, just because a column says False does not immediately mean a process is hidden. For example, every process does not spawn child processes, so they will not all appear in parents. Similarly, not every process is a session leader.

psxview is a very powerful plugin as a rootkit would have to hide the process from potentially six different sources while still keeping the system stable.

Conclusion

In this blog post we have covered a number of plugins that are able to recover processes from OS X kernel memory as well as the psxview plugin that can use these to detect rootkits. Tomorrow we will discuss OS X process memory as well as the oddities of the OS that caused us quite a few headaches while developing the capabilities.

No comments:

Post a Comment