Ejemplo n.º 1
0
    def test_mount(self):
        volumes = []
        self.filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), self.filename)
        parser = ImageParser([self.filename], None, False)
        for v in parser.init():
            volumes.append(v)

        parser.clean()

        self.validate_count(volumes)
        self.validate_types(volumes)
Ejemplo n.º 2
0
    def test_mount(self):
        volumes = []
        self.filename = os.path.join(
            os.path.dirname(os.path.realpath(__file__)), self.filename)
        parser = ImageParser([self.filename], None, False)
        for v in parser.init():
            volumes.append(v)

        parser.clean()

        self.validate_count(volumes)
        self.validate_types(volumes)
Ejemplo n.º 3
0
    def _mount_dd_img(self):
        """
        Mounts a dd image and all of its volumes and returns a list of directory paths to each volume, as well as the
        mount path for the disk image itself.

        :return: path_to_mountpoint, list of paths to mounted volumes
        """
        parser = ImageParser([self.img_path],
                             pretty=True,
                             mountdir=self.mount_parent,
                             casename=self.mount_stub,
                             disk_mounter="xmount")
        volume_mount_paths = []

        for volume in parser.init(single=True, swallow_exceptions=True):

            # parser.init() loops over all volumes and mounts them
            if volume.mountpoint:
                # If the mountpoint is set, we have successfully mounted it
                logger.info(
                    f"Mounted volume {volume.get_description()} on {volume.mountpoint}"
                )
                volume_mount_paths.append((volume.mountpoint))

            elif volume.exception and volume.size is not None and volume.size <= 1048576:
                # If an exception occurred, but the volume is small, this is just a warning
                logger.info(
                    f"Exception while mounting small volume {volume.get_description()}"
                )

            elif volume.exception:
                # Other exceptions are a bit troubling. Should never happen, actually.
                logger.debug(
                    f"Exception while mounting {volume.get_description()}")

        return parser.disks[0].mountpoint, volume_mount_paths
