def create_extractor_instance(investigation_id: str): ec2 = client("ec2") instance_service = InstanceService(investigation_id) instance = instance_service.get_instance(investigation_id) instance_service.logger("Creating extractor instance") extractor = ec2.run_instances( ImageId=environ["EXTRACTOR_AMI_ID"], InstanceType="c5.large", MinCount=1, MaxCount=1, InstanceInitiatedShutdownBehavior="terminate", NetworkInterfaces=[{ "AssociatePublicIpAddress": True, "DeleteOnTermination": True, "DeviceIndex": 0, "SubnetId": instance["NetworkInterfaces"][0]["SubnetId"], "Groups": [environ["SECURITY_GROUP"]], }], BlockDeviceMappings=[{ "DeviceName": "/dev/sda1", "Ebs": { "VolumeSize": 8 + round(instance_service.get_memory_size(instance) / 1000) } }, { "DeviceName": "/dev/sdm", "Ebs": { "VolumeSize": round((instance_service.get_memory_size(instance) / 1000) + 1) } }], TagSpecifications=[{ "ResourceType": "instance", "Tags": [{ "Key": "Name", "Value": "CLAIRE Evidence Extractor" }, { "Key": "CLAIRE", "Value": "Worker", }, { "Key": "InvestigationId", "Value": investigation_id, }] }], IamInstanceProfile={ "Arn": environ["IAM_PROFILE"], })["Instances"][0] instance_service.logger("extractor instance created") return extractor
class SnapshotCreationService: ec2 = client("ec2") instance_service: InstanceService logger: callable def __init__(self, investigation_id: str): self.instance_service = InstanceService(investigation_id) self.logger = self.instance_service.logger def snapshot_volumes(self, investigation_id: str): instance = self.instance_service.get_instance(investigation_id) return list( map( lambda v: self.__snapshot(v["Ebs"]["VolumeId"], investigation_id), instance["BlockDeviceMappings"], )) def is_snapshot_complete(self, snapshot_ids: str): self.logger("Getting snapshot status for {}".format(snapshot_ids)) return reduce( lambda is_ready, s: is_ready if s["State"] == "completed" else False, self.ec2.describe_snapshots(SnapshotIds=snapshot_ids)["Snapshots"], True, ) def __snapshot(self, volume_id: str, investigation_id: str): tags = [{ "Key": CLAIRE, "Value": "Investigating", }, { "Key": "InvestigationId", "Value": investigation_id, }] self.logger("Tagging volume {}".format(volume_id)) self.ec2.create_tags(Resources=[volume_id], Tags=tags) self.logger("Tags created for volume {}".format(volume_id)) self.logger("Creating snapshot for volume {}".format(volume_id)) resp = self.ec2.create_snapshot( Description="Created by CLAIRE for investigation {}".format( investigation_id), VolumeId=volume_id, TagSpecifications=[{ "ResourceType": "snapshot", "Tags": tags, }], DryRun=False) self.logger("Snapshot of volume {} complete {}".format( volume_id, resp)) return resp["SnapshotId"]
def capture_volumes(volumes: list, investigation_id: str, bucket: str) -> dict: ins = InstanceService(investigation_id) instance_id = ins.get_extractor_instance(investigation_id)["InstanceId"] ssm = client("ssm") ins.logger("Sending volume capture commands to {}".format(instance_id)) resp = ssm.send_command( DocumentName="AWS-RunShellScript", InstanceIds=[instance_id], Comment="Acquiring volumes for investigation {}".format( investigation_id), TimeoutSeconds=3600, Parameters={ "commands": get_capture_commands(investigation_id, volumes) }, OutputS3BucketName=bucket, OutputS3KeyPrefix="{}/cmd/capture-volumes".format(investigation_id), ) return { "running_command_instance": instance_id, "running_command_id": resp["Command"]["CommandId"], }
def lambda_create_volumes(event: object, _): investigation_id = event["investigation_id"] mvs = ManageVolumesService(investigation_id) extractor = InstanceService(investigation_id).get_extractor_instance( investigation_id) event["volumes"] = mvs.create_volumes( event["snapshot_ids"], extractor["Placement"]["AvailabilityZone"]) event["data"] = { "investigation_id": event["investigation_id"], "volumes": event["volumes"], "instance_from": None, "instance_to": extractor["InstanceId"] } event["is_ready"] = False return event
def isolate(investigation_id: str, security_group): logger = get_logger(investigation_id) instance = InstanceService(investigation_id).get_instance(investigation_id) logger("Saving security group(s) to tag:claire_removed_groups") ec2.create_tags(Resources=[instance["InstanceId"]], Tags=[{ "Key": "claire_removed_groups", "Value": ",".join(g["GroupId"] for g in instance["SecurityGroups"]) }]) logger("Changing security group to {}".format(security_group)) ec2.modify_instance_attribute( InstanceId=instance["InstanceId"], Groups=[security_group], ) logger("Security group updated successfully")
def create_manual_extractor(investigation_id: str, key_name: str): ec2 = client("ec2") return ec2.run_instances( ImageId=environ["EXTRACTOR_AMI_ID"], InstanceType="c5.large", MinCount=1, MaxCount=1, KeyName=key_name, InstanceInitiatedShutdownBehavior="terminate", NetworkInterfaces=[{ "AssociatePublicIpAddress": True, "DeleteOnTermination": True, "DeviceIndex": 0, "SubnetId": InstanceService(investigation_id).get_instance(investigation_id) ["NetworkInterfaces"][0]["SubnetId"], "Groups": [environ["SECURITY_GROUP"]], }], TagSpecifications=[{ "ResourceType": "instance", "Tags": [{ "Key": "Name", "Value": "CLAIRE Manual Evidence Extractor" }, { "Key": "CLAIRE", "Value": "Worker", }, { "Key": "InvestigationId", "Value": investigation_id, }] }], IamInstanceProfile={ "Arn": environ["IAM_PROFILE"], }, )["Instances"][0]
def __init__(self, investigation_id: str): self.instance_service = InstanceService(investigation_id) self.logger = self.instance_service.logger