Beispiel #1
0
from builtins import object
import pickle
import io
import os
import six
import time

from rekall import config
from rekall import io_manager
from rekall import obj
from rekall.ui import json_renderer
from rekall_lib import utils

config.DeclareOption("--cache",
                     default="file",
                     type="String",
                     choices=["file", "memory", "timed"],
                     help="Type of cache to use. ")

config.DeclareOption("--cache_expiry_time",
                     default=600,
                     type="Float",
                     help="Expiry times for timed caches. ")


class RestrictedUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        # Only allow safe classes from builtins.
        if module == "builtins" and name in safe_builtins:
            return getattr(builtins, name)
        # Forbid everything else.
Beispiel #2
0
import socket
import struct

import arrow

from rekall import config
from rekall import obj
from rekall.plugins.overlays import native_types
from rekall_lib import utils

if six.PY3:
    long = int

config.DeclareOption(
    "--timezone",
    default="UTC",
    group="Interface",
    help="Timezone to output all times (e.g. Australia/Sydney).")


class String(obj.StringProxyMixIn, obj.NativeType):
    """Class for dealing with Null terminated C Strings.

    Note that these strings are _not_ text strings - they are effectively bytes
    arrays and therefore are not encoded in any particular unicode encoding.
    """
    def __init__(self,
                 length=1024,
                 max_length=1024000,
                 term=b"\x00",
                 **kwargs):
from rekall import addrspace
from rekall import config
from rekall import obj
from rekall import plugin
from rekall import testlib
from rekall import utils
from rekall.plugins.common import address_resolver
from rekall.plugins.windows import common
from rekall.plugins.overlays.windows import pe_vtypes
from rekall.plugins.overlays.windows import windows

config.DeclareOption(
    "autodetect_build_local_tracked",
    group="Autodetection Overrides",
    default=["nt", "win32k", "tcpip", "ntdll"],
    type="ArrayStringParser",
    help="When autodetect_build_local is set to 'basic' we fetch these "
    "modules directly from the symbol server.")

# In windows there are two types of mapped PE files - kernel modules and Dlls.


class PEModule(address_resolver.Module):
    """Windows overlays PE files in memory."""

    _profile = None

    def detect_profile_from_session(self):
        """Get the module guid from the session cache.
Beispiel #4
0
""" This is based on Jesse Kornblum's patch to clean up the standard AS's.
"""
# pylint: disable=protected-access

import struct

from rekall import addrspace
from rekall import config
from rekall import obj
from rekall import utils
from rekall.plugins.addrspaces import intel
from rekall.plugins.addrspaces import standard


config.DeclareOption("ept", group="Virtualization support",
                     type="ArrayIntParser",
                     help="The EPT physical address.")


class AMD64PagedMemory(intel.IA32PagedMemoryPae):
    """Standard AMD 64-bit address space.

    Provides an address space for AMD64 paged memory, aka the x86_64
    architecture, which is laid out similarly to Physical Address
    Extensions (PAE). Allows callers to map virtual address to
    offsets in physical memory.

    Create a new AMD64 address space to sit on top of the base address
    space and a Directory Table Base (CR3 value) of 'dtb'.

    Comments in this class mostly come from the Intel(R) 64 and IA-32
                                 volatile=False)
                session.SetCache("dtb", address_space.dtb, volatile=False)

            return profile

    def DetectFromHit(self, hit, file_offset, address_space):
        """Gets called for each hit.

        If a profile matches, return it, otherwise None.
        """


# By default use all detection modules.
config.DeclareOption("autodetect", group="Autodetection Overrides",
                     type="ChoiceArray", required=True,
                     choices=utils.JITIterator(DetectionMethod),
                     default=utils.JITIterator(DetectionMethod),
                     help="Autodetection method.")

config.DeclareOption("autodetect_threshold", default=1.0,
                     group="Autodetection Overrides",
                     help="Worst acceptable match for profile autodetection." +
                     " (Default 1.0)",
                     type="Float")