Ejemplo n.º 4
0
def main():
    # We use argparse to parse arguments from the command line.
    parser = argparse.ArgumentParser(description='Simple CLI to mount disk images.')
    parser.add_argument('--version', action='version', version=__version__, help='display version and exit')
    parser.add_argument("-i", "--in", action='append', required=True, metavar='IN',
                        help="path(s) to the files you want to mount", dest='images')
    parser.add_argument("-o", "--out", help="directory to mount the volumes in", dest="mountdir")
    parser.add_argument("-c", "--casename", help="the name of the case (this is appended to the output dir)")
    parser.add_argument("-r", "--restore", action="store_true", help="carve unallocated space", dest="carve")
    parser.add_argument("-s", "--shadow", action="store_true", help="mount volume shadow copies", dest="vshadow")
    parser.add_argument("-v", "--verbose", action="store_true", help="enable verbose output")
    args = parser.parse_args()

    # This sets up the logger. This is somewhat huge part of this example
    class ImageMounterFormatter(logging.Formatter):
        def format(self, record):
            msg = record.getMessage()
            if args.verbose and record.exc_info:
                if not record.exc_text:
                    record.exc_text = self.formatException(record.exc_info)
                if msg[-1:] != "\n":
                    msg += "\n"
                msg += record.exc_text
            if record.levelno >= logging.WARNING:
                return colored("[-] " + msg, 'cyan')
            elif record.levelno == logging.INFO:
                return colored("[+] " + msg, 'cyan')
            elif msg.startswith('$'):
                return colored("  " + msg, 'cyan')
            else:
                return colored("    " + msg, 'cyan')

    # Set logging level for internal Python
    handler = logging.StreamHandler()
    handler.setFormatter(ImageMounterFormatter())
    logger = logging.getLogger("imagemounter")
    logger.setLevel(logging.WARNING if not args.verbose else logging.DEBUG)
    logger.addHandler(handler)

    # This is the basic parser.
    parser = ImageParser(args.images, pretty=True, **vars(args))
    for volume in parser.init():
        # parser.init() loops over all volumes and mounts them
        if volume.mountpoint:
            # If the mountpoint is set, we have successfully mounted it
            print('[+] Mounted volume {0} on {1}.'.format(colored(volume.get_description(), attrs=['bold']),
                                                          colored(volume.mountpoint, 'green', attrs=['bold'])))

        elif volume.loopback:
            # If the mountpoint is not set, but a loopback is used, this is probably something like an LVM that did
            # not work properly.
            print('[+] Mounted volume {0} as loopback on {1}.'.format(colored(volume.get_description(), attrs=['bold']),
                                                                      colored(volume.loopback, 'green', attrs=['bold'])))
            print(colored('[-] Could not detect further volumes in the loopback device.', 'red'))

        elif volume.exception and volume.size is not None and volume.size <= 1048576:
            # If an exception occurred, but the volume is small, this is just a warning
            print(colored('[-] Exception while mounting small volume {0}'.format(volume.get_description()), 'yellow'))

        elif volume.exception:
            # Other exceptions are a bit troubling. Should never happen, actually.
            print(colored('[-] Exception while mounting {0}'.format(volume.get_description()), 'red'))

        elif volume.flag != 'meta' or args.verbose:
            # Meta volumes are not interesting enough to always show a warning about
            # Other volumes, we just print a warning that we couldn't mount it.
            print(colored('[-] Could not mount volume {0}'.format(volume.get_description()), 'yellow'))

        if args.carve and volume.flag != 'meta':
            # Carving is not neccesary on meta volumes, other volumes are carved for their unallocated space
            # or their entire space, depending on whether we could mount it.
            sys.stdout.write("[+] Carving volume...\r")
            sys.stdout.flush()
            try:
                path = volume.carve(freespace=not volume.mountpoint)
            except ImageMounterError:
                print(colored('[-] Carving failed.', 'red'))
            else:
                print('[+] Carved data is available at {0}.'.format(colored(path, 'green', attrs=['bold'])))

        if args.vshadow and volume.fstype == 'ntfs':
            sys.stdout.write("[+] Mounting volume shadow copies...\r")
            sys.stdout.flush()
            try:
                volumes = volume.detect_volume_shadow_copies()
            except ImageMounterError:
                print(colored('[-] Volume shadow copies could not be mounted.', 'red'))
            else:
                for v in volumes:
                    try:
                        v.init_volume()
                    except ImageMounterError:
                        print(colored('[-] Volume shadow copy {} not mounted'.format(v), 'red'))
                    else:
                        print('[+] Volume shadow copy available at {0}.'.format(colored(v.mountpoint, 'green', attrs=['bold'])))
        else:
            continue  # we do not need the unmounting sequence
