MacOS forensic I

Forensic, MacOS & Volatility

I recently came to investigate on a MacOS memory dump and raw disk. In this serie of posts there are some commands, guidelines and tricks I could not find while doing it with volatility on the memory dump.

Next, I will probably dump someone’s mac (as I do not possess one) to see if I can get my hands on a more recent version of the OS.

Determining the OS version

While there is a nice way of doing it when you have previous access to the system you are investigating on volatility’s page, that is not possible when the only things you are provided is a dump and no information.

However, version can be found in a string on the system:

$ grep -Eao "Version [0-9]+.[0-9]+ \([a-zA-Z0-9 ]+\)" file.dmp
Version 5.01 (Microsoft)
Version 10.8 (Build 12A269)
Version 10.8 (Build 12A269)
Version 10.8 (Build 12A269)
...

There are several occurences of 10.8, which is “Mountain Lion” (see here). Build number can be googled to confirm it. Also, if you have or get an account on Apple’s devs website, you can search the development kits page.

With that information, we will be able to get a corresponding OS profile for Volatility.

Get a Volatility profile

If you are lucky, there is an available profile for the MacOS version you determined on this repository. If not you will have to build it yourself (reference here).

Place it in a folder and for the next commands, use it as such:

$ ls profiles/
MountainLion_10.8.1_AMD.zip
$ vol.py --plugins=./profiles --profile=MacMountainLion_10_8_1_AMDx64 -f file.dmp mac_version

From now on, all Volatility’s mac plugins can be used, list them if you need a reminder:

$ vol.py --plugins=./profiles --profile=MacMountainLion_10_8_1_AMDx64 -f file.dmp -h | grep "mac_"

Processes

Probably the first thing you should look for are suspicious processes.

List processes

Running processes can be listed with mac_pslist:

$ vol.py --plugins=./profiles --profile=MacMountainLion_10_8_1_AMDx64 -f file.dmp mac_pslist
Offset             Name                 Pid      Uid      Gid      PGID     Bits         DTB                Start Time Ppid
------------------ -------------------- -------- -------- -------- -------- ------------ ------------------ ---------- --------
0xffffff801313f760 bash                 124      501      20       124      64BIT        0x0000000028ecd000 2020-11-22 20:07:02 UTC+0000 123
0xffffff8011f33300 login                123      0        20       123      64BIT        0x0000000027ddd000 2020-11-22 20:07:01 UTC+0000 147
0xffffff8013b955e0 Keychain Access      111      501      20       111      64BIT        0x00000000347cf000 2020-11-22 20:05:37 UTC+0000 126
...

Full command line can be retreived when available with mac_psaux:

Pid      Name                 Bits             Stack              Length   Argc     Arguments
-------- -------------------- ---------------- ------------------ -------- -------- ---------
111 Keychain Access      64BIT            0x00007fff548f2000      648        2 /Applications/Utilities/Keychain Access.app/Contents/MacOS/Keychain Access -psn_0_843982
123 login                64BIT            0x00007fff5d468000      680        3 /usr/bin/login login -pf user
124 bash                 64BIT            0x00007fff54c25000      672        1 /bin/bash -bash
...

Files

Memory-cached files belonging to running processes are the next useful information.

List files

Files in cache can be listed via mac_list_files:

$ vol.py --plugins=./profiles --profile=MacMountainLion_10_8_1_AMDx64 -f file.dmp mac_list_files | tee list_files
Offset (V)         File Path
------------------ ---------
0xffffff800eec0000 /usr/share/man/mann/lower.ntcl
0xffffff800e330000 /private/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/Cleanup At Startup/PKInstallSandboxManager/1.sandbox/Root/System/Library/PrivateFrameworks/ScreenReader.framework/Versions/A/Resources/VoiceOver Quickstart.app/Contents/Resources/VOTraining.bundle/Contents/Resources/zh_TW.lproj/Splash.nib
0xffffff800d79df80 /private/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/Cleanup At Startup/PKInstallSandboxManager/1.sandbox/Root/System/Library/PreferencePanes/ParentalControls.prefPane/Contents/Resources/Spanish.lproj
0xffffff800e8c85d0 /private/var/folders/zz/zyxvpxvq6csfxvn_n0000000000000/Cleanup At Startup/PKInstallSandboxManager/1.sandbox/Root/System/Library/SystemConfiguration/IPMonitor.bundle/Contents
...

