def StartAnalysisVm(args: 'argparse.Namespace') -> None:
  """Start forensic analysis VM.

  Args:
    args (argparse.Namespace): Arguments from ArgumentParser.
  """
  if args.attach_volumes and len(args.attach_volumes.split(',')) > 11:
    logger.error('--attach_volumes must be < 11')
    return

  attach_volumes = []
  if args.attach_volumes:
    volumes = args.attach_volumes.split(',')
    # Check if volumes parameter exists and if there
    # are any empty entries.
    if not (volumes and all(elements for elements in volumes)):
      logger.error('parameter --attach_volumes: {0:s}'.format(
          args.attach_volumes))
      return

    # AWS recommends using device names that are within /dev/sd[f-p].
    device_letter = ord('f')
    for volume in volumes:
      attach = (volume, '/dev/sd'+chr(device_letter))
      attach_volumes.append(attach)
      device_letter = device_letter + 1

  key_name = args.ssh_key_name
  if args.generate_ssh_key_pair:
    logger.info('Generating SSH key pair for the analysis VM.')
    aws_account = account.AWSAccount(args.zone)
    key_name, private_key = aws_account.ec2.GenerateSSHKeyPair(
        args.instance_name)
    path = os.path.join(os.getcwd(), key_name + '.pem')
    with open(path, 'w') as f:
      f.write(private_key)
    logger.info(
        'Created key pair {0:s} in AWS. Your private key is saved in: '
        '{1:s}'.format(key_name, path))

  logger.info('Starting analysis VM...')
  vm = forensics.StartAnalysisVm(vm_name=args.instance_name,
                                 default_availability_zone=args.zone,
                                 boot_volume_size=int(args.boot_volume_size),
                                 boot_volume_type=args.boot_volume_type,
                                 cpu_cores=int(args.cpu_cores),
                                 ami=args.ami,
                                 ssh_key_name=key_name,
                                 attach_volumes=attach_volumes,
                                 dst_profile=args.dst_profile)

  logger.info('Analysis VM started.')
  logger.info('Name: {0:s}, Started: {1:s}, Region: {2:s}'.format(vm[0].name,
                                                                  str(vm[1]),
                                                                  vm[0].region))
示例#2
0
 def setUpClass(cls):
   try:
     project_info = utils.ReadProjectInfo(['instance', 'zone'])
   except (OSError, RuntimeError, ValueError) as exception:
     raise unittest.SkipTest(str(exception))
   cls.instance_to_analyse = project_info['instance']
   cls.zone = project_info['zone']
   cls.dst_zone = project_info.get('destination_zone', None)
   cls.volume_to_copy = project_info.get('volume_id', None)
   cls.encrypted_volume_to_copy = project_info.get('encrypted_volume_id', None)
   cls.aws = account.AWSAccount(cls.zone)
   cls.analysis_vm_name = 'new-vm-for-analysis'
   cls.analysis_vm, _ = forensics.StartAnalysisVm(cls.analysis_vm_name,
                                                  cls.zone,
                                                  10)
   cls.volumes = []  # List of (AWSAccount, AWSVolume) tuples
示例#3
0
def StartAnalysisVm(args: 'argparse.Namespace') -> None:
  """Start forensic analysis VM.

  Args:
    args (argparse.Namespace): Arguments from ArgumentParser.
  """
  if args.attach_volumes and len(args.attach_volumes.split(',')) > 11:
    print('error: --attach_volumes must be < 11')
    return

  attach_volumes = []
  if args.attach_volumes:
    volumes = args.attach_volumes.split(',')
    # Check if volumes parameter exists and if there
    # are any empty entries.
    if not (volumes and all(elements for elements in volumes)):
      print('error: parameter --attach_volumes: {0:s}'.format(args.attach_volumes))
      return

    # AWS recommends using device names that are within /dev/sd[f-p].
    device_letter = ord('f')
    for volume in volumes:
      attach = (volume, '/dev/sd'+chr(device_letter))
      attach_volumes.append(attach)
      device_letter = device_letter + 1

  print('Starting analysis VM...')
  vm = forensics.StartAnalysisVm(vm_name=args.instance_name,
                                 default_availability_zone=args.zone,
                                 boot_volume_size=int(args.boot_volume_size),
                                 cpu_cores=int(args.cpu_cores),
                                 ami=args.ami,
                                 ssh_key_name=args.ssh_key_name,
                                 attach_volumes=attach_volumes,
                                 dst_profile=args.dst_profile)

  print('Analysis VM started.')
  print('Name: {0:s}, Started: {1:s}, Region: {2:s}'.format(vm[0].name,
                                                            str(vm[1]),
                                                            vm[0].region))
示例#4
0
    def testStartVm(self):
        """End to end test on AWS.

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

        volume_copy = forensics.CreateVolumeCopy(self.zone,
                                                 volume_id=self.volume_to_copy)
        self.volumes.append((self.aws, volume_copy))
        # Create and start the analysis VM and attach the boot volume
        self.analysis_vm, _ = forensics.StartAnalysisVm(
            self.analysis_vm_name,
            self.zone,
            10,
            attach_volumes=[(volume_copy.volume_id, '/dev/sdp')])

        # The forensic instance should be live in the analysis AWS account and
        # the volume should be attached
        instance = self.aws.ResourceApi(EC2_SERVICE).Instance(
            self.analysis_vm.instance_id)
        self.assertEqual(instance.instance_id, self.analysis_vm.instance_id)
        self.assertIn(volume_copy.volume_id,
                      [vol.volume_id for vol in instance.volumes.all()])
示例#5
0
  def SetUp(self,
            remote_profile_name,
            remote_zone,
            incident_id,
            remote_instance_id=None,
            volume_ids=None,
            all_volumes=False,
            analysis_profile_name=None,
            analysis_zone=None,
            boot_volume_size=50,
            cpu_cores=16,
            ami=None):
    """Sets up an Amazon web Services (AWS) collector.

    This method creates and starts an analysis VM in the AWS account and
    selects volumes to copy from the target instance / list of volumes passed
    in parameter.

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

    If remote_instance_id is specified, two behaviors are possible:
    * If no other parameters are specified, it will select the instance's boot
      volume.
    * if all_volumes is set to True, it will select all volumes in the account
      that are attached to the instance.

    volume_ids takes precedence over remote_instance_id.

    Args:
      remote_profile_name (str): The AWS account in which the
          volume(s) exist(s). This is the profile name that is defined in
          your AWS credentials file.
      remote_zone (str): The AWS zone in which the source volume(s) exist(s).
      incident_id (str): Incident identifier used to name the analysis VM.
      remote_instance_id (str): Optional. Instance ID that needs forensicating.
      volume_ids (str): Optional. Comma-separated list of volume ids to
          copy.
      all_volumes (bool): Optional. True if all volumes attached to the source
          instance should be copied.
      analysis_profile_name (str): Optional. The AWS account in which to
          create the analysis VM. This is the profile name that is defined in
          your AWS credentials file.
      analysis_zone (str): Optional. The AWS zone in which to create the VM.
          If not specified, the VM will be created in the same zone where the
          volume(s) exist(s).
      boot_volume_size (int): Optional. The size (in GB) of the boot volume
          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 16.
      ami (str): Optional. The Amazon Machine Image ID to use to create the
          analysis VM. If not specified, will default to selecting Ubuntu 18.04
          TLS.
    """

    if not (remote_instance_id or volume_ids):
      self.ModuleError(
          'You need to specify at least an instance name or volume ids to copy',
          critical=True)
      return

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

    self.remote_profile_name = remote_profile_name
    self.remote_zone = remote_zone
    self.source_account = aws_account.AWSAccount(
        self.remote_zone, aws_profile=self.remote_profile_name)

    self.incident_id = incident_id
    self.remote_instance_id = remote_instance_id

    self.volume_ids = volume_ids.split(',') if volume_ids else []
    self.all_volumes = all_volumes
    self.analysis_zone = analysis_zone or remote_zone
    self.analysis_profile_name = analysis_profile_name or remote_profile_name

    analysis_vm_name = 'aws-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, _ = aws_forensics.StartAnalysisVm(
        analysis_vm_name,
        self.analysis_zone,
        boot_volume_size,
        ami=ami,
        cpu_cores=cpu_cores,
        dst_profile=self.analysis_profile_name,
    )