config.DeclareOption("autodetect_build_local", default="basic",
                     group="Autodetection Overrides",
                     choices=["full", "basic", "none"],
                     help="Attempts to fetch and build profile locally.",
                     type="Choices")
Beispiel #6
0
from rekall import config
from rekall import constants
from rekall import plugin
from rekall import session
from rekall import quotas

from pkg_resources import iter_entry_points
for entry_point in iter_entry_points(group='rekall.plugins', name=None):
    entry_point.load()

# Load all the plugins.
from rekall import plugins  # pylint: disable=unused-import


config.DeclareOption(
    "--version", default=False, type="Boolean",
    help="Prints the Rekall version and exits.")


class Run(plugin.PrivilegedMixIn, plugin.Command):
    """A plugin which runs its argument (using eval).

    Note: This plugin is only defined and available when using the main entry
    point. It is not available when Rekall is used as a library since it allows
    arbitrary code execution.
    """

    name = "run"

    @classmethod
    def args(cls, parser):
Beispiel #7
0
# 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 <*****@*****.**>"
import logging
from multiprocessing.pool import ThreadPool
from rekall import config
from rekall import plugin

config.DeclareOption("agent_configuration",
                     group="Rekall Agent",
                     help="The Rekall Agent configuration file. When "
                     "specified Rekall switches to Agent mode.")


class Interpolator(dict):
    """A commonly used format interpolator for locations.

The below supports path temple interpolations allowing various expansions to be
    made dynamically. For example a file path template may include
    "/path{client_id}/foo" to expand the client_id into the path.
    """
    def __init__(self, session, **kwargs):
        super(Interpolator, self).__init__(**kwargs)
        self.session = session
        self._config = session.GetParameter("agent_config_obj")
Beispiel #8
0
# 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
#
""" This is Jesse Kornblum's patch to clean up the standard AS's.
"""
import struct

from rekall import addrspace
from rekall import config
from rekall import obj

config.DeclareOption(name="dtb",
                     group="Autodetection Overrides",
                     action=config.IntParser,
                     help="The DTB physical address.")


class IA32PagedMemory(addrspace.PagedReader):
    """ Standard x86 32 bit non PAE address space.

    Provides an address space for IA32 paged memory, aka the x86
    architecture, without Physical Address Extensions (PAE). Allows
    callers to map virtual address to offsets in physical memory.

    Create a new IA32 address space without PAE to sit on top of
    the base address space and a Directory Table Base (CR3 value)
    of 'dtb'.

    Comments in this class mostly come from the Intel(R) 64 and IA-32
Beispiel #9
0
The code works by wrapping a session object with progress handlers
which check for the CPU quota.

Note that when Rekall is used as a library, the caller must
deliberately wrap its own session with this module.
"""
import time

import psutil

from rekall import config
from rekall import plugin


config.DeclareOption(
    "--cpu_quota", type="IntParser", group="Quotas",
    help="Number of allocated CPU seconds Rekall is allowed to consume. "
    "If not set, unlimited CPU time can be used.")

config.DeclareOption(
    "--load_quota", type="IntParser", group="Quotas",
    help="The target maximal process load level (in percent).")


def wrap_session(session, cpu_quota=None, load_quota=None):
    """Wraps the session limiting cpu quota."""
    if load_quota is None:
        load_quota = session.GetParameter("load_quota")

    if cpu_quota is None:
        cpu_quota = session.GetParameter("cpu_quota")
Beispiel #10
0
   they support.
"""
import collections
import gc
import inspect
import logging
import time

from rekall import config
from rekall import constants
from rekall import registry
from rekall import utils

config.DeclareOption("-v",
                     "--verbose",
                     default=False,
                     type="Boolean",
                     help="Set logging to debug level.",
                     group="Output control")

config.DeclareOption("-q",
                     "--quiet",
                     default=False,
                     type="Boolean",
                     help="Turn off logging to stderr.",
                     group="Output control")

config.DeclareOption(
    "--debug",
    default=False,
    type="Boolean",
    help="If set we break into the debugger on error conditions.")
Beispiel #11
0
"""This module manages the command line parsing logic."""

__author__ = "Michael Cohen <*****@*****.**>"

import argparse
import logging
import os
import sys
import zipfile

from rekall import config
from rekall import constants
from rekall import plugin


config.DeclareOption("--plugin", default=[], nargs="+",
                     help="Load user provided plugin bundle.")

config.DeclareOption(
    "-h", "--help", default=False, action="store_true",
    help="Show help about global paramters.")


class MockArgParser(object):
    def add_argument(self, short_flag="", long_flag="", dest="", **_):
        if short_flag.startswith("--"):
            flag = short_flag
        elif long_flag.startswith("--"):
            flag = long_flag
        elif dest:
            flag = dest
        else:
Beispiel #12
0
import logging
import pdb
import sys

from rekall import args
from rekall import config
from rekall import session

# Import and register the core plugins
from rekall import plugins  # pylint: disable=unused-import

from rekall.ui import text

config.DeclareOption(
    "-r",
    "--run",
    default=None,
    help="Run this script before dropping into the interactive shell.")


def main(argv=None):
    # New user interactive session (with extra bells and whistles).
    user_session = session.InteractiveSession()
    user_session.session_list.append(user_session)
    text_renderer = text.TextRenderer(session=user_session)

    with text_renderer.start():
        plugin_cls, flags = args.parse_args(argv=argv,
                                            user_session=user_session)

        # Determine if an external script needs to be run first.
from IPython.terminal import embed
from IPython.terminal import prompts

try:
    from traitlets.config.loader import Config
except ImportError:
    from IPython.config.loader import Config

from rekall import constants
from rekall import config
from rekall import session as session_module
from rekall import utils

config.DeclareOption("--highlighting_style",
                     default="monokai",
                     type="Choices",
                     choices=list(styles.get_all_styles()),
                     help="Highlighting style for interactive console.")


def RekallCompleter(self, text):
    """Sophisticated command line completer for Rekall."""
    try:
        command_parts = self.line_buffer.split(" ")
        command = command_parts[0]

        if command.startswith("plugins."):
            command = command[len("plugins."):]

        global_matches = set(self.global_matches(command))
Beispiel #14
0
from rekall import config
from rekall import constants
from rekall import obj
from rekall import session

# Import and register the core plugins
from rekall import plugins  # pylint: disable=unused-import

try:
    from rekall import ipython_support
except ImportError:
    ipython_support = None

config.DeclareOption(
    "-r",
    "--run",
    default=None,
    help="Run this script before dropping into the interactive shell.")

config.DeclareOption(
    "-s",
    "--session_filename",
    default=None,
    help="If specified we save and restore the session from this filename.")


def IPython012Support(user_session):
    """Launch the ipython session for post 0.12 versions.

    Returns:
      False if we failed to use IPython. True if the session was run and exited.
Beispiel #15
0
__author__ = "Michael Cohen <*****@*****.**>"

import argparse
import logging
import re
import os
import sys
import zipfile

from rekall import config
from rekall import constants
from rekall import plugin
from rekall import utils


config.DeclareOption("--plugin", default=[], type="ArrayStringParser",
                     help="Load user provided plugin bundle.")

config.DeclareOption(
    "-h", "--help", default=False, type="Boolean",
    help="Show help about global paramters.")


class RekallHelpFormatter(argparse.RawDescriptionHelpFormatter):
    def add_argument(self, action):
        # Allow us to suppress an arg from the --help output for those options
        # which do not make sense on the command line.
        if action.dest != "SUPPRESS":
            super(RekallHelpFormatter, self).add_argument(action)


class RekallArgParser(argparse.ArgumentParser):
Beispiel #16
0
    # Found in every OS X image. See documentation for DarwinFindKASLR for
    # details.
    OSX_NEEDLE,

    # The Linux kernels we care about contain this.
    "Linux version ",
]


class ProfileScanner(scan.BaseScanner):
    checks = [("MultiStringFinderCheck", dict(needles=PROFILE_STRINGS))]


config.DeclareOption("--no_autodetect",
                     default=False,
                     action="store_true",
                     help="Should profiles be autodetected.")

config.DeclareOption("--autodetect_threshold",
                     default=1.0,
                     action="store",
                     help="Worst acceptable match for profile autodetection." +
                     " (Default 1.0)",
                     type=float)


class KernelASHook(kb.ParameterHook):
    """A ParameterHook for default_address_space.

    This will only be called if default_address_space is not set. We load the
    kernel address space, or load it if needed.
Beispiel #17
0
   used within the renderer they only need to cooperate with the renderer class
   they support.
"""
import collections
import gc
import inspect
import logging
import time

from rekall import config
from rekall import registry
from rekall import utils

config.DeclareOption("-v",
                     "--verbose",
                     default=False,
                     type="Boolean",
                     help="Set logging to debug level.",
                     group="Output control")

config.DeclareOption("-q",
                     "--quiet",
                     default=False,
                     type="Boolean",
                     help="Turn off logging to stderr.",
                     group="Output control")

config.DeclareOption(
    "--debug",
    default=False,
    type="Boolean",
    help="If set we break into the debugger on error conditions.")
Beispiel #18
0
from rekall import constants
from rekall import entity
from rekall import io_manager
from rekall import kb
from rekall import obj
from rekall import plugin
from rekall import utils

from rekall.ui import renderer
from rekall.ui import text

# Top level args.
config.DeclareOption("-p",
                     "--profile",
                     group="Autodetection Overrides",
                     help="Name of the profile to load. This is the "
                     "filename of the profile found in the profiles "
                     "directory. Profiles are searched in the profile "
                     "path order.")

config.DeclareOption("--profile_path",
                     default=[],
                     action="append",
                     help="Path to search for profiles. This can take "
                     "any form supported by the IO Manager (e.g. zip files, "
                     "directories, URLs etc)")

config.DeclareOption("-f", "--filename", help="The raw image to load.")

config.DeclareOption(
    "--buffer_size",
Beispiel #19
0
from builtins import str
from past.builtins import basestring
from past.utils import old_div
from builtins import object
__author__ = "Michael Cohen <*****@*****.**>"

import re

from rekall import config
from rekall import obj
from rekall_lib import utils

config.DeclareOption("--name_resolution_strategies",
                     default=["Module", "Symbol", "Export"],
                     group="Interface",
                     type="ChoiceArray",
                     choices=["Module", "Symbol", "Export"])


class Module(object):
    """A range in the virtual address space which maps an executable.

    Each binary in the address space has its own profile, which knows about
    symbols within it. This simple class is just a container to facilitate
    access to the profile that represents this module.

    Within Rekall, each module has a name. Rekall uses a simple syntax to refer
    to an address in the address space by name (see below).
    """
    def __init__(self,
Beispiel #20
0
#
# 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
#
""" These are standard address spaces supported by Rekall Memory Forensics """
import StringIO
import struct
import os
import weakref

from rekall import addrspace
from rekall import config

config.DeclareOption("-o",
                     "--file_offset",
                     type="IntParser",
                     help="A Relative offset for image file.")


class FDAddressSpace(addrspace.BaseAddressSpace):
    """An address space which operated on a file like object."""

    __name = "filelike"

    # We should be first.
    order = 0

    def __init__(self, base=None, fhandle=None, **kwargs):
        self.as_assert(base == None, "Base passed to FDAddressSpace.")
        self.as_assert(fhandle is not None, 'file handle must be provided')
Beispiel #21
0
the required performance vtop() simply looks for the PhysicalAddressDescriptor()
and returns it. This is essentially a noop for any of the other descriptors and
therefore maintains the same speed benefits.

"""
import StringIO
import struct

from rekall import addrspace
from rekall import config
from rekall import obj
from rekall.ui import text as text_renderer
from rekall_lib import utils

config.DeclareOption("dtb",
                     group="Autodetection Overrides",
                     type="IntParser",
                     help="The DTB physical address.")

PAGE_SHIFT = 12
PAGE_MASK = ~0xFFF


class AddressTranslationDescriptor(object):
    """A descriptor of a step in the translation process.

    This is a class because there may be OS specific steps in the address
    translation.
    """
    object_name = None

    def __init__(self,
Beispiel #22
0
from rekall import config
from rekall import io_manager
from rekall import kb
from rekall import obj
from rekall import plugin
from rekall import registry
from rekall import utils

from rekall.entities import manager as entity_manager
from rekall.ui import renderer
from rekall.ui import json_renderer

config.DeclareOption("--repository_path",
                     default=[],
                     type="ArrayStringParser",
                     help="Path to search for profiles. This can take "
                     "any form supported by the IO Manager (e.g. zip files, "
                     "directories, URLs etc)")

config.DeclareOption("-f", "--filename", help="The raw image to load.")

config.DeclareOption(
    "--buffer_size",
    default=20 * 1024 * 1024,
    type="IntParser",
    help="The maximum size of buffers we are allowed to read. "
    "This is used to control Rekall memory usage.")

config.DeclareOption("--output",
                     default=None,
                     help="If specified we write output to this file.")
Beispiel #23
0
this file handle compressed pages and return the decompressed data
when a compressed page is read.
"""

from rekall import addrspace
from rekall import config
from rekall.plugins.windows import pagefile
from rekall.plugins.addrspaces import xpress
from rekall.plugins.addrspaces import intel

PAGE_SIZE = 0x1000
XPRESS_ALGO = 3

config.DeclareOption("--vspagefilenumber",
                     type="int",
                     default=2,
                     group="Windows 10 Memory Compression",
                     help=('Specify the page file number corresponding'
                           ' to the Virtual Store (default is 2)'))


class WindowsCompressedMemoryDescriptor(intel.AddressTranslationDescriptor):
    """A descriptor for compressed memory pages (Windows 10)."""
    def __init__(self,
                 address=0,
                 pagefile_number=0,
                 pte_value=0,
                 session=None):
        super().__init__(session=session)
        self.address = address
        self.pagefile_number = pagefile_number
Beispiel #24
0
from rekall import config
from rekall import constants

try:
    from IPython.terminal import embed
except ImportError:
    try:
        from IPython.frontend.terminal import embed
    except ImportError:
        embed = None

from IPython.config.loader import Config


config.DeclareOption("--ipython_engine",
                     help="IPython engine, e.g. notebook.")


def RekallCompleter(self, text):
    """Sophisticated command line completer for Rekall."""
    try:
        command_parts = self.line_buffer.split(" ")
        command = command_parts[0]

        if command.startswith("plugins."):
            command = command[len("plugins."):]

        global_matches = set(self.global_matches(command))

        # Complete strings which look like symbol names.
        m = re.match("\"([^!]+![^\"]*)$", command_parts[-1])
Beispiel #25
0
from builtins import object
import pickle
import io
import os
import six
import time

from rekall import config
from rekall import io_manager
from rekall import obj
from rekall.ui import json_renderer
from rekall_lib import utils

config.DeclareOption("--cache",
                     default="file",
                     type="String",
                     choices=["file", "memory", "timed"],
                     help="Type of cache to use. ")


class RestrictedUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        # Only allow safe classes from builtins.
        if module == "builtins" and name in safe_builtins:
            return getattr(builtins, name)
        # Forbid everything else.
        raise pickle.UnpicklingError("global '%s.%s' is forbidden" %
                                     (module, name))


def RestrictedPickler(raw):
Beispiel #26
0
#
"""This address space overlays a pagefile into the physical address space.

This essentially implements the --pagefile parameter. Note that for images taken
with winpmem there is no need to specify the pagefile specifically since it is
already detected by the Elf64CoreDump class.
"""

__author__ = "Michael Cohen <*****@*****.**>"

from rekall import addrspace
from rekall import config
from rekall import session

config.DeclareOption("--pagefile",
                     type="ArrayStringParser",
                     default=[],
                     help="A pagefile to load into the image.")


class PagefilePhysicalAddressSpace(addrspace.RunBasedAddressSpace):
    __image = True
    name = "pagefile"
    order = 200

    def __init__(self, **kwargs):
        super(PagefilePhysicalAddressSpace, self).__init__(**kwargs)
        pagefile_names = self.session.GetParameter("pagefile")

        self.as_assert(pagefile_names, "Pagefile not specified")
        self.as_assert(self.base.__class__ is not self.__class__)
Beispiel #27
0
from rekall import cache
from rekall import config
from rekall import constants
from rekall import io_manager
from rekall import kb
from rekall import obj
from rekall import plugin
from rekall import registry
from rekall import utils

from rekall.ui import renderer

config.DeclareOption("--repository_path",
                     default=[],
                     type="ArrayStringParser",
                     help="Path to search for profiles. This can take "
                     "any form supported by the IO Manager (e.g. zip files, "
                     "directories, URLs etc)")

config.DeclareOption("-f", "--filename", help="The raw image to load.")

config.DeclareOption(
    "--buffer_size",
    default=20 * 1024 * 1024,
    type="IntParser",
    help="The maximum size of buffers we are allowed to read. "
    "This is used to control Rekall memory usage.")

config.DeclareOption("--output",
                     default=None,
                     help="If specified we write output to this file.")
Beispiel #28
0
# 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
#
""" This is based on Jesse Kornblum's patch to clean up the standard AS's.
"""

import struct

from rekall import config
from rekall.plugins.addrspaces import intel

config.DeclareOption(name="ept",
                     group="Virtualization support",
                     action=config.ArrayIntParser,
                     help="The EPT physical address.")


class AMD64PagedMemory(intel.IA32PagedMemoryPae):
    """Standard AMD 64-bit address space.

    Provides an address space for AMD64 paged memory, aka the x86_64
    architecture, which is laid out similarly to Physical Address
    Extensions (PAE). Allows callers to map virtual address to
    offsets in physical memory.

    Create a new AMD64 address space to sit on top of the base address
    space and a Directory Table Base (CR3 value) of 'dtb'.

    Comments in this class mostly come from the Intel(R) 64 and IA-32
We locally cache selected files from the remote profile repository. If a profile
is not found in the local cache, we retrieve it from the remote repository, and
add it to the cache.

We check the remote repository for staleness and update the local cache in the
background.
"""

__author__ = "Michael Cohen <*****@*****.**>"
import os

from rekall import config
from rekall import io_manager

config.DeclareOption("cache_dir",
                     default=None,
                     help="Location of the profile cache directory.")


class CachingManager(io_manager.IOManager):

    # We wrap this io manager class
    DELEGATE = io_manager.URLManager

    # If the cache is available we should be selected before the regular
    # manager.
    order = DELEGATE.order - 10

    def __init__(self, session=None, **kwargs):
        cache_dir = session.GetParameter("cache_dir")
Beispiel #30
0
    "1486.2.11": "10.6.2",
    "1456.1.26": "10.6.1",

    # The signature of an RSDS record.
    "RSDS": "PDB",

    "Linux version ": "Linux",
    }



class ProfileScanner(scan.BaseScanner):
    checks = [("MultiStringFinderCheck", dict(needles=PROFILE_STRINGS))]


config.DeclareOption("--no_autodetect", default=False, action="store_true",
                     help="Should profiles be autodetected.")


class KernelASHook(kb.ParameterHook):
    """A ParameterHook for default_address_space.

    This will only be called if default_address_space is not set. We load the
    kernel address space, or load it if needed.
    """
    name = "default_address_space"

    def calculate(self):
        if not self.session.profile:
            self.session.GetParameter("profile")

        if self.session.kernel_address_space: