@@ -761,10 +761,11 @@ For more information about Applications check:
761761../az-basic-information/
762762{{# endref}}
763763
764- When an App is generated 2 types of permissions are given:
764+ When an App is generated 3 types of permissions are given:
765765
766- - ** Permissions** given to the ** Service Principal**
766+ - ** Permissions** given to the ** Service Principal** (via roles).
767767- ** Permissions** the ** app** can have and use on ** behalf of the user** .
768+ - ** API Permissions** that gives the app permissions over EntraID withuot requiring other roles granting these permissions.
768769
769770{{# tabs }}
770771{{# tab name="az cli" }}
@@ -820,7 +821,7 @@ az ad sp show --id 00000003-0000-0000-c000-000000000000 --query "appRoles[?id=='
820821` ` `
821822
822823< details>
823- < summary> Find all applications with API permissions to non- Microsoft APIs (az cli)< /summary>
824+ < summary> Find all applications API permissions and mark Microsoft-owned APIs (az cli)< /summary>
824825
825826` ` ` bash
826827#! /usr/bin/env bash
@@ -843,6 +844,32 @@ is_microsoft_owner() {
843844 return 1
844845}
845846
847+ get_permission_value () {
848+ local resource_app_id=" $1 "
849+ local perm_type=" $2 "
850+ local perm_id=" $3 "
851+ local key value
852+ key=" ${resource_app_id} |${perm_type} |${perm_id} "
853+
854+ value=" $( awk -F ' \t' -v k=" $key " ' $1==k {print $2; exit}' " $tmp_perm_cache " ) "
855+ if [ -n " $value " ]; then
856+ printf ' %s\n' " $value "
857+ return 0
858+ fi
859+
860+ if [ " $perm_type " = " Scope" ]; then
861+ value=" $( az ad sp show --id " $resource_app_id " --query " oauth2PermissionScopes[?id=='$perm_id '].value | [0]" -o tsv 2> /dev/null || true) "
862+ elif [ " $perm_type " = " Role" ]; then
863+ value=" $( az ad sp show --id " $resource_app_id " --query " appRoles[?id=='$perm_id '].value | [0]" -o tsv 2> /dev/null || true) "
864+ else
865+ value=" "
866+ fi
867+
868+ [ -n " $value " ] || value=" UNKNOWN"
869+ printf ' %s\t%s\n' " $key " " $value " >> " $tmp_perm_cache "
870+ printf ' %s\n' " $value "
871+ }
872+
846873command -v az > /dev/null 2>&1 || { echo " az CLI not found" >&2 ; exit 1; }
847874command -v jq > /dev/null 2>&1 || { echo " jq not found" >&2 ; exit 1; }
848875az account show > /dev/null
@@ -851,7 +878,8 @@ apps_json="$(az ad app list --all --query '[?length(requiredResourceAccess) > `0
851878
852879tmp_map=" $( mktemp) "
853880tmp_ids=" $( mktemp) "
854- trap ' rm -f "$tmp_map" "$tmp_ids"' EXIT
881+ tmp_perm_cache=" $( mktemp) "
882+ trap ' rm -f "$tmp_map" "$tmp_ids" "$tmp_perm_cache"' EXIT
855883
856884# Build unique resourceAppId values used by applications.
857885jq -r ' .[][2][]?.resourceAppId' <<< " $apps_json" | sort -u > " $tmp_ids "
@@ -865,9 +893,9 @@ while IFS= read -r rid; do
865893 printf ' %s\t%s\t%s\n' " $rid " " $owner " " $name " >> " $tmp_map "
866894done < " $tmp_ids "
867895
868- echo -e " appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tresourceOwnerOrgId\tpermissionType\tpermissionId "
896+ echo -e " appDisplayName\tappId\tresourceApiDisplayName\tresourceAppId\tisMicrosoft\tpermissions "
869897
870- # Print only app permissions where the target API is NOT Microsoft-owned.
898+ # Print all app API permissions and mark if the target API is Microsoft-owned.
871899while IFS= read -r row; do
872900 app_name=" $( jq -r ' .[0]' <<< " $row" ) "
873901 app_id=" $( jq -r ' .[1]' <<< " $row" ) "
@@ -882,14 +910,25 @@ while IFS= read -r row; do
882910 [ -n " $resource_name " ] || resource_name=" UNKNOWN"
883911
884912 if is_microsoft_owner " $owner_org " ; then
885- continue
913+ is_ms=" true"
914+ else
915+ is_ms=" false"
886916 fi
887917
918+ permissions_csv=" "
888919 while IFS= read -r access; do
889920 perm_type=" $( jq -r ' .type' <<< " $access" ) "
890921 perm_id=" $( jq -r ' .id' <<< " $access" ) "
891- echo -e " ${app_name} \t${app_id} \t${resource_name} \t${resource_app_id} \t${owner_org} \t${perm_type} \t${perm_id} "
922+ perm_value=" $( get_permission_value " $resource_app_id " " $perm_type " " $perm_id " ) "
923+ perm_label=" ${perm_type} :${perm_value} "
924+ if [ -z " $permissions_csv " ]; then
925+ permissions_csv=" $perm_label "
926+ else
927+ permissions_csv=" ${permissions_csv} ,${perm_label} "
928+ fi
892929 done < <( jq -c ' .resourceAccess[]' <<< " $rra" )
930+
931+ echo -e " ${app_name} \t${app_id} \t${resource_name} \t${resource_app_id} \t${is_ms} \t${permissions_csv} "
893932 done < <( jq -c ' .[2][]' <<< " $row" )
894933done < <( jq -c ' .[]' <<< " $apps_json" )
895934` ` `
@@ -1383,5 +1422,3 @@ The default mode is **Audit**:
13831422- [EntraTokenAid](https://github.com/zh54321/EntraTokenAid)
13841423
13851424{{#include ../../../banners/hacktricks-training.md}}
1386-
1387-
0 commit comments