A trick to locate interesting files is to get all extensions present in the list:

$ grep -oE "\.[a-z]{3,4}$" list_files | sort | uniq
.aif
.aiff
.app
.apsd
.asl
.bin
.caf
.car
.cfs
.cgi
...

Related commands:

mac_lsof       	Lists per-process opened files

Dump files

Once file list has been established, files can be dumped from memory image to disk with mac_dump_file:

$ vol.py --plugins=./profiles --profile=MacMountainLion_10_8_1_AMDx64 -f file.dmp mac_dump_file -O extracted_files/${offset}_${name} --file-offset ${offset}

I suggest to always prefix the name of dumped files with the “offset” field to not be confused later.

I took a semi-automatic way of doing it by writing an (ugly) script that takes input from mac_list_files and dump files in a dedicated folder each time:

#!/bin/bash

FILES=$1
OUTDIR=extracted_files/$2

while read f; do
    offset=$(echo "$f" | awk '{ print $1 }')
    name=$(echo "$f" | awk '{ print $2 }')
    name=$(basename $name)
    vol.py --plugins=./profiles --profile=MacMountainLion_10_8_1_AMDx64 -f file.dmp mac_dump_file -O ${OUTDIR}/${offset}_${name} --file-offset ${offset}
done < $FILES

and then grep and extract files containing a string of interest in their path:

$ grep -i "some_string" list_files > files_some_string
$ ./extract_files.sh files_some_string out_some_string

Probably not the best nor the cleanest solution but it accelerates the investigation.

Bash history

A nice plugin is mac_bash which allows you to see the Bash history:

$ vol.py --plugins=./profiles --profile=MacMountainLion_10_8_1_AMDx64 -f file.dmp mac_bash
Pid      Name                 Command Time                   Command
-------- -------------------- ------------------------------ -------
200 bash                 2020-11-22 12:00:32 UTC+0000   ls -lah
200 bash                 2020-11-22 12:00:32 UTC+0000   pwd
200 bash                 2020-11-22 12:00:32 UTC+0000   ping 8.8.8.8
200 bash                 2020-11-22 12:00:32 UTC+0000   ping 1.1.1.1
200 bash                 2020-11-22 12:00:32 UTC+0000   history
...

Related commands:

mac_bash	Recover bash history from bash process memory
mac_bash_env   	Recover bash's environment variables
mac_bash_hash   Recover bash hash table from bash process memory

Web history

Safari’s web history files can be found in /Users/<username>/Library/Caches/Metadata/Safari/History. “.webhistory” files contains URL and page title. “.plist” files contains a lot of useful information like URL, timestamps, number of visits… Plist files can be converted to XML on Linux using plistutil:

plistutil -i ./extracted_files/Safari/0xffffff800fc19d10_History.plist -o /tmp/History.xml

And read with any text editor.

The “Cache.db” or “Cache.db-journal” are SQLite3 databases. They contain useful information and can be investigated with sqlite3:

$ sqlite3 extracted_files/Safari/db/0xffffff800fb5ca28_Cache.db
SQLite version 3.34.0 2020-12-01 16:14:00
Enter ".help" for usage hints.
sqlite> .tables
cfurl_cache_blob_data       cfurl_cache_response      
cfurl_cache_receiver_data   cfurl_cache_schema_version
sqlite> select * from cfurl_cache_response;
552|0|-1256570452|0|http://www.apple.com/fr/startpage/|2018-11-23 14:23:20
553|0|-2011404520|0|http://clients1.google.com/complete/search?client=safari&q=go|2018-11-23 14:23:27
554|0|1967490288|0|http://clients1.google.com/complete/search?client=safari&q=goog|2018-11-23 14:23:28
...

I found a pretty good forensic article there that gives you examples of SQLite requests.

To be continued…

This is just a piece of what can be done on a MacOS memory dump, it lacks all section on Keychains, Evernote etc. Hopefully I will soon write a second post including these, to be continued ;)…

References