{ "schemaVersion": "0.3", "description": "Isolate EC2 instance and collect forensic data on GuardDuty malware finding", "assumeRole": "{{ AutomationAssumeRole }}", "parameters": { "InstanceId": { "type": "String", "description": "EC2 Instance ID from GuardDuty finding" }, "IsolationSecurityGroupId": { "type": "String", "description": "Security Group ID with no inbound/outbound rules" }, "S3BucketName": { "type": "String", "default": "guardduty-malware-demo" }, "AutomationAssumeRole": { "type": "String", "description": "IAM role for automation execution" }, "AwsRegion": { "type": "String", "default": "ap-south-1", "description": "AWS region for S3 upload (e.g. ap-south-1)" } }, "mainSteps": [ { "name": "GetInstanceDetails", "action": "aws:executeAwsApi", "inputs": { "Service": "ec2", "Api": "DescribeInstances", "InstanceIds": [ "{{ InstanceId }}" ] }, "outputs": [ { "Name": "volumeId", "Selector": "$.Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId", "Type": "String" } ] }, { "name": "CollectForensicData", "action": "aws:runCommand", "inputs": { "DocumentName": "AWS-RunShellScript", "InstanceIds": [ "{{ InstanceId }}" ], "Parameters": { "commands": [ "#!/bin/bash\nset -e\n\nS3_BUCKET=\"{{ S3BucketName }}\"\nINSTANCE_ID=\"{{ InstanceId }}\"\nTIMESTAMP=$(date +%Y%m%d-%H%M%S)\nWORK_DIR=\"/var/tmp/forensics-${TIMESTAMP}\"\nmkdir -p \"$WORK_DIR\"\n\necho \"Starting forensic collection for ${INSTANCE_ID}...\"\n\n# Collect process information\nps auxww > \"${WORK_DIR}/processes.txt\"\nps -eo pid,ppid,cmd,stat,start > \"${WORK_DIR}/process-tree.txt\"\n\n# Collect network connections\nnetstat -antp > \"${WORK_DIR}/network-connections.txt\" 2>/dev/null || ss -antp > \"${WORK_DIR}/network-connections.txt\"\n\n# Collect process details from /proc\nfor pid in /proc/[0-9]*; do\n if [ -d \"$pid\" ]; then\n pid_num=$(basename \"$pid\")\n mkdir -p \"${WORK_DIR}/proc/${pid_num}\"\n cp \"$pid/cmdline\" \"${WORK_DIR}/proc/${pid_num}/\" 2>/dev/null || true\n cp \"$pid/environ\" \"${WORK_DIR}/proc/${pid_num}/\" 2>/dev/null || true\n ls -l \"$pid/fd\" > \"${WORK_DIR}/proc/${pid_num}/fd.txt\" 2>/dev/null || true\n cat \"$pid/status\" > \"${WORK_DIR}/proc/${pid_num}/status.txt\" 2>/dev/null || true\n fi\ndone\n\n# Memory dump with AVML (pre-installed)\necho \"Collecting memory dump with AVML...\"\navml \"${WORK_DIR}/memory.lime\" --compress || echo \"WARNING: Memory dump failed\"\n\n# System information\nuname -a > \"${WORK_DIR}/system-info.txt\"\ndf -h > \"${WORK_DIR}/disk-usage.txt\"\nmount > \"${WORK_DIR}/mounts.txt\"\ncat /etc/os-release > \"${WORK_DIR}/os-release.txt\"\n\n# Active user sessions\nwho > \"${WORK_DIR}/active-users.txt\"\nlast -20 > \"${WORK_DIR}/recent-logins.txt\"\n\n# Cron jobs\ncrontab -l > \"${WORK_DIR}/crontab.txt\" 2>/dev/null || echo \"No crontab\" > \"${WORK_DIR}/crontab.txt\"\nls -la /etc/cron.* > \"${WORK_DIR}/cron-jobs.txt\" 2>/dev/null || true\n\n# Package data\ncd /var/tmp\ntar -czf \"forensics-${INSTANCE_ID}-${TIMESTAMP}.tar.gz\" \"forensics-${TIMESTAMP}/\"\n\n# Upload to S3\necho \"Uploading to S3...\"\nREGION=\"{{ AwsRegion }}\"\naws s3 cp \"/var/tmp/forensics-${INSTANCE_ID}-${TIMESTAMP}.tar.gz\" \"s3://${S3_BUCKET}/guardduty-ec2-malware/${INSTANCE_ID}/\" \\\n --region \"$REGION\" --no-progress\n\n# Cleanup\nrm -rf \"$WORK_DIR\" \"/var/tmp/forensics-${INSTANCE_ID}-${TIMESTAMP}.tar.gz\"\n\necho \"Forensic collection complete. Data uploaded to s3://${S3_BUCKET}/guardduty-ec2-malware/${INSTANCE_ID}/\"\n" ] }, "TimeoutSeconds": 600 } }, { "name": "CreateEBSSnapshot", "action": "aws:executeAwsApi", "inputs": { "Service": "ec2", "Api": "CreateSnapshot", "VolumeId": "{{ GetInstanceDetails.volumeId }}", "Description": "Forensic snapshot for {{ InstanceId }} - GuardDuty malware finding", "TagSpecifications": [ { "ResourceType": "snapshot", "Tags": [ { "Key": "Forensics", "Value": "GuardDuty-Malware" }, { "Key": "InstanceId", "Value": "{{ InstanceId }}" } ] } ] } }, { "name": "ReplaceSecurityGroup", "action": "aws:executeAwsApi", "inputs": { "Service": "ec2", "Api": "ModifyInstanceAttribute", "InstanceId": "{{ InstanceId }}", "Groups": [ "{{ IsolationSecurityGroupId }}" ] } } ] }