/usr/lib/python2.7/dist-packages/rekall/plugins/tools/live_darwin.py is in python-rekall-core 1.6.0+dfsg-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | #!/usr/bin/env python2
# Rekall Memory Forensics
# Copyright 2015 Google Inc. All Rights Reserved.
#
# Author: Michael Cohen scudette@google.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
__author__ = "Michael Cohen <scudette@google.com>"
"""A plugin to install relevant kernel modules to enable live analysis.
The intention is to allow the user to launch:
rekall live
and have Rekall install the right kernel module and connect to the driver on all
supported operating systems.
"""
import os
import subprocess
import tarfile
from rekall import plugin
from rekall import obj
from rekall import resources
from rekall import session
from rekall import utils
from rekall.plugins.addrspaces import pmem
class Live(plugin.TypedProfileCommand,
plugin.ProfileCommand):
"""Launch a Rekall shell for live analysis on the current system."""
name = "live"
PROFILE_REQUIRED = False
__args = [
dict(name="mode", default="Memory", type="Choices",
choices=session.LIVE_MODES,
help="Mode for live analysis."),
dict(name="driver_path",
help="Driver file to load"),
dict(name="device", default=r"/dev/pmem",
help="Device name to use"),
dict(name="unload", type="Boolean",
help="Just unload the driver and exit."),
dict(name="load", type="Boolean",
help="Just load the driver and exit."),
]
table_header = [
dict(name="Message")
]
def __init__(self, *args, **kw):
super(Live, self).__init__(*args, **kw)
# It is OK for non privileged sessions to use the default drivers.
if not self.session.privileged and self.plugin_args.driver:
raise plugin.PluginError(
"Installing arbitrary drivers is only available for "
"interactive or privileged sessions.")
self.driver_path = (self.plugin_args.driver_path or
resources.get_resource("MacPmem.kext.tgz"))
if self.driver_path is None:
raise IOError("Driver resource not found.")
# Did we load the driver? If so we need to clean up.
self.we_started_driver = False
def load_driver(self):
"""Unpack and load the driver."""
tarfile_handle = tarfile.open(self.plugin_args.driver_path)
# Try to extract the resource into a tempdir.
with utils.TempDirectory() as tmp_name:
self.session.logging.info("Unpacking driver to %s", tmp_name)
tarfile_handle.extractall(tmp_name)
# Change ownership of the extracted files to make sure they are
# owned by root otherwise they will not load.
for root, files, dirs in os.walk(tmp_name):
for f in files:
os.chown(os.path.join(root, f), 0, 0)
for d in dirs:
os.chown(os.path.join(root, d), 0, 0)
for member_name in tarfile_handle.getnames():
if member_name.endswith(".kext"):
self.member_name = member_name.lstrip("/")
full_driver_path = os.path.join(tmp_name,
self.member_name)
self.session.logging.info(
"Loading driver from %s", full_driver_path)
res = subprocess.check_call(
["kextload", full_driver_path])
if res != 0:
raise plugin.PluginError(
"Failed to load driver. Are you root?")
def live(self):
phys_as = obj.NoneObject("Unable to access physical memory")
if self.plugin_args.mode == "Memory":
try:
phys_as = pmem.MacPmemAddressSpace(
session=self.session,
filename=self.plugin_args.device)
except IOError as e:
self.session.logging.debug("%s", e)
self.load_driver()
phys_as = pmem.MacPmemAddressSpace(
session=self.session,
filename=self.plugin_args.device)
self.session.physical_address_space = phys_as
with self.session:
self.session.SetParameter("live_mode", self.plugin_args.mode)
self.session.SetParameter("session_name", "Live (%s)" %
self.plugin_args.mode)
def unload_driver(self):
tarfile_handle = tarfile.open(self.plugin_args.driver_path)
for member_name in tarfile_handle.getnames():
if not member_name.endswith(".kext"):
continue
self.member_name = member_name.lstrip("/")
# Try to extract the resource into a tempdir.
with utils.TempDirectory() as tmp_name:
tarfile_handle.extractall(tmp_name)
full_driver_path = os.path.join(tmp_name,
self.member_name)
self.session.logging.info(
"Unloading driver from %s", full_driver_path)
try:
subprocess.check_call(
["kextunload",
os.path.join(tmp_name, self.member_name)])
except Exception as e:
# There isnt much we can do about it here.
self.session.logging.debug(
"Unable to unload driver: %s" % e)
def close(self):
if self.we_started_driver:
self.unload_driver()
def collect(self):
yield ("Launching live memory analysis\n",)
try:
self.live()
renderer = self.session.GetRenderer()
# Launch the shell.
shell = self.session.plugins.shell()
shell.render(renderer)
finally:
self.close()
def __enter__(self):
self.live()
return self
def __exit__(self, exc_type, exc_value, trace):
self.close()
|