This file is indexed.

/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()