Ejemplo n.º 5
0
def main():
    # We use argparse to parse arguments from the command line.
    parser = argparse.ArgumentParser(
        description='Simple CLI to mount disk images.')
    parser.add_argument('--version',
                        action='version',
                        version=__version__,
                        help='display version and exit')
    parser.add_argument("-i",
                        "--in",
                        action='append',
                        required=True,
                        metavar='IN',
                        help="path(s) to the files you want to mount",
                        dest='images')
    parser.add_argument("-o",
                        "--out",
                        help="directory to mount the volumes in",
                        dest="mountdir")
    parser.add_argument(
        "-c",
        "--casename",
        help="the name of the case (this is appended to the output dir)")
    parser.add_argument("-r",
                        "--restore",
                        action="store_true",
                        help="carve unallocated space",
                        dest="carve")
    parser.add_argument("-s",
                        "--shadow",
                        action="store_true",
                        help="mount volume shadow copies",
                        dest="vshadow")
    parser.add_argument("-v",
                        "--verbose",
                        action="store_true",
                        help="enable verbose output")
    args = parser.parse_args()

    # This sets up the logger. This is somewhat huge part of this example
    class ImageMounterFormatter(logging.Formatter):
        def format(self, record):
            msg = record.getMessage()
            if args.verbose and record.exc_info:
                if not record.exc_text:
                    record.exc_text = self.formatException(record.exc_info)
                if msg[-1:] != "\n":
                    msg += "\n"
                msg += record.exc_text
            if record.levelno >= logging.WARNING:
                return colored("[-] " + msg, 'cyan')
            elif record.levelno == logging.INFO:
                return colored("[+] " + msg, 'cyan')
            elif msg.startswith('$'):
                return colored("  " + msg, 'cyan')
            else:
                return colored("    " + msg, 'cyan')

    # Set logging level for internal Python
    handler = logging.StreamHandler()
    handler.setFormatter(ImageMounterFormatter())
    logger = logging.getLogger("imagemounter")
    logger.setLevel(logging.WARNING if not args.verbose else logging.DEBUG)
    logger.addHandler(handler)

    # This is the basic parser.
    parser = ImageParser(args.images, pretty=True, **vars(args))
    for volume in parser.init():
        # parser.init() loops over all volumes and mounts them
        if volume.mountpoint:
            # If the mountpoint is set, we have successfully mounted it
            print('[+] Mounted volume {0} on {1}.'.format(
                colored(volume.get_description(), attrs=['bold']),
                colored(volume.mountpoint, 'green', attrs=['bold'])))

        elif volume.loopback:
            # If the mountpoint is not set, but a loopback is used, this is probably something like an LVM that did
            # not work properly.
            print('[+] Mounted volume {0} as loopback on {1}.'.format(
                colored(volume.get_description(), attrs=['bold']),
                colored(volume.loopback, 'green', attrs=['bold'])))
            print(
                colored(
                    '[-] Could not detect further volumes in the loopback device.',
                    'red'))

        elif volume.exception and volume.size is not None and volume.size <= 1048576:
            # If an exception occurred, but the volume is small, this is just a warning
            print(
                colored(
                    '[-] Exception while mounting small volume {0}'.format(
                        volume.get_description()), 'yellow'))

        elif volume.exception:
            # Other exceptions are a bit troubling. Should never happen, actually.
            print(
                colored(
                    '[-] Exception while mounting {0}'.format(
                        volume.get_description()), 'red'))

        elif volume.flag != 'meta' or args.verbose:
            # Meta volumes are not interesting enough to always show a warning about
            # Other volumes, we just print a warning that we couldn't mount it.
            print(
                colored(
                    '[-] Could not mount volume {0}'.format(
                        volume.get_description()), 'yellow'))

        if args.carve and volume.flag != 'meta':
            # Carving is not neccesary on meta volumes, other volumes are carved for their unallocated space
            # or their entire space, depending on whether we could mount it.
            sys.stdout.write("[+] Carving volume...\r")
            sys.stdout.flush()
            try:
                path = volume.carve(freespace=not volume.mountpoint)
            except ImageMounterError:
                print(colored('[-] Carving failed.', 'red'))
            else:
                print('[+] Carved data is available at {0}.'.format(
                    colored(path, 'green', attrs=['bold'])))

        if args.vshadow and volume.fstype == 'ntfs':
            sys.stdout.write("[+] Mounting volume shadow copies...\r")
            sys.stdout.flush()
            try:
                volumes = volume.detect_volume_shadow_copies()
            except ImageMounterError:
                print(
                    colored('[-] Volume shadow copies could not be mounted.',
                            'red'))
            else:
                for v in volumes:
                    try:
                        v.init_volume()
                    except ImageMounterError:
                        print(
                            colored(
                                '[-] Volume shadow copy {} not mounted'.format(
                                    v), 'red'))
                    else:
                        print(
                            '[+] Volume shadow copy available at {0}.'.format(
                                colored(v.mountpoint, 'green',
                                        attrs=['bold'])))
        else:
            continue  # we do not need the unmounting sequence