def testStartVm(self):
    """End to end test on Azure.

    Test creating an analysis VM and attaching a copied disk to it.
    """

    disk_copy = forensics.CreateDiskCopy(
        self.resource_group_name,
        disk_name=self.disk_to_copy)
    self._StoreDiskForCleanup(disk_copy)

    # Create and start the analysis VM and attach the disk
    self.analysis_vm, _ = forensics.StartAnalysisVm(
        self.resource_group_name,
        self.analysis_vm_name,
        50,
        self.ssh_public_key,
        attach_disks=[disk_copy.name]
    )

    # The forensic instance should be live in the analysis Azure account and
    # the disk should be attached
    instance = self.az.compute.compute_client.virtual_machines.get(
        self.resource_group_name, self.analysis_vm.name)
    self.assertEqual(instance.name, self.analysis_vm.name)
    self.assertIn(disk_copy.name, self.analysis_vm.ListDisks())
    self._StoreDiskForCleanup(self.analysis_vm.GetBootDisk())
Example #2
0
 def setUpClass(cls):
     try:
         project_info = utils.ReadProjectInfo(
             ['resource_group_name', 'instance_name', 'ssh_public_key'])
     except (OSError, RuntimeError, ValueError) as exception:
         raise unittest.SkipTest(str(exception))
     cls.resource_group_name = project_info['resource_group_name']
     cls.instance_to_analyse = project_info['instance_name']
     cls.ssh_public_key = project_info['ssh_public_key']
     cls.disk_to_copy = project_info.get('disk_name')
     cls.dst_region = project_info.get('dst_region')
     cls.az = account.AZAccount(cls.resource_group_name)
     cls.analysis_vm_name = 'new-vm-for-analysis'
     cls.analysis_vm, _ = forensics.StartAnalysisVm(cls.resource_group_name,
                                                    cls.analysis_vm_name,
                                                    50, cls.ssh_public_key)
     cls.disks = []  # List of AZDisks for test cleanup
Example #3
0
def StartAnalysisVm(args: 'argparse.Namespace') -> None:
  """Start forensic analysis VM.

  Args:
    args (argparse.Namespace): Arguments from ArgumentParser.
  """
  attach_disks = []
  if args.attach_disks:
    attach_disks = args.attach_disks.split(',')
    # Check if attach_disks parameter exists and if there
    # are any empty entries.
    if not (attach_disks and all(elements for elements in attach_disks)):
      logger.error('error: parameter --attach_disks: {0:s}'.format(
          args.attach_disks))
      return

  ssh_public_key = args.ssh_public_key
  if not ssh_public_key:
    # According to https://docs.microsoft.com/cs-cz/samples/azure-samples/
    # resource-manager-python-template-deployment/resource-manager-python-
    # template-deployment/ there's no API to generate a new SSH key pair in
    # Azure, so we do this manually...
    ssh_public_key = _GenerateSSHKeyPair(args.instance_name)

  logger.info('Starting analysis VM...')
  vm = forensics.StartAnalysisVm(args.default_resource_group_name,
                                 args.instance_name,
                                 int(args.disk_size),
                                 ssh_public_key,
                                 cpu_cores=int(args.cpu_cores),
                                 memory_in_mb=int(args.memory_in_mb),
                                 region=args.region,
                                 attach_disks=attach_disks,
                                 dst_profile=args.dst_profile)

  logger.info('Analysis VM started.')
  logger.info('Name: {0:s}, Started: {1:s}'.format(vm[0].name, str(vm[1])))
Example #4
0
    def SetUp(self,
              remote_profile_name,
              analysis_resource_group_name,
              incident_id,
              ssh_public_key,
              remote_instance_name=None,
              disk_names=None,
              all_disks=False,
              analysis_profile_name=None,
              analysis_region=None,
              boot_disk_size=50,
              cpu_cores=4,
              memory_in_mb=8192):
        """Sets up a Microsoft Azure collector.

    This method creates and starts an analysis VM in the analysis account and
    selects disks to copy from the remote account.

    If disk_names is specified, it will copy the corresponding disks from the
    account, ignoring disks belonging to any specific instances.

    If remote_instance_name is specified, two behaviors are possible:
    * If no other parameters are specified, it will select the instance's boot
      disk
    * if all_disks is set to True, it will select all disks in the account
      that are attached to the instance

    disk_names takes precedence over instance_names

    Args:
      remote_profile_name (str): The Azure account in which the disk(s)
          exist(s). This is the profile name that is defined in your credentials
          file.
      analysis_resource_group_name (str): The Azure resource group name in
          which to create the VM.
      incident_id (str): Incident identifier used to name the analysis VM.
      ssh_public_key (str): The public SSH key to attach to the instance.
      remote_instance_name (str): Instance ID that needs forensicating.
      disk_names (str): Comma-separated list of disk names to copy.
      all_disks (bool): True if all disk attached to the source
          instance should be copied.
      analysis_profile_name (str): The Azure account in which to create the
          analysis VM. This is the profile name that is defined in your
          credentials file.
      analysis_region (str): The Azure region in which to create the VM.
      boot_disk_size (int): Optional. The size (in GB) of the boot disk
          for the analysis VM. Default is 50 GB.
      cpu_cores (int): Optional. The number of CPU cores to use for the
          analysis VM. Default is 4.
      memory_in_mb (int): Optional. The amount of memory in mb to use for the
          analysis VM. Default is 8Gb.
    """
        if not (remote_instance_name or disk_names):
            self.ModuleError(
                'You need to specify at least an instance name or disks to copy',
                critical=True)
            return

        if not ssh_public_key:
            self.ModuleError(
                'You need to specify a SSH public key to add to the '
                'VM.',
                critical=True)
            return

        if not (remote_profile_name and analysis_resource_group_name):
            self.ModuleError(
                'You must specify "remote_profile_name" and '
                '"analysis_resource_group_name" parameters',
                critical=True)
            return

        self.remote_profile_name = remote_profile_name
        self.analysis_resource_group_name = analysis_resource_group_name
        self.analysis_profile_name = analysis_profile_name
        self.source_account = account.AZAccount(
            self.analysis_resource_group_name,
            profile_name=self.remote_profile_name)

        self.incident_id = incident_id
        self.remote_instance_name = remote_instance_name

        self.disk_names = disk_names.split(',') if disk_names else []
        self.all_disks = all_disks
        self.analysis_region = analysis_region
        self.analysis_profile_name = analysis_profile_name or remote_profile_name

        analysis_vm_name = 'azure-forensics-vm-{0:s}'.format(self.incident_id)
        print('Your analysis VM will be: {0:s}'.format(analysis_vm_name))
        self.state.StoreContainer(
            containers.TicketAttribute(
                name=self._ANALYSIS_VM_CONTAINER_ATTRIBUTE_NAME,
                type_=self._ANALYSIS_VM_CONTAINER_ATTRIBUTE_TYPE,
                value=analysis_vm_name))
        self.analysis_vm, _ = az_forensics.StartAnalysisVm(
            self.analysis_resource_group_name,
            analysis_vm_name,
            boot_disk_size,
            ssh_public_key=ssh_public_key,
            cpu_cores=cpu_cores,
            memory_in_mb=memory_in_mb,
            region=self.analysis_region,
            dst_profile=self.analysis_profile_name,
        )