Owner
Difficulty:
Shown in Report
Help Goose James near the park discover the accidentally leaked SAS token in a public JavaScript file and determine what Azure Storage resource it exposes and what permissions it grants.
Objective Image
Back
Challenge

Cluckβ€”wait, what? I swear I’m hearing voices, but all the elves are gone…
Anyway, the Neighborhood HOA runs their IT infrastructure on Azure. Their admins use RBAC for access control.
Your task: Audit the RBAC configuration to ensure security best practices are followed. They claim elevated access uses PIM, but confirm there are no permanently assigned Owner roles.

Solution

This task is guided by the system. Therefore, I will only show the commands and most important console outputs here:

πŸŽ„ Welcome to the Owner Challenge! πŸŽ„
You're connected to a read-only Azure CLI session in "The Neighborhood" tenant.
Your mission: Investigate the permissions and identify WHO has access they shouldn't.
Connecting you now... ❄️
Let's learn some more Azure CLI, the --query parameter with JMESPath syntax!
$ az account list --query "[].name"
Here, [] loops through each item, .name grabs the name field
neighbor@b13c1911d74e:~$ az account list --query "[].name"
[
  "theneighborhood-sub",
...
You can do some more advanced queries using conditional filtering with custom output.
  $ az account list --query "[?state=='Enabled'].{Name:name, ID:id}"
Cool! 😎  [?condition] filters what you want, {custom:fields} makes clean output ✨
neighbor@b13c1911d74e:~$ az account list --query "[?state=='Enabled'].{Name:name, ID:id}"
[
  {
    "ID": "2b0942f3-9bca-484b-a508-abdae2db5e64",
    "Name": "theneighborhood-sub"
...
Let's take a look at the Owner's of the first listed subscription πŸ”. Pass in the first subscription id.
Try: az role assignment list --scope "/subscriptions/{ID of first Subscription}" --query [?roleDefinition=='Owner']
neighbor@b13c1911d74e:~$ az role assignment list --scope "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64" --query [?roleDefinition=='Owner']
[
  {
    "condition": "null",
    "conditionVersion": "null",
    "createdBy": "85b095fa-a9b4-4bdc-a3af-c9f95ebb8dd6",
...
Ok πŸ€” β€” there is a group present for the Owners permission; however, we've been assured this is a πŸ” PIM enabled group.
Currently, no PIM activations are present. 🚨
Let's run the previous command against the other subscriptions to see what we come up with.
neighbor@b13c1911d74e:~$ az role assignment list --scope "/subscriptions/065cc24a-077e-40b9-b666-2f4dd9f3a617" --query [?roleDefinition=='Owner']
...
    "name": "6b452f58-6872-4064-ae9b-78742e8d987e",
    "principalId": "6b982f2f-78a0-44a8-b915-79240b2b4796",
    "principalName": "IT Admins",
    "principalType": "Group",
...
Looks like you are on to something here! πŸ•΅οΈ  We were assured that only the πŸ” PIM group was present for each subscription.
πŸ”Ž Let's figure out the membership of that group.
Hint: use the az ad member list command. Pass the group id instead of the name.
Remember: | less lets you scroll through long output
neighbor@b13c1911d74e:~$ az ad member list --group 6b982f2f-78a0-44a8-b915-79240b2b4796 | less
...
    "groupTypes": [],
    "id": "631ebd3f-39f9-4492-a780-aef2aec8c94e",
    "isAssignableToRole": null,
...
Well 😀, that's annoying. Looks like we have a nested group!
Let's run the command one more time against this group.
neighbor@b13c1911d74e:~$ az ad member list --group 631ebd3f-39f9-4492-a780-aef2aec8c94e | less
...
    "displayName": "Firewall Frank",
    "givenName": "Frank",
    "id": "b8613dd2-5e33-4d77-91fb-b4f2338c19c9",
    "jobTitle": "HOA IT Administrator",
    "mail": "frank.firewall@theneighborhood.invalid",
elevated access instead of permanent assignments. Permanent Owner roles create persistent
attack paths and violate least-privilege principles.

Challenge Complete! To finish, type: finish