Skip to content

Commit

Permalink
feat(queries): add new aws iam privilege escalation queries (#5423)
Browse files Browse the repository at this point in the history
* feat(queries): add new aws iam privilege escalation queries

* change to KICS query file structure

* add functions get_group, get_role, get_user, unrecommended_permission_policy_scenarios, unrecommended_permission_policy to common library

* Titling queryName

* fix descriptionUrl

* fix positive tests

* fix positive tests expected result

* change iam privilege escalation folders names

* add resourceType and resourceName

* fix rego import and role/user/group reference

* Add links in description

Co-authored-by: gafnit <agafnit@gmail.com>
  • Loading branch information
gafnit-lightspin and gafnit authored Aug 22, 2022
1 parent 1216dc9 commit 4006b83
Show file tree
Hide file tree
Showing 286 changed files with 5,543 additions and 0 deletions.
122 changes: 122 additions & 0 deletions assets/libraries/common.rego
Original file line number Diff line number Diff line change
Expand Up @@ -541,3 +541,125 @@ is_aws_ebs_optimized_by_default(instanceType) {
inArray(data.common_lib.aws_ebs_optimized_by_default, instanceType)
}

get_group_from_policy_attachment(attachment) = group {
group := split(attachment.groups[_], ".")[1]
} else = group {
group := split(attachment.group, ".")[1]
}

get_role_from_policy_attachment(attachment) = role {
role := split(attachment.roles[_], ".")[1]
} else = role {
role := split(attachment.role, ".")[1]
}

get_user_from_policy_attachment(attachment) = user {
user := split(attachment.users[_], ".")[1]
} else = user {
user := split(attachment.user, ".")[1]
}

unrecommended_permission_policy(resourcePolicy, permission) {
policy := json_unmarshal(resourcePolicy.policy)

st := get_statement(policy)
statement := st[_]

is_allow_effect(statement)

equalsOrInArray(statement.Resource, "*")
equalsOrInArray(statement.Action, lower(permission))
}

group_unrecommended_permission_policy_scenarios(targetGroup, permission) {
# get the IAM group policy
groupPolicy := input.document[_].resource.aws_iam_group_policy[_]

# get the group referenced in IAM group policy and confirm it is the target group
group := split(groupPolicy.group, ".")[1]
group == targetGroup

# verify that the policy is unrecommended
unrecommended_permission_policy(groupPolicy, permission)
} else {

# find attachment
attachments := {"aws_iam_policy_attachment", "aws_iam_group_policy_attachment"}
attachment := input.document[_].resource[attachments[_]][_]

# get the group referenced in IAM policy attachment and confirm it is the target group
group := get_group_from_policy_attachment(attachment)
group == targetGroup

# confirm that policy associated is unrecommended
policy := split(attachment.policy_arn, ".")[1]

policies := {"aws_iam_role_policy", "aws_iam_user_policy", "aws_iam_group_policy", "aws_iam_policy"}
resourcePolicy := input.document[_].resource[policies[_]][policy]

# verify that the policy is unrecommended
unrecommended_permission_policy(resourcePolicy, permission)

}

role_unrecommended_permission_policy_scenarios(targetRole, permission) {
# get the IAM role policy
rolePolicy := input.document[_].resource.aws_iam_role_policy[_]

# get the role referenced in IAM role policy and confirm it is the target role
role := split(rolePolicy.role, ".")[1]
role == targetRole

# verify that the policy is unrecommended
unrecommended_permission_policy(rolePolicy, permission)
} else {

# find attachment
attachments := {"aws_iam_policy_attachment", "aws_iam_role_policy_attachment"}
attachment := input.document[_].resource[attachments[_]][_]

# get the role referenced in IAM policy attachment and confirm it is the target role
role := get_role_from_policy_attachment(attachment)
role == targetRole

# confirm that policy associated is unrecommended
policy := split(attachment.policy_arn, ".")[1]

policies := {"aws_iam_role_policy", "aws_iam_user_policy", "aws_iam_group_policy", "aws_iam_policy"}
resourcePolicy := input.document[_].resource[policies[_]][policy]

# verify that the policy is unrecommended
unrecommended_permission_policy(resourcePolicy, permission)

}

user_unrecommended_permission_policy_scenarios(targetUser, permission) {
# get the IAM user policy
userPolicy := input.document[_].resource.aws_iam_user_policy[_]

# get the user referenced in IAM user policy and confirm it is the target user
user := split(userPolicy.user, ".")[1]
user == targetUser

# verify that the policy is unrecommended
unrecommended_permission_policy(userPolicy, permission)
} else {

# find attachment
attachments := {"aws_iam_policy_attachment", "aws_iam_user_policy_attachment"}
attachment := input.document[_].resource[attachments[_]][_]

# get the user referenced in IAM policy attachment and confirm it is the target user
user := get_user_from_policy_attachment(attachment)
user == targetUser

# confirm that policy associated is unrecommended
policy := split(attachment.policy_arn, ".")[1]

policies := {"aws_iam_role_policy", "aws_iam_user_policy", "aws_iam_group_policy", "aws_iam_policy"}
resourcePolicy := input.document[_].resource[policies[_]][policy]

# verify that the policy is unrecommended
unrecommended_permission_policy(resourcePolicy, permission)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"id": "8f3c16b3-354d-45db-8ad5-5066778a9485",
"queryName": "Group With Privilege Escalation By Actions 'glue:UpdateDevEndpoint'",
"severity": "MEDIUM",
"category": "Access Control",
"descriptionText": "Group with privilege escalation by actions 'glue:UpdateDevEndpoint' and Resource set to '*'. For more information see https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/.",
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_policy#policy",
"platform": "Terraform",
"descriptionID": "10f17e18",
"cloudProvider": "aws"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package Cx

import data.generic.common as common_lib
import data.generic.terraform as tf_lib

CxPolicy[result] {

# get a AWS IAM group
group := input.document[i].resource.aws_iam_group[targetGroup]

common_lib.group_unrecommended_permission_policy_scenarios(targetGroup, "glue:UpdateDevEndpoint")


result := {
"documentId": input.document[i].id,
"resourceType": "aws_iam_group",
"resourceName": tf_lib.get_resource_name(group, targetGroup),
"searchKey": sprintf("aws_iam_group[%s]", [targetGroup]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("group %s is not associated with a policy that has Action set to 'glue:UpdateDevEndpoint' and Resource set to '*'", [targetGroup]),
"keyActualValue": sprintf("group %s is associated with a policy that has Action set to 'glue:UpdateDevEndpoint' and Resource set to '*'", [targetGroup]),
"searchLine": common_lib.build_search_line(["resource", "aws_iam_group", targetGroup], []),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "aws_iam_user" "cosmic2" {
name = "cosmic2"
}

resource "aws_iam_user_policy" "inline_policy_run_instances2" {
name = "inline_policy_run_instances"
user = aws_iam_user.cosmic2.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "aws_iam_group" "cosmic" {
name = "cosmic"
}

resource "aws_iam_group_policy" "test_inline_policy" {
name = "test_inline_policy"
group = aws_iam_group.cosmic.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"glue:UpdateDevEndpoint",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"queryName": "Group With Privilege Escalation By Actions 'glue:UpdateDevEndpoint'",
"severity": "MEDIUM",
"line": 1,
"fileName": "positive1.tf"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"id": "970ed7a2-0aca-4425-acf1-0453c9ecbca1",
"queryName": "Group With Privilege Escalation By Actions 'iam:AddUserToGroup'",
"severity": "MEDIUM",
"category": "Access Control",
"descriptionText": "Group with privilege escalation by actions 'iam:AddUserToGroup' and Resource set to '*'. For more information see https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/.",
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_policy#policy",
"platform": "Terraform",
"descriptionID": "576ba016",
"cloudProvider": "aws"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package Cx

import data.generic.common as common_lib
import data.generic.terraform as tf_lib

CxPolicy[result] {

# get a AWS IAM group
group := input.document[i].resource.aws_iam_group[targetGroup]

common_lib.group_unrecommended_permission_policy_scenarios(targetGroup, "iam:AddUserToGroup")


result := {
"documentId": input.document[i].id,
"resourceType": "aws_iam_group",
"resourceName": tf_lib.get_resource_name(group, targetGroup),
"searchKey": sprintf("aws_iam_group[%s]", [targetGroup]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("group %s is not associated with a policy that has Action set to 'iam:AddUserToGroup' and Resource set to '*'", [targetGroup]),
"keyActualValue": sprintf("group %s is associated with a policy that has Action set to 'iam:AddUserToGroup' and Resource set to '*'", [targetGroup]),
"searchLine": common_lib.build_search_line(["resource", "aws_iam_group", targetGroup], []),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "aws_iam_user" "cosmic2" {
name = "cosmic2"
}

resource "aws_iam_user_policy" "inline_policy_run_instances2" {
name = "inline_policy_run_instances"
user = aws_iam_user.cosmic2.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "aws_iam_group" "cosmic" {
name = "cosmic"
}

resource "aws_iam_group_policy" "test_inline_policy" {
name = "test_inline_policy"
group = aws_iam_group.cosmic.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"iam:AddUserToGroup",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"queryName": "Group With Privilege Escalation By Actions 'iam:AddUserToGroup'",
"severity": "MEDIUM",
"line": 1,
"fileName": "positive1.tf"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"id": "70b42736-efee-4bce-80d5-50358ed94990",
"queryName": "Group With Privilege Escalation By Actions 'iam:AttachGroupPolicy'",
"severity": "MEDIUM",
"category": "Access Control",
"descriptionText": "Group with privilege escalation by actions 'iam:AttachGroupPolicy' and Resource set to '*'. For more information see https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/.",
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_group_policy#policy",
"platform": "Terraform",
"descriptionID": "e42aec0c",
"cloudProvider": "aws"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package Cx

import data.generic.common as common_lib
import data.generic.terraform as tf_lib

CxPolicy[result] {

# get a AWS IAM group
group := input.document[i].resource.aws_iam_group[targetGroup]

common_lib.group_unrecommended_permission_policy_scenarios(targetGroup, "iam:AttachGroupPolicy")


result := {
"documentId": input.document[i].id,
"resourceType": "aws_iam_group",
"resourceName": tf_lib.get_resource_name(group, targetGroup),
"searchKey": sprintf("aws_iam_group[%s]", [targetGroup]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("group %s is not associated with a policy that has Action set to 'iam:AttachGroupPolicy' and Resource set to '*'", [targetGroup]),
"keyActualValue": sprintf("group %s is associated with a policy that has Action set to 'iam:AttachGroupPolicy' and Resource set to '*'", [targetGroup]),
"searchLine": common_lib.build_search_line(["resource", "aws_iam_group", targetGroup], []),
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
resource "aws_iam_user" "cosmic2" {
name = "cosmic2"
}

resource "aws_iam_user_policy" "inline_policy_run_instances2" {
name = "inline_policy_run_instances"
user = aws_iam_user.cosmic2.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
resource "aws_iam_group" "cosmic" {
name = "cosmic"
}

resource "aws_iam_group_policy" "test_inline_policy" {
name = "test_inline_policy"
group = aws_iam_group.cosmic.name

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"iam:AttachGroupPolicy",
]
Effect = "Allow"
Resource = "*"
},
]
})
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"queryName": "Group With Privilege Escalation By Actions 'iam:AttachGroupPolicy'",
"severity": "MEDIUM",
"line": 1,
"fileName": "positive1.tf"
}
]
Loading

0 comments on commit 4006b83

Please sign in to comment.