mirror of
https://github.com/mgeeky/Penetration-Testing-Tools.git
synced 2024-11-25 12:01:37 +01:00
Enhanced evaluate-iam-role.sh
This commit is contained in:
parent
fb01387ed3
commit
98262b1cee
@ -93,7 +93,78 @@ Afterwards, one should see following logs in CloudWatch traces for planted Lambd
|
|||||||
[*] Following S3 object could be removed: (Bucket=90112981864022885796153088027941100000000000000000000000, Key=cloudtrail/AWSLogs/712800000000/CloudTrail/us-west-2/2019/03/20/712800000000_CloudTrail_us-west-2_20190320T1000Z_oxxxxxxxxxxxxc.json.gz)
|
[*] Following S3 object could be removed: (Bucket=90112981864022885796153088027941100000000000000000000000, Key=cloudtrail/AWSLogs/712800000000/CloudTrail/us-west-2/2019/03/20/712800000000_CloudTrail_us-west-2_20190320T1000Z_oxxxxxxxxxxxxc.json.gz)
|
||||||
```
|
```
|
||||||
|
|
||||||
- **`evaluate-iam-role.sh`** - Enumerates attached IAM Role policies, goes through all of granted permissions and lists those that are known for Privilege Escalation risks. Based on [Rhino Security Labs work](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/). [gist](https://gist.github.com/mgeeky/14685d94af7848e64afefe6fd2341a18)
|
- **`evaluate-iam-role.sh`** - Enumerates attached IAM Role policies or specified Policy by it's Arn, goes through all of granted permissions and lists those that are known for Privilege Escalation or other risks. If `all` was specified as a role-name, the tool will evaluate all of the user-specified IAM Roles, iteratively. Based on [Rhino Security Labs work](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/). [gist](https://gist.github.com/mgeeky/14685d94af7848e64afefe6fd2341a18)
|
||||||
|
|
||||||
|
```
|
||||||
|
attacker $ ./evaluate-iam-role.sh awl CustomSysOpsRole
|
||||||
|
[+] Working on specified Role: CustomSysOpsRole
|
||||||
|
|
||||||
|
[+] Role (CustomSysOpsRole) has following policies attached:
|
||||||
|
- arn:aws:iam::aws:policy/AmazonRDSFullAccess
|
||||||
|
- arn:aws:iam::aws:policy/AmazonEC2FullAccess
|
||||||
|
- arn:aws:iam::aws:policy/AWSLambdaFullAccess
|
||||||
|
- arn:aws:iam::aws:policy/AmazonS3FullAccess
|
||||||
|
- arn:aws:iam::aws:policy/ReadOnlyAccess
|
||||||
|
- arn:aws:iam::aws:policy/AmazonSSMFullAccess
|
||||||
|
- arn:aws:iam::aws:policy/AmazonMQFullAccess
|
||||||
|
- arn:aws:iam::aws:policy/AWSBackupAdminPolicy
|
||||||
|
|
||||||
|
|
||||||
|
[+] =============== Permissions granted ===============
|
||||||
|
|
||||||
|
a4b:Describe*
|
||||||
|
a4b:Get*
|
||||||
|
a4b:List*
|
||||||
|
a4b:Search*
|
||||||
|
acm:Describe*
|
||||||
|
acm:DescribeCertificate
|
||||||
|
acm:Get*
|
||||||
|
acm:List*
|
||||||
|
[...]
|
||||||
|
workdocs:Get*
|
||||||
|
worklink:Describe*
|
||||||
|
worklink:List*
|
||||||
|
workmail:Describe*
|
||||||
|
workmail:Get*
|
||||||
|
workmail:List*
|
||||||
|
workmail:Search*
|
||||||
|
workspaces:Describe*
|
||||||
|
xray:BatchGet*
|
||||||
|
xray:Get*
|
||||||
|
xray:PutTelemetryRecords
|
||||||
|
xray:PutTraceSegments
|
||||||
|
|
||||||
|
|
||||||
|
[-] =============== Detected POTENTIALLY dangerous permissions granted ===============
|
||||||
|
|
||||||
|
[...]
|
||||||
|
backup:*
|
||||||
|
backup-storage:*
|
||||||
|
clouddirectory:BatchRead
|
||||||
|
cloudformation:*
|
||||||
|
cloudformation:CreateStack
|
||||||
|
[...]
|
||||||
|
iot:CreateThing
|
||||||
|
iot:CreateTopicRule
|
||||||
|
sns:*
|
||||||
|
sqs:*
|
||||||
|
sqs:SendMessage
|
||||||
|
ssm:*
|
||||||
|
ssmmessages:CreateControlChannel
|
||||||
|
ssmmessages:CreateDataChannel
|
||||||
|
support:*
|
||||||
|
xray:BatchGet*
|
||||||
|
xray:PutTelemetryRecords
|
||||||
|
xray:PutTraceSegments
|
||||||
|
|
||||||
|
|
||||||
|
[!] =============== Detected DANGEROUS permissions granted ===============
|
||||||
|
|
||||||
|
cloudformation:CreateStack
|
||||||
|
iam:AttachRolePolicy
|
||||||
|
iam:PassRole
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
- **`exfiltrate-ec2.py`** - This script exploits insecure permissions given to the EC2 IAM Role allowing to exfiltrate target EC2's filesystem data in a form of it's shared EBS snapshot or publicly exposed AMI image.
|
- **`exfiltrate-ec2.py`** - This script exploits insecure permissions given to the EC2 IAM Role allowing to exfiltrate target EC2's filesystem data in a form of it's shared EBS snapshot or publicly exposed AMI image.
|
||||||
|
|
||||||
|
@ -1,131 +1,245 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Evaluates specified AWS IAM Role or Policy given their name/Arn.
|
||||||
|
# Dumps all of the attached policies in case of Role and all of defined
|
||||||
|
# policy statements. Then goes through allowed permissions to pick all of them out.
|
||||||
|
# Finally, checks every allowed permission against a list of known troublesome ones.
|
||||||
|
#
|
||||||
|
# Mariusz B., mgeeky '19, <mb@binary-offensive.com>
|
||||||
|
# v0.1
|
||||||
|
#
|
||||||
|
|
||||||
if [ $# -ne 2 ]; then
|
if [ $# -lt 2 ] ; then
|
||||||
echo "Usage: evaluate-iam-role.sh <profile> <role-name>"
|
echo "Usage: evaluate-iam-role.sh [-v] <profile> <role-name|policy-arn>"
|
||||||
|
echo
|
||||||
|
echo -e "-v\t\t\tVerbose mode. Dumps full roles/policies contents."
|
||||||
|
echo -e "profile\t\t\tAWS credentials profile name."
|
||||||
|
echo -e "role-name|policy-name\tEither IAM Role name or Policy Arn to evaluate."
|
||||||
|
echo -e "\t\t\tIf 'all' was specified, will evaluate ALL used IAM Roles"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
VERBOSE=0
|
||||||
|
if [[ "$1" == "-v" ]]; then
|
||||||
|
VERBOSE=1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
PROFILE=$1
|
PROFILE=$1
|
||||||
ROLE_NAME=$2
|
ROLE_NAME=$2
|
||||||
|
|
||||||
known_potentially_dangerous_permissions=(
|
known_potentially_dangerous_permissions=(
|
||||||
".*:\*"
|
".+:\*"
|
||||||
".*:.*Attach.*"
|
".*:Add.*"
|
||||||
".*:.*Create.*"
|
".*:Attach.*"
|
||||||
".*:.*Delete.*"
|
".*:Batch.*"
|
||||||
".*:.*Reboot.*"
|
".*:Change.*"
|
||||||
".*:.*Command.*"
|
".*:Command.*"
|
||||||
".*:.*Run.*"
|
".*:Create.*"
|
||||||
".*:.*Send.*"
|
".*:Delete.*"
|
||||||
".*:.*Batch.*"
|
".*:Execute.*"
|
||||||
".*:.*Set.*"
|
".*:Invoke.*"
|
||||||
".*:.*Invoke.*"
|
".*:Modify.*"
|
||||||
".*:.*Add.*"
|
".*:Put.*"
|
||||||
".*:.*Execute.*"
|
".*:Reboot.*"
|
||||||
".*:.*Start.*"
|
".*:Register.*"
|
||||||
".*:.*Modify.*"
|
".*:Replace.*"
|
||||||
".*:.*Register.*"
|
".*:Run.*"
|
||||||
".*:.*Replace.*"
|
".*:Send.*"
|
||||||
".*:.*Change.*"
|
".*:Set.*"
|
||||||
".*:.*Update.*"
|
".*:Start.*"
|
||||||
".*:.*Put.*"
|
".*:Update.*"
|
||||||
)
|
)
|
||||||
|
|
||||||
known_dangerous_permissions=(
|
known_dangerous_permissions=(
|
||||||
"\*:\*"
|
"\*:\*"
|
||||||
"iam:\*"
|
|
||||||
"iam:CreatePolicyVersion"
|
|
||||||
"iam:SetDefaultPolicyVersion"
|
|
||||||
"iam:PassRole"
|
|
||||||
"ec2:RunInstances"
|
|
||||||
"iam:CreateAccessKey"
|
|
||||||
"iam:CreateLoginProfile"
|
|
||||||
"iam:UpdateLoginProfile"
|
|
||||||
"iam:AttachUserPolicy"
|
|
||||||
"iam:AttachGroupPolicy"
|
|
||||||
"iam:AttachRolePolicy"
|
|
||||||
"iam:PutUserPolicy"
|
|
||||||
"iam:PutGroupPolicy"
|
|
||||||
"iam:PutRolePolicy"
|
|
||||||
"iam:AddUserToGroup"
|
|
||||||
"iam:UpdateAssumeRolePolicy"
|
|
||||||
"sts:AssumeRole"
|
|
||||||
"iam:PassRole"
|
|
||||||
"lambda:CreateFunction"
|
|
||||||
"lambda:InvokeFunction"
|
|
||||||
"lambda:CreateEventSourceMapping"
|
|
||||||
"lambda:UpdateFunctionCode"
|
|
||||||
"glue:CreateDevEndpoint"
|
|
||||||
"glue:UpdateDevEndpoint"
|
|
||||||
"cloudformation:CreateStack"
|
"cloudformation:CreateStack"
|
||||||
"datapipeline:CreatePipeline"
|
"datapipeline:CreatePipeline"
|
||||||
"datapipeline:PutPipelineDefinition"
|
"datapipeline:PutPipelineDefinition"
|
||||||
|
"ec2:RunInstances"
|
||||||
|
"glue:CreateDevEndpoint"
|
||||||
|
"glue:UpdateDevEndpoint"
|
||||||
|
"iam:\*"
|
||||||
|
"iam:AddUserToGroup"
|
||||||
|
"iam:AttachGroupPolicy"
|
||||||
|
"iam:AttachRolePolicy"
|
||||||
|
"iam:AttachUserPolicy"
|
||||||
|
"iam:CreateAccessKey"
|
||||||
|
"iam:CreateLoginProfile"
|
||||||
|
"iam:CreatePolicyVersion"
|
||||||
|
"iam:PassRole"
|
||||||
|
"iam:PassRole"
|
||||||
|
"iam:PutGroupPolicy"
|
||||||
|
"iam:PutRolePolicy"
|
||||||
|
"iam:PutUserPolicy"
|
||||||
|
"iam:SetDefaultPolicyVersion"
|
||||||
|
"iam:UpdateAssumeRolePolicy"
|
||||||
|
"iam:UpdateLoginProfile"
|
||||||
|
"lambda:CreateEventSourceMapping"
|
||||||
|
"lambda:CreateFunction"
|
||||||
|
"lambda:InvokeFunction"
|
||||||
|
"lambda:UpdateFunctionCode"
|
||||||
|
"sts:AssumeRole"
|
||||||
)
|
)
|
||||||
|
|
||||||
role_policy=$(aws --profile $PROFILE iam get-role --role-name $ROLE_NAME)
|
known_dangerous_aws_managed_policies=(
|
||||||
|
"arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"
|
||||||
echo -e "=============== Role: $ROLE_NAME ==============="
|
"arn:aws:iam::aws:policy/service-role/AmazonMachineLearningRoleforRedshiftDataSource"
|
||||||
echo "$role_policy"
|
)
|
||||||
|
|
||||||
IFS=$'\n'
|
|
||||||
attached_role_policies=($(aws --profile $PROFILE iam list-attached-role-policies --role-name $ROLE_NAME | jq -r '.AttachedPolicies[].PolicyArn'))
|
|
||||||
|
|
||||||
dangerous_permissions=()
|
dangerous_permissions=()
|
||||||
potentially_dangerous_permissions=()
|
potentially_dangerous_permissions=()
|
||||||
all_perms=()
|
all_perms=()
|
||||||
|
used_bad_policies=()
|
||||||
|
|
||||||
for policy in "${attached_role_policies[@]}" ; do
|
function examine_policy() {
|
||||||
echo -e "\n=============== Attached Policy Arn: $policy ==============="
|
policy=$1
|
||||||
|
role_name=$2
|
||||||
|
|
||||||
version_id=$(aws --profile $PROFILE iam get-policy --policy-arn $policy | jq -r '.Policy.DefaultVersionId')
|
out=$(aws --profile $PROFILE iam get-policy --policy-arn $policy)
|
||||||
|
version_id=$(echo "$out" | jq -r '.Policy.DefaultVersionId')
|
||||||
|
policy_name=$(echo "$out" | jq -r '.Policy.PolicyName')
|
||||||
|
|
||||||
policy_version=$(aws --profile $PROFILE iam get-policy-version --policy-arn $policy --version-id $version_id)
|
policy_version=$(aws --profile $PROFILE iam get-policy-version --policy-arn $policy --version-id $version_id)
|
||||||
echo "$policy_version"
|
|
||||||
|
if [[ $VERBOSE == 1 ]]; then
|
||||||
|
echo -e "\n------------[ Policy Arn: $policy ]------------"
|
||||||
|
echo "$policy_version"
|
||||||
|
fi
|
||||||
|
|
||||||
permissions=($(echo "$policy_version" | jq -r '.PolicyVersion.Document.Statement[] | select(.Effect=="Allow") | if .Action|type=="string" then [.Action] else .Action end | .[]'))
|
permissions=($(echo "$policy_version" | jq -r '.PolicyVersion.Document.Statement[] | select(.Effect=="Allow") | if .Action|type=="string" then [.Action] else .Action end | .[]'))
|
||||||
|
|
||||||
|
path=""
|
||||||
|
if [[ "$role_name" != "" ]]; then
|
||||||
|
path="$role_name.$policy_name."
|
||||||
|
else
|
||||||
|
path="$policy_name."
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$ROLE_NAME" != "all" ]] ; then
|
||||||
|
path=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
for bad_policy in "${known_dangerous_aws_managed_policies[@]}"; do
|
||||||
|
if echo "$policy" | grep -iq "$bad_policy" ; then
|
||||||
|
used_bad_policies+=("$path$bad_policy")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
for perm in "${permissions[@]}" ; do
|
for perm in "${permissions[@]}" ; do
|
||||||
all_perms+=("$perm")
|
permadd="$path$perm"
|
||||||
for dangperm in "${known_dangerous_permissions[@]}"; do
|
all_perms+=("$permadd")
|
||||||
if echo "$dangperm" | grep -iq $perm ; then
|
|
||||||
dangerous_permissions+=("$perm")
|
for potdangperm in "${known_potentially_dangerous_permissions[@]}"; do
|
||||||
|
if [[ "$perm" == "iam:*" ]]; then continue ; fi
|
||||||
|
if echo "$perm" | grep -Piq "$potdangperm" ; then
|
||||||
|
potentially_dangerous_permissions+=("$permadd")
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
for dangperm in "${known_potentially_dangerous_permissions[@]}"; do
|
|
||||||
if echo "$perm" | grep -Piq "$dangperm" ; then
|
for dangperm in "${known_dangerous_permissions[@]}"; do
|
||||||
potentially_dangerous_permissions+=("$perm")
|
if echo "$perm" | grep -iq "$dangperm" ; then
|
||||||
|
dangerous_permissions+=("$permadd")
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
done
|
}
|
||||||
|
|
||||||
|
function examine_role() {
|
||||||
|
role_name=$1
|
||||||
|
|
||||||
|
role_policy=$(aws --profile $PROFILE iam get-role --role-name $role_name)
|
||||||
|
|
||||||
|
if [[ $VERBOSE == 1 ]]; then
|
||||||
|
echo -e "------------[ Role: $role_name ]------------"
|
||||||
|
echo "$role_policy"
|
||||||
|
fi
|
||||||
|
|
||||||
|
attached_role_policies=($(aws --profile $PROFILE iam list-attached-role-policies --role-name $role_name | jq -r '.AttachedPolicies[].PolicyArn'))
|
||||||
|
|
||||||
|
if [[ $VERBOSE == 1 ]]; then
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
echo "[+] Role ($role_name) has following policies attached:"
|
||||||
|
for policy in "${attached_role_policies[@]}" ; do
|
||||||
|
echo -e "\t- $policy"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $VERBOSE == 1 ]]; then
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
for policy in "${attached_role_policies[@]}" ; do
|
||||||
|
examine_policy $policy $role_name
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
#------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
|
||||||
|
IFS=$'\n'
|
||||||
|
|
||||||
|
if [[ "$ROLE_NAME" == "all" ]]; then
|
||||||
|
echo "[+] Evaluating ALL used IAM Roles"
|
||||||
|
echo
|
||||||
|
|
||||||
|
out=($(aws --profile awl iam list-roles --query 'Roles[*].RoleName' --output text | tr '\t' '\n'))
|
||||||
|
|
||||||
|
for role in "${out[@]}"; do
|
||||||
|
examine_role $role
|
||||||
|
done
|
||||||
|
|
||||||
|
elif echo "$ROLE_NAME" | grep -q "arn:aws:iam:" && echo "$ROLE_NAME" | grep -q ":policy/" ; then
|
||||||
|
echo "[+] Working on specified Policy Arn: $ROLE_NAME"
|
||||||
|
echo
|
||||||
|
|
||||||
|
examine_policy $ROLE_NAME
|
||||||
|
else
|
||||||
|
echo "[+] Working on specified Role: $ROLE_NAME"
|
||||||
|
echo
|
||||||
|
|
||||||
|
examine_role $ROLE_NAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
#------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [[ ${#used_bad_policies[@]} -gt 0 ]]; then
|
||||||
|
echo -e "\n\n[-] =============== Found AWS Managed Insecure Policies in Use ==============="
|
||||||
|
echo
|
||||||
|
sorted=($(echo "${used_bad_policies[@]}" | tr ' ' '\n' | sort -u ))
|
||||||
|
for pol in "${sorted[@]}"; do
|
||||||
|
echo -e "\t$pol"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ${#all_perms[@]} -gt 0 ]]; then
|
if [[ ${#all_perms[@]} -gt 0 ]]; then
|
||||||
echo -e "\n\n=============== All permissions granted to this role ==============="
|
echo -e "\n\n[+] =============== Permissions granted ==============="
|
||||||
|
echo
|
||||||
sorted=($(echo "${all_perms[@]}" | tr ' ' '\n' | sort -u ))
|
sorted=($(echo "${all_perms[@]}" | tr ' ' '\n' | sort -u ))
|
||||||
for perm in "${sorted[@]}"; do
|
for perm in "${sorted[@]}"; do
|
||||||
echo -e "\t$perm"
|
echo -e "\t$perm" | sed -r 's/\./ -> /g'
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ ${#potentially_dangerous_permissions[@]} -gt 0 ]]; then
|
if [[ ${#potentially_dangerous_permissions[@]} -gt 0 ]]; then
|
||||||
echo -e "\n\n=============== Detected POTENTIALLY dangerous permissions granted ==============="
|
echo -e "\n\n[-] =============== Detected POTENTIALLY dangerous permissions granted ==============="
|
||||||
|
echo
|
||||||
sorted=($(echo "${potentially_dangerous_permissions[@]}" | tr ' ' '\n' | sort -u ))
|
sorted=($(echo "${potentially_dangerous_permissions[@]}" | tr ' ' '\n' | sort -u ))
|
||||||
for dangperm in "${sorted[@]}"; do
|
for dangperm in "${sorted[@]}"; do
|
||||||
echo -e "\t$dangperm"
|
echo -e "\t$dangperm" | sed -r 's/\./ -> /g'
|
||||||
done
|
done
|
||||||
else
|
|
||||||
echo -e "\nNo potentially dangerous permissions were found to be granted."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ${#dangerous_permissions[@]} -gt 0 ]]; then
|
if [[ ${#dangerous_permissions[@]} -gt 0 ]]; then
|
||||||
echo -e "\n\n=============== Detected dangerous permissions granted ==============="
|
echo -e "\n\n[!] =============== Detected DANGEROUS permissions granted ==============="
|
||||||
|
echo
|
||||||
sorted=($(echo "${dangerous_permissions[@]}" | tr ' ' '\n' | sort -u ))
|
sorted=($(echo "${dangerous_permissions[@]}" | tr ' ' '\n' | sort -u ))
|
||||||
for dangperm in "${sorted[@]}"; do
|
for dangperm in "${sorted[@]}"; do
|
||||||
echo -e "\t$dangperm"
|
echo -e "\t$dangperm" | sed -r 's/\./ -> /g'
|
||||||
done
|
done
|
||||||
else
|
|
||||||
echo -e "\nNo dangerous permissions were found to be granted."
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -e "\nNo permissions were found to be granted."
|
echo -e "\nNo permissions were found to be granted."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
Loading…
Reference in New Issue
Block a user