diff --git a/core/api/EntraID/graph/helpers/user/Get-MonkeyGraphAADUser.ps1 b/core/api/EntraID/graph/helpers/user/Get-MonkeyGraphAADUser.ps1 index b03e5bd8..31ba7c47 100644 --- a/core/api/EntraID/graph/helpers/user/Get-MonkeyGraphAADUser.ps1 +++ b/core/api/EntraID/graph/helpers/user/Get-MonkeyGraphAADUser.ps1 @@ -237,12 +237,18 @@ Function Get-MonkeyGraphAADUser { $User | Add-Member -type NoteProperty -name mfaenabled -value $mfaenabled -Force $User | Add-Member -type NoteProperty -name mfaStatus -value $mfaStatus -Force $User | Add-Member -type NoteProperty -name mfaMethods -value ($methods -join ",") -Force + #Add id property + $User | Add-Member -type NoteProperty -name id -value $User.objectId -Force #return User $User } } else{ - $allUsers + @($allUsers).ForEach({ + #Add id property + $_ | Add-Member -type NoteProperty -name id -value $_.objectId -Force + $_ + }) } } End{ diff --git a/core/api/EntraID/msgraph/Get-MonkeyMSGraphObject.ps1 b/core/api/EntraID/msgraph/api/Get-MonkeyMSGraphObject.ps1 similarity index 100% rename from core/api/EntraID/msgraph/Get-MonkeyMSGraphObject.ps1 rename to core/api/EntraID/msgraph/api/Get-MonkeyMSGraphObject.ps1 diff --git a/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMActiveRoleAssignment.ps1 b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMActiveRoleAssignment.ps1 new file mode 100644 index 00000000..00904a39 --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMActiveRoleAssignment.ps1 @@ -0,0 +1,67 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Get-MonkeyMSGraphPIMActiveRoleAssignment { + <# + .SYNOPSIS + Get the instances of active role assignments in tenant + + .DESCRIPTION + Get the instances of active role assignments in tenant + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphPIMActiveRoleAssignment + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding()] + Param ( + [parameter(Mandatory=$false, HelpMessage="API version")] + [ValidateSet("v1.0","beta")] + [String]$APIVersion = "beta" + ) + Begin{ + $Environment = $O365Object.Environment + #Get Graph Auth + $graphAuth = $O365Object.auth_tokens.MSGraph + } + Process{ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'roleManagement/directory/roleAssignmentScheduleInstances'; + Environment = $Environment; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + End{ + #Nothing to do here + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMEligibleRoleAssignment.ps1 b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMEligibleRoleAssignment.ps1 new file mode 100644 index 00000000..5c4ca008 --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMEligibleRoleAssignment.ps1 @@ -0,0 +1,67 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Get-MonkeyMSGraphPIMEligibleRoleAssignment { + <# + .SYNOPSIS + Get the instances of role eligibilities in tenant + + .DESCRIPTION + Get the instances of role eligibilities in tenant + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphPIMEligibleRoleAssignment + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding()] + Param ( + [parameter(Mandatory=$false, HelpMessage="API version")] + [ValidateSet("v1.0","beta")] + [String]$APIVersion = "beta" + ) + Begin{ + $Environment = $O365Object.Environment + #Get Graph Auth + $graphAuth = $O365Object.auth_tokens.MSGraph + } + Process{ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'roleManagement/directory/roleEligibilityScheduleInstances'; + Environment = $Environment; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + End{ + #Nothing to do here + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleAssignment.ps1 b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleAssignment.ps1 new file mode 100644 index 00000000..0e519f05 --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleAssignment.ps1 @@ -0,0 +1,468 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +Function Get-MonkeyMSGraphPIMRoleAssignment{ + <# + .SYNOPSIS + Get PIM role assignments + + .DESCRIPTION + Get PIM role assignments + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphPIMRoleAssignment + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Scope="Function")] + [CmdletBinding()] + Param () + try{ + $useOldApi = $true + #Set Job params + If($O365Object.isConfidentialApp){ + $jobParam = @{ + ScriptBlock = { Get-MonkeyMsGraphMFAUserDetail -UserId $_ -APIVersion 'beta'}; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + $useOldApi = $false + } + Else{ + If($O365Object.useOldAADAPIForUsers){ + If($O365Object.canRequestMFAForUsers){ + $jobParam = @{ + ScriptBlock = { Get-MonkeyGraphAADUser -UserId $_ }; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + $useOldApi = $true + } + Else{ + #Set job params + $jobParam = @{ + ScriptBlock = { Get-MonkeyMSGraphUser -UserId $_ -BypassMFACheck -APIVersion 'beta' }; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + $useOldApi = $false + } + } + Else{ + If($O365Object.auth_tokens.MSGraph.clientId -eq (Get-WellKnownAzureService -AzureService MicrosoftGraph)){ + #Set job params + $jobParam = @{ + ScriptBlock = { Get-MonkeyMsGraphMFAUserDetail -UserId $_ -APIVersion 'beta'}; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + $useOldApi = $false + } + Else{ + #Set job params + $jobParam = @{ + ScriptBlock = { Get-MonkeyMSGraphUser -UserId $_ -BypassMFACheck -APIVersion 'beta' }; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + $useOldApi = $false + } + } + } + #Set generic list + $allroleAssignments = [System.Collections.Generic.List[System.Management.Automation.PsObject]]::new() + #Get PIM role assignments + $msg = @{ + MessageData = "Getting Role management policy from PIM"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIDPIMInfo'); + } + Write-Information @msg + $policyAssignments = Get-MonkeyMSGraphPIMRoleManagementPolicyAssignment + #Get role templates + $msg = @{ + MessageData = "Getting Role templates from PIM"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIDPIMInfo'); + } + Write-Information @msg + $roleTemplates = Get-MonkeyMSGraphDirectoryRoleTemplate + #Get all policies + $p = @{ + ScriptBlock = { Get-MonkeyMSGraphPIMRoleManagementPolicy -InputObject $_.policyId }; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + @($policyAssignments).ForEach( + { + $policy = $_; + $settings = $policy | Invoke-MonkeyJob @p + $policy | Add-Member -MemberType NoteProperty -Name settings -Value $settings + #Get role + $role = @($roleTemplates).Where({$_.id -eq $policy.roleDefinitionId}) + if($role.Count -gt 0){ + $roleObject = $role | New-MonkeyPIMRoleObject + $roleObject.policy = $policy; + [void]$allroleAssignments.Add($roleObject); + } + Start-Sleep -Milliseconds 500; + } + ); + #Get Active role assignment + $msg = @{ + MessageData = "Getting active role assignments from PIM"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIDPIMInfo'); + } + Write-Information @msg + $activeRoleAssignments = Get-MonkeyMSGraphPIMActiveRoleAssignment + #Group objects + $active_objects = $activeRoleAssignments | Group-Object -Property roleDefinitionId + foreach($activeRole in $active_objects){ + #Get the role + $myRole = $allroleAssignments.Where({$_.id -eq $activeRole.Name}) | Select-Object -First 1 + $msg = @{ + MessageData = ("Getting active role assignments for {0}" -f $myRole.Name); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIDPIMInfo'); + } + Write-Information @msg + #update object + $myRole.activeAssignment.isUsed = $true; + $myRole.roleInUse = $true; + $activeMembers = $activeRole.Group | Select-Object principalId,startDateTime,endDateTime,assignmentType,memberType -ErrorAction Ignore + if($null -ne $activeMembers){ + #Set array + $allMembers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + $allUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + $allServicePrincipals = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + #Get ids + $ids = $activeMembers | Select-Object -ExpandProperty principalId + $identities = Get-MonkeyMSGraphDirectoryObjectById -Ids $ids + #Get groups + $groups = @($identities).Where({$_.'@odata.type' -match '#microsoft.graph.group'}) + #Get users + $users = @($identities).Where({$_.'@odata.type' -match '#microsoft.graph.user'}) + #Get service Principals + $allSP = @($identities).Where({$_.'@odata.type' -match '#microsoft.graph.servicePrincipal'}) + #get Real members + foreach($grp in $groups){ + $objMetadata = @($activeMembers).Where({$_.principalId -eq $grp.id}) | Select-Object * -First 1 -ErrorAction Ignore + $groupMember = Get-MonkeyMSGraphGroupTransitiveMember -GroupId $grp.id -Parents @($grp.id) + if($groupMember){ + $ids = @($groupMember).Where({$_.'@odata.type' -match '#microsoft.graph.user'}) | Select-Object -ExpandProperty Id + #Invoke job + $members = $ids | Invoke-MonkeyJob @jobParam + if($members){ + foreach($member in @($members)){ + if($null -ne $objMetadata){ + $member | Add-Member -MemberType NoteProperty -Name startDateTime -Value $objMetadata.startDateTime + $member | Add-Member -MemberType NoteProperty -Name endDateTime -Value $objMetadata.endDateTime + $member | Add-Member -MemberType NoteProperty -Name assignmentType -Value $objMetadata.assignmentType + $member | Add-Member -MemberType NoteProperty -Name memberType -Value $objMetadata.memberType + } + [void]$allUsers.Add($member) + } + } + #Get Service Principals + $sps = @($groupMember).Where({$_.'@odata.type' -match '#microsoft.graph.servicePrincipal'}) + foreach($sp in $sps){ + if($null -ne $objMetadata){ + $sp | Add-Member -MemberType NoteProperty -Name startDateTime -Value $objMetadata.startDateTime + $sp | Add-Member -MemberType NoteProperty -Name endDateTime -Value $objMetadata.endDateTime + $sp | Add-Member -MemberType NoteProperty -Name assignmentType -Value $objMetadata.assignmentType + $sp | Add-Member -MemberType NoteProperty -Name memberType -Value $objMetadata.memberType + } + [void]$allServicePrincipals.Add($sp); + } + } + } + #Add users + $ids = $users| Select-Object -ExpandProperty Id + #Invoke job + $members = $ids | Invoke-MonkeyJob @jobParam + if($null -ne $members){ + foreach($member in @($members)){ + $objMetadata = @($activeMembers).Where({$_.principalId -eq $member.id}) | Select-Object * -First 1 -ErrorAction Ignore + if($null -ne $objMetadata){ + $member | Add-Member -MemberType NoteProperty -Name startDateTime -Value $objMetadata.startDateTime + $member | Add-Member -MemberType NoteProperty -Name endDateTime -Value $objMetadata.endDateTime + $member | Add-Member -MemberType NoteProperty -Name assignmentType -Value $objMetadata.assignmentType + $member | Add-Member -MemberType NoteProperty -Name memberType -Value $objMetadata.memberType + } + [void]$allUsers.Add($member) + } + } + #Populate Service principals + foreach($sp in @($allSP)){ + $objMetadata = @($activeMembers).Where({$_.principalId -eq $sp.id}) | Select-Object * -First 1 -ErrorAction Ignore + if($null -ne $objMetadata){ + $sp | Add-Member -MemberType NoteProperty -Name startDateTime -Value $objMetadata.startDateTime + $sp | Add-Member -MemberType NoteProperty -Name endDateTime -Value $objMetadata.endDateTime + $sp | Add-Member -MemberType NoteProperty -Name assignmentType -Value $objMetadata.assignmentType + $sp | Add-Member -MemberType NoteProperty -Name memberType -Value $objMetadata.memberType + } + [void]$allServicePrincipals.Add($sp) + } + #Populate Groups + $myRole.activeAssignment.groups = $groups; + #Get effective users and remove duplicate members + $uniqueUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + $alluniqueUsers = $allUsers | Sort-Object -Property Id -Unique -ErrorAction Ignore + if($null -ne $alluniqueUsers){ + foreach($usr in @($alluniqueUsers)){ + [void]$uniqueUsers.Add($usr); + } + } + #Populate members + $myRole.activeAssignment.users = $uniqueUsers; + #Populate Service Principals + $myRole.activeAssignment.servicePrincipals = $allServicePrincipals; + #Count objects + $myRole.activeAssignment.totalActiveMembers = ($myRole.activeAssignment.users.Count + $myRole.activeAssignment.servicePrincipals.Count) + #Get duplicate users + if($allUsers.Count -gt 0){ + $myRole.activeAssignment.duplicateUsers = Get-MonkeyDuplicateObjectsByProperty -ReferenceObject $allUsers -Property Id + } + Else{ + #Set empty collection + $myRole.activeAssignment.duplicateUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + } + <# + Foreach($identity in @($identities)){ + $obj = @($activeMembers).Where({$_.principalId -eq $identity.id}) | Select-Object * -First 1 -ErrorAction Ignore + if($null -ne $obj){ + $identity | Add-Member -MemberType NoteProperty -Name startDateTime -Value $obj.startDateTime + $identity | Add-Member -MemberType NoteProperty -Name endDateTime -Value $obj.endDateTime + $identity | Add-Member -MemberType NoteProperty -Name assignmentType -Value $obj.assignmentType + $identity | Add-Member -MemberType NoteProperty -Name memberType -Value $obj.memberType + } + [void]$allMembers.Add($identity) + } + $groups = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.group'}) + #get Real members + foreach($grp in $groups){ + $groupMember = Get-MonkeyMSGraphGroupTransitiveMember -GroupId $grp.id -Parents @($grp.id) + if($groupMember){ + foreach($member in $groupMember){ + #Update object + $member | Add-Member -MemberType NoteProperty -Name startDateTime -Value $grp.startDateTime + $member | Add-Member -MemberType NoteProperty -Name endDateTime -Value $grp.endDateTime + $member | Add-Member -MemberType NoteProperty -Name assignmentType -Value $grp.assignmentType + $member | Add-Member -MemberType NoteProperty -Name memberType -Value "Group" + [void]$allMembers.Add($member) + } + } + } + #Get effective users and remove duplicate members + $uniqueUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + $alluniqueUsers = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.user'}) | Sort-Object -Property Id -Unique -ErrorAction Ignore + if($null -ne $alluniqueUsers){ + foreach($usr in @($alluniqueUsers)){ + [void]$uniqueUsers.Add($usr); + } + } + #Get user's id + $allIds = $uniqueUsers | Select-Object -ExpandProperty Id -ErrorAction Ignore + #Invoke job + $members = $allIds | Invoke-MonkeyJob @jobParam + $extendedUniqueUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + if($null -ne $members){ + foreach($member in $members){ + [void]$extendedUniqueUsers.Add($member); + } + } + #> + <# + #Populate members + $myRole.activeAssignment.users = $extendedUniqueUsers; + #Get service principals + $servicePrincipals = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.servicePrincipal'}) + #Populate Service Principals + $myRole.activeAssignment.servicePrincipals = $servicePrincipals; + #Populate Groups + $myRole.activeAssignment.groups = $groups; + #Count objects + $myRole.activeAssignment.totalActiveMembers = ($myRole.activeAssignment.users.Count + $myRole.activeAssignment.servicePrincipals.Count) + #Get duplicate users + $allUsers = (@($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.user'})) + if($allUsers.Count -gt 0){ + $myRole.activeAssignment.duplicateUsers = Get-MonkeyDuplicateObjectsByProperty -ReferenceObject $allUsers -Property Id + } + Else{ + #Set empty collection + $myRole.activeAssignment.duplicateUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + } + #> + } + Else{ + $myRole.activeAssignment.totalActiveMembers = 0; + $myRole.activeAssignment.duplicateUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + } + } + #Get eligible assignments + $msg = @{ + MessageData = "Getting eligible role assignments from PIM"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIDPIMInfo'); + } + Write-Information @msg + $eligibleRoleAssignments = Get-MonkeyMSGraphPIMEligibleRoleAssignment + #Group objects + $eligible_objects = $eligibleRoleAssignments | Group-Object -Property roleDefinitionId + foreach($eligibleRole in $eligible_objects){ + #Get the role + $myRole = $allroleAssignments.Where({$_.id -eq $eligibleRole.Name}) | Select-Object -First 1 + $msg = @{ + MessageData = ("Getting eligible role assignments for {0}" -f $myRole.Name); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIDPIMInfo'); + } + Write-Information @msg + #update object + $myRole.eligibleAssignment.isUsed = $true; + $myRole.roleInUse = $true; + $ids = $eligibleRole.Group | Select-Object -ExpandProperty principalId -ErrorAction Ignore + if($null -ne $ids){ + $identities = Get-MonkeyMSGraphDirectoryObjectById -Ids $ids + #Set array + $allMembers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + foreach($identity in @($identities)){ + [void]$allMembers.Add($identity) + } + #Get groups + $groups = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.group'}) + #get Real members + foreach($grp in $groups){ + $groupMember = Get-MonkeyMSGraphGroupTransitiveMember -GroupId $grp.id -Parents @($grp.id) + if($groupMember){ + foreach($member in $groupMember){ + [void]$allMembers.Add($member); + } + } + } + #Get effective users and remove duplicate members + $uniqueUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + $alluniqueUsers = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.user'}) | Sort-Object -Property Id -Unique -ErrorAction Ignore + if($null -ne $alluniqueUsers){ + foreach($usr in @($alluniqueUsers)){ + [void]$uniqueUsers.Add($usr); + } + } + #Get user's id + $allIds = $uniqueUsers | Select-Object -ExpandProperty Id -ErrorAction Ignore + #Invoke job + $members = $allIds | Invoke-MonkeyJob @jobParam + $extendedUniqueUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + if($null -ne $members){ + foreach($member in $members){ + [void]$extendedUniqueUsers.Add($member); + } + } + #Populate members + $myRole.eligibleAssignment.users = $extendedUniqueUsers; + #Get service principals + $servicePrincipals = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.servicePrincipal'}) + #Populate Service Principals + $myRole.eligibleAssignment.servicePrincipals = $servicePrincipals; + #Populate Groups + $myRole.eligibleAssignment.groups = $groups; + #Count objects + $myRole.eligibleAssignment.totalEligibleMembers = ($myRole.eligibleAssignment.users.Count + $myRole.eligibleAssignment.servicePrincipals.Count) + #Get duplicate users + $allUsers = (@($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.user'})) + if($allUsers.Count -gt 0){ + $myRole.eligibleAssignment.duplicateUsers = Get-MonkeyDuplicateObjectsByProperty -ReferenceObject $allUsers -Property Id + } + Else{ + #Set empty collection + $myRole.eligibleAssignment.duplicateUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + } + } + Else{ + $myRole.eligibleAssignment.totalEligibleMembers = 0; + $myRole.eligibleAssignment.duplicateUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + } + #Calculate eligible and active members + $myRole.totalMembers = $myRole.eligibleAssignment.totalEligibleMembers + $myRole.activeAssignment.totalActiveMembers + } + #return data + $allroleAssignments + } + Catch{ + $msg = @{ + MessageData = $_; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'verbose'; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + Tags = @('EntraIDPIMError'); + } + Write-Verbose @msg + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleManagementPolicy.ps1 b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleManagementPolicy.ps1 new file mode 100644 index 00000000..860efab9 --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleManagementPolicy.ps1 @@ -0,0 +1,103 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Get-MonkeyMSGraphPIMRoleManagementPolicy { + <# + .SYNOPSIS + Get the details of the policies in PIM that can be applied to Microsoft Entra roles or group membership or ownership + + .DESCRIPTION + Get the details of the policies in PIM that can be applied to Microsoft Entra roles or group membership or ownership + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphPIMRoleManagementPolicy + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding(DefaultParameterSetName = 'All')] + Param ( + [Parameter(Mandatory=$false, ParameterSetName = 'PolicyId', ValueFromPipeline = $True, HelpMessage="Policy Id")] + [String]$InputObject, + + [Parameter(Mandatory=$false, ParameterSetName = 'DirectoryRole', HelpMessage="Roles scoped to the tenant")] + [Switch]$DirectoryRole, + + [parameter(Mandatory=$false, HelpMessage="API version")] + [ValidateSet("v1.0","beta")] + [String]$APIVersion = "beta" + ) + Begin{ + $Environment = $O365Object.Environment + #Get Graph Auth + $graphAuth = $O365Object.auth_tokens.MSGraph + } + Process{ + if($PSCmdlet.ParameterSetName -eq 'PolicyId'){ + $p = @{ + Authentication = $graphAuth; + ObjectType = ('policies/roleManagementPolicies/{0}/rules' -f $PSBoundParameters['InputObject']); + Environment = $Environment; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + ElseIf($PSCmdlet.ParameterSetName -eq 'DirectoryRole'){ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'policies/roleManagementPolicies'; + Environment = $Environment; + Filter = "scopeId eq '/' and scopeType eq 'DirectoryRole'"; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + Else{ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'policies/roleManagementPolicies'; + Environment = $Environment; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + } + End{ + #Nothing to do here + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleManagementPolicyAssignment.ps1 b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleManagementPolicyAssignment.ps1 new file mode 100644 index 00000000..52da5d61 --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/PIM/Get-MonkeyMSGraphPIMRoleManagementPolicyAssignment.ps1 @@ -0,0 +1,68 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Get-MonkeyMSGraphPIMRoleManagementPolicyAssignment { + <# + .SYNOPSIS + Get the details of all role management policy assignments made in PIM for Microsoft Entra roles and PIM for groups. + + .DESCRIPTION + Get the details of all role management policy assignments made in PIM for Microsoft Entra roles and PIM for groups. + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphPIMRoleManagementPolicyAssignment + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding()] + Param ( + [parameter(Mandatory=$false, HelpMessage="API version")] + [ValidateSet("v1.0","beta")] + [String]$APIVersion = "beta" + ) + Begin{ + $Environment = $O365Object.Environment + #Get Graph Auth + $graphAuth = $O365Object.auth_tokens.MSGraph + } + Process{ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'policies/roleManagementPolicyAssignments'; + Environment = $Environment; + Filter = "scopeId eq '/' and scopeType eq 'DirectoryRole'"; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + End{ + #Nothing to do here + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphAADDirectoryRole.ps1 b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphAADDirectoryRole.ps1 deleted file mode 100644 index b0dc7ffa..00000000 --- a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphAADDirectoryRole.ps1 +++ /dev/null @@ -1,309 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -Function Get-MonkeyMSGraphAADDirectoryRole{ - <# - .SYNOPSIS - Get Azure AD directory role information - - .DESCRIPTION - Get Azure AD directory role information - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MonkeyMSGraphAADDirectoryRole - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Scope="Function")] - [CmdletBinding(DefaultParameterSetName = 'All')] - Param ( - [Parameter(Mandatory=$True, ParameterSetName = 'Role', HelpMessage="Role only")] - [Switch]$RoleOnly, - - [Parameter(Mandatory=$True, ParameterSetName = 'User', HelpMessage="User id")] - [String]$UserId, - - [parameter(Mandatory=$True, ParameterSetName = 'CurrentUser', HelpMessage="Current user")] - [Switch]$CurrentUser, - - [Parameter(Mandatory=$True, ParameterSetName = 'PrincipalId', HelpMessage="Principal Id")] - [String]$PrincipalId, - - [Parameter(Mandatory=$True, ParameterSetName = 'Group', HelpMessage="Group Id")] - [String]$GroupId, - - [parameter(Mandatory=$false, HelpMessage="API version")] - [ValidateSet("v1.0","beta")] - [String]$APIVersion = "v1.0" - ) - Begin{ - #Get Config - try{ - $aadConf = $O365Object.internal_config.entraId.provider.msgraph - } - catch{ - $msg = @{ - MessageData = ($message.MonkeyInternalConfigError); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'verbose'; - InformationAction = $O365Object.InformationAction; - Tags = @('Monkey365ConfigError'); - } - Write-Verbose @msg - throw ("[ConfigError] {0}: {1}" -f $message.MonkeyInternalConfigError,$_.Exception.Message) - } - #Get param for nested jobs - if($O365Object.useOldAADAPIForUsers){ - $jobParam = @{ - ScriptBlock = { Get-MonkeyGraphAADUser -UserId $_ }; - Runspacepool = $O365Object.monkey_runspacePool; - ReuseRunspacePool = $true; - Debug = $O365Object.VerboseOptions.Debug; - Verbose = $O365Object.VerboseOptions.Verbose; - MaxQueue = $O365Object.nestedRunspaces.MaxQueue; - BatchSleep = $O365Object.nestedRunspaces.BatchSleep; - BatchSize = $O365Object.nestedRunspaces.BatchSize; - } - } - else{ - $new_arg = @{ - APIVersion = $aadConf.api_version; - } - $jobParam = @{ - ScriptBlock = { Get-MonkeyMsGraphMFAUserDetail -User $_ }; - Arguments = $new_arg; - Runspacepool = $O365Object.monkey_runspacePool; - ReuseRunspacePool = $true; - Debug = $O365Object.VerboseOptions.Debug; - Verbose = $O365Object.VerboseOptions.Verbose; - MaxQueue = $O365Object.nestedRunspaces.MaxQueue; - BatchSleep = $O365Object.nestedRunspaces.BatchSleep; - BatchSize = $O365Object.nestedRunspaces.BatchSize; - } - } - } - Process{ - if($PSCmdlet.ParameterSetName -eq 'Role'){ - $p = @{ - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - Get-MonkeyMSGraphAADRoleAssignment @p - } - Elseif($PSCmdlet.ParameterSetName -eq 'UserId'){ - $msg = @{ - MessageData = ($message.RbacPermissionsMessage -f $UserId, "user"); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'info'; - InformationAction = $O365Object.InformationAction; - Tags = @('AzureRbacInfo'); - } - Write-Information @msg - $p = @{ - UserId = $UserId; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - Get-MonkeyMSGraphUserDirectoryRole @p - } - Elseif($PSCmdlet.ParameterSetName -eq 'CurrentUser'){ - if($O365Object.userId){ - $msg = @{ - MessageData = ($message.RbacPermissionsMessage -f $O365Object.userPrincipalName, "user"); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'info'; - InformationAction = $O365Object.InformationAction; - Tags = @('AzureRbacInfo'); - } - Write-Information @msg - $p = @{ - UserId = $O365Object.userId; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - Get-MonkeyMSGraphUserDirectoryRole @p - } - elseif($O365Object.isConfidentialApp){ - $msg = @{ - MessageData = ($message.RbacPermissionsMessage -f $O365Object.clientApplicationId, "client application"); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'info'; - InformationAction = $O365Object.InformationAction; - Tags = @('AzureRbacInfo'); - } - Write-Information @msg - $p = @{ - PrincipalId = $O365Object.clientApplicationId; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - Get-MonkeyMSGraphServicePrincipalDirectoryRole @p - } - } - Elseif($PSCmdlet.ParameterSetName -eq 'PrincipalId'){ - $msg = @{ - MessageData = ($message.RbacPermissionsMessage -f $PrincipalId, "Service principal"); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'info'; - InformationAction = $O365Object.InformationAction; - Tags = @('AzureRbacInfo'); - } - Write-Information @msg - $p = @{ - PrincipalId = $PrincipalId; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - Get-MonkeyMSGraphServicePrincipalDirectoryRole @p - } - Elseif($PSCmdlet.ParameterSetName -eq 'GroupId'){ - $msg = @{ - MessageData = ($message.RbacPermissionsMessage -f $GroupId, "Group"); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'info'; - InformationAction = $O365Object.InformationAction; - Tags = @('AzureRbacInfo'); - } - Write-Information @msg - $p = @{ - GroupId = $GroupId; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - Get-MonkeyMSGraphGroupDirectoryRoleMemberOf @p - } - Else{#All rbac permissions - try{ - $allRBAC = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() - #Get all RBAC info - $p = @{ - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - $role_assignments = Get-MonkeyMSGraphAADRoleAssignment @p | Group-Object roleDefinitionId - if($role_assignments){ - foreach ($ra in $role_assignments){ - $allmembers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() - #Get role assignment - $ra_info = $ra.Group.roleDefinition | Select-Object -Unique - #get Members - $members = $ra.Group.Principal - #Get groups - $grp = @($ra.Group.Principal).Where({$_.'@odata.type' -eq '#microsoft.graph.group'}) - #Get users - $usr = @($ra.Group.Principal).Where({$_.'@odata.type' -eq '#microsoft.graph.user'}) - #Check if check for MFA - if($O365Object.canRequestMFAForUsers){ - if($O365Object.useOldAADAPIForUsers){ - $usr = $usr | Select-Object -ExpandProperty Id - $member = $usr | Invoke-MonkeyJob @jobParam - } - else{ - $member = $usr | Invoke-MonkeyJob @jobParam - } - if($member){ - foreach($m in @($member)){ - [void]$allmembers.Add($m) - } - } - } - else{ - #Add members - $allmembers.AddRange($usr) - } - #Get service Principals - $sp = @($ra.Group.Principal).Where({$_.'@odata.type' -eq '#microsoft.graph.servicePrincipal'}) - #Add members - $allmembers.AddRange($sp) - #get Effective members - if($grp.Count -gt 0){ - foreach($group in $grp){ - #Get members - $p = @{ - GroupId = $group.id; - Parents = @(('{0}' -f $group.id)); - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - $members = Get-MonkeyMSGraphGroupTransitiveMember @p - if($members){ - #Check if check for MFA - if($O365Object.canRequestMFAForUsers){ - if($O365Object.useOldAADAPIForUsers){ - $members = $members | Select-Object -ExpandProperty Id - $all_members = $usr | Invoke-MonkeyJob @jobParam - } - else{ - $all_members = $members | Invoke-MonkeyJob @jobParam - } - if($all_members){ - foreach($m in $all_members){ - [void]$allmembers.Add($m) - } - } - } - else{ - foreach($member in $members){ - [void]$allmembers.Add($member) - } - } - } - } - } - #Populate Object - $ra_info | Add-Member -type NoteProperty -name users -value $usr -Force - $ra_info | Add-Member -type NoteProperty -name groups -value $grp -Force - $ra_info | Add-Member -type NoteProperty -name servicePrincipal -value $sp -Force - $ra_info | Add-Member -type NoteProperty -name effectiveMembers -value $allmembers -Force - $allRBAC.Add($ra_info); - } - } - Write-Output $allRBAC -NoEnumerate - } - catch{ - $msg = @{ - MessageData = ($_.Exception.Message); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'verbose'; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose - Tags = @('MonkeyMSGraphAADRBACError'); - } - Write-Verbose @msg - } - } - } - End{ - #Nothing to do here - } -} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphAADRoleAssignment.ps1 b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphAADRoleAssignment.ps1 deleted file mode 100644 index c4dc4161..00000000 --- a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphAADRoleAssignment.ps1 +++ /dev/null @@ -1,85 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MonkeyMSGraphAADRoleAssignment { - <# - .SYNOPSIS - Get Azure AD role assignment - - .DESCRIPTION - Get Azure AD role assignment - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MonkeyMSGraphAADRoleAssignment - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [CmdletBinding()] - Param ( - [parameter(ValueFromPipeline = $True,ValueFromPipeLineByPropertyName = $True)] - [ValidateSet("v1.0","beta")] - [String]$APIVersion = "v1.0" - ) - Begin{ - $Environment = $O365Object.Environment - #Get Graph Auth - $graphAuth = $O365Object.auth_tokens.MSGraph - } - Process{ - #Get Roles and expand the Principal attribute - $params = @{ - Authentication = $graphAuth; - ObjectType = "roleManagement/directory/roleAssignments"; - Environment = $Environment; - Expand = 'Principal'; - ContentType = 'application/json'; - Method = "GET"; - APIVersion = $APIVersion; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - $role_assignments = Get-MonkeyMSGraphObject @params - #Get Roles and expand the roleDefinition attribute - $params.Expand = 'roleDefinition'; - $role_definitions = Get-MonkeyMSGraphObject @params - #Populate all role definitions - if($role_assignments -and $role_definitions){ - foreach ($role in $role_assignments){ - $role_definition = $role_definitions | Where-Object {$_.id -eq $role.id} | Select-Object -ExpandProperty roleDefinition - if($null -ne $role_definition){ - $role | Add-Member -type NoteProperty -name roleDefinition -value $role_definition -Force - } - #Count principals - $role | Add-Member -type NoteProperty -name members -value (@($role.principal).Count) -Force - } - } - #Return role assignments - return $role_assignments - } - End{ - #Nothing to do here - } -} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphDirectoryRoleTemplate.ps1 b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphDirectoryRoleTemplate.ps1 new file mode 100644 index 00000000..3dc5b1fe --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphDirectoryRoleTemplate.ps1 @@ -0,0 +1,84 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Get-MonkeyMSGraphDirectoryRoleTemplate { + <# + .SYNOPSIS + Get the details of all role management policy assignments made in PIM for Microsoft Entra roles and PIM for groups. + + .DESCRIPTION + Get the details of all role management policy assignments made in PIM for Microsoft Entra roles and PIM for groups. + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphPIMRoleManagementPolicyAssignment + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding(DefaultParameterSetName = 'All')] + Param ( + [Parameter(Mandatory=$false, ParameterSetName = 'TemplateId', ValueFromPipeline = $True, HelpMessage="Template Id")] + [String]$InputObject, + + [parameter(Mandatory=$false, HelpMessage="API version")] + [ValidateSet("v1.0","beta")] + [String]$APIVersion = "v1.0" + ) + Begin{ + $Environment = $O365Object.Environment + #Get Graph Auth + $graphAuth = $O365Object.auth_tokens.MSGraph + } + Process{ + if($PSCmdlet.ParameterSetName -eq 'TemplateId'){ + $p = @{ + Authentication = $graphAuth; + ObjectType = ('directoryRoleTemplates/{0}' -f $PSBoundParameters['InputObject']); + Environment = $Environment; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + Else{ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'directoryRoleTemplates'; + Environment = $Environment; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + } + End{ + #Nothing to do here + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphEntraDirectoryRole.ps1 b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphEntraDirectoryRole.ps1 new file mode 100644 index 00000000..9c0d0c61 --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphEntraDirectoryRole.ps1 @@ -0,0 +1,181 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +Function Get-MonkeyMSGraphEntraDirectoryRole{ + <# + .SYNOPSIS + Get EntraID directory role information + + .DESCRIPTION + Get EntraID directory role information + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphEntraDirectoryRole + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Scope="Function")] + [CmdletBinding(DefaultParameterSetName = 'All')] + Param ( + [Parameter(Mandatory=$True, ParameterSetName = 'User', HelpMessage="User Id")] + [String]$UserId, + + [parameter(Mandatory=$True, ParameterSetName = 'CurrentUser', HelpMessage="Current user")] + [Switch]$CurrentUser, + + [Parameter(Mandatory=$True, ParameterSetName = 'PrincipalId', HelpMessage="Principal Id")] + [String]$PrincipalId, + + [Parameter(Mandatory=$True, ParameterSetName = 'Group', HelpMessage="Group Id")] + [String]$GroupId, + + [parameter(Mandatory=$false, HelpMessage="API version")] + [ValidateSet("v1.0","beta")] + [String]$APIVersion = "v1.0" + ) + Begin{ + #Get Config + try{ + $aadConf = $O365Object.internal_config.entraId.provider.msgraph + } + catch{ + $msg = @{ + MessageData = ($message.MonkeyInternalConfigError); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'verbose'; + InformationAction = $O365Object.InformationAction; + Tags = @('Monkey365ConfigError'); + } + Write-Verbose @msg + throw ("[ConfigError] {0}: {1}" -f $message.MonkeyInternalConfigError,$_.Exception.Message) + } + } + Process{ + If($PSCmdlet.ParameterSetName -eq 'UserId'){ + $msg = @{ + MessageData = ($message.RbacPermissionsMessage -f $UserId, "user"); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('MonkeyEntraIDRoleInfo'); + } + Write-Information @msg + $p = @{ + ObjectId = $UserId; + ObjectType = "user"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObjectDirectoryRole @p + } + ElseIf($PSCmdlet.ParameterSetName -eq 'PrincipalId'){ + $msg = @{ + MessageData = ($message.RbacPermissionsMessage -f $PrincipalId, "Service principal"); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('MonkeyEntraIDRoleInfo'); + } + Write-Information @msg + $p = @{ + ObjectId = $PrincipalId; + ObjectType = "servicePrincipal"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObjectDirectoryRole @p + } + Elseif($PSCmdlet.ParameterSetName -eq 'GroupId'){ + $msg = @{ + MessageData = ($message.RbacPermissionsMessage -f $GroupId, "Group"); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('MonkeyEntraIDRoleInfo'); + } + Write-Information @msg + $p = @{ + GroupId = $GroupId; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphGroupDirectoryRoleMemberOf @p + } + Elseif($PSCmdlet.ParameterSetName -eq 'CurrentUser'){ + $objectType = $objectId = $null; + if($O365Object.userId){ + $msg = @{ + MessageData = ($message.RbacPermissionsMessage -f $O365Object.userPrincipalName, "user"); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('MonkeyEntraIDRoleInfo'); + } + Write-Information @msg + $objectType = "user"; + $objectId = $O365Object.userId; + } + ElseIf($O365Object.isConfidentialApp){ + $msg = @{ + MessageData = ($message.RbacPermissionsMessage -f $O365Object.clientApplicationId, "client application"); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('MonkeyEntraIDRoleInfo'); + } + Write-Information @msg + $objectType = "servicePrincipal"; + $objectId = $O365Object.clientApplicationId; + } + Else{ + $objectType = $null; + } + If($null -ne $objectType -and $null -ne $objectId){ + $p = @{ + ObjectId = $objectId; + ObjectType = $objectType; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObjectDirectoryRole @p + } + } + Else{#All members + $p = @{ + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphEntraRoleAssignment @p + } + } + End{ + #Nothing to do here + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphEntraRoleAssignment.ps1 b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphEntraRoleAssignment.ps1 new file mode 100644 index 00000000..ef2eeb14 --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphEntraRoleAssignment.ps1 @@ -0,0 +1,228 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Get-MonkeyMSGraphEntraRoleAssignment { + <# + .SYNOPSIS + Get Entra ID role assignment + + .DESCRIPTION + Get Entra ID role assignment + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphEntraRoleAssignment + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding()] + Param ( + [parameter(ValueFromPipeline = $True,ValueFromPipeLineByPropertyName = $True)] + [ValidateSet("v1.0","beta")] + [String]$APIVersion = "v1.0" + ) + Begin{ + #Set generic list + $allEntraIDRoleAssignment = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + #Set nulls + $role_assignments = $role_definitions = $null; + $Environment = $O365Object.Environment + #Get Graph Auth + $graphAuth = $O365Object.auth_tokens.MSGraph + #Set Job params + If($O365Object.isConfidentialApp){ + $jobParam = @{ + ScriptBlock = { Get-MonkeyMsGraphMFAUserDetail -UserId $_ -APIVersion 'beta'}; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + } + Else{ + If($O365Object.useOldAADAPIForUsers){ + If($O365Object.canRequestMFAForUsers){ + $jobParam = @{ + ScriptBlock = { Get-MonkeyGraphAADUser -UserId $_ }; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + } + Else{ + #Set job params + $jobParam = @{ + ScriptBlock = { Get-MonkeyMSGraphUser -UserId $_ -BypassMFACheck -APIVersion 'beta' }; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + } + } + Else{ + If($O365Object.auth_tokens.MSGraph.clientId -eq (Get-WellKnownAzureService -AzureService MicrosoftGraph)){ + #Set job params + $jobParam = @{ + ScriptBlock = { Get-MonkeyMsGraphMFAUserDetail -UserId $_ -APIVersion 'beta'}; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + } + Else{ + #Set job params + $jobParam = @{ + ScriptBlock = { Get-MonkeyMSGraphUser -UserId $_ -BypassMFACheck -APIVersion 'beta' }; + Runspacepool = $O365Object.monkey_runspacePool; + ReuseRunspacePool = $true; + Debug = $O365Object.VerboseOptions.Debug; + Verbose = $O365Object.VerboseOptions.Verbose; + MaxQueue = $O365Object.nestedRunspaces.MaxQueue; + BatchSleep = $O365Object.nestedRunspaces.BatchSleep; + BatchSize = $O365Object.nestedRunspaces.BatchSize; + } + } + } + } + } + Process{ + $p = @{ + Authentication = $graphAuth; + ObjectType = "roleManagement/directory/roleAssignments"; + Environment = $Environment; + Expand = 'Principal'; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = "v1.0"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $role_assignments = Get-MonkeyMSGraphObject @p + #Get Roles and expand the roleDefinition attribute + $p.Expand = 'roleDefinition'; + $role_definitions = Get-MonkeyMSGraphObject @p + } + End{ + Try{ + If($null -ne $role_assignments -and $null -ne $role_definitions){ + $groupAssignments = $role_assignments | Group-Object -Property roleDefinitionId + foreach($assignment in $groupAssignments){ + $roleAssignment = $role_definitions.Where({$_.roleDefinitionId -eq $assignment.Name},'First') + $roleObject = $roleAssignment | New-MonkeyEntraIDRoleObject + #get Members + $allMembers = $assignment.Group.principal + #Get users + $roleObject.users = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.user'}) + #Get groups + $roleObject.groups = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.group'}) + #Get users + $users = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.user'}) + #Check for group members + If($null -ne $roleObject.groups){ + #get Real members + foreach($grp in $roleObject.groups){ + $groupMember = Get-MonkeyMSGraphGroupTransitiveMember -GroupId $grp.id -Parents @($grp.id) -APIVersion beta + if($groupMember){ + foreach($member in $groupMember){ + [void]$users.Add($member); + } + } + } + } + #Get effective users and remove duplicate members + $uniqueUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + $alluniqueUsers = @($users).Where({$_.'@odata.type' -match '#microsoft.graph.user'}) | Sort-Object -Property Id -Unique -ErrorAction Ignore + if($null -ne $alluniqueUsers){ + foreach($usr in @($alluniqueUsers)){ + [void]$uniqueUsers.Add($usr); + } + } + #Get user's id + $allIds = $uniqueUsers | Select-Object -ExpandProperty Id -ErrorAction Ignore + #Invoke job + $members = $allIds | Invoke-MonkeyJob @jobParam + $extendedUniqueUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + if($null -ne $members){ + foreach($member in $members){ + [void]$extendedUniqueUsers.Add($member); + } + } + $roleObject.effectiveUsers = $extendedUniqueUsers; + #Get servicePrincipals + $servicePrincipals = @($allMembers).Where({$_.'@odata.type' -match '#microsoft.graph.servicePrincipal'}) + #Check if transitive members had service principals + $transitiveSps = @($users).Where({$_.'@odata.type' -match '#microsoft.graph.servicePrincipal'}) + foreach($sp in $transitiveSps){ + [void]$servicePrincipals.Add($sp) + } + #Add Serviceprincipals to object + $roleObject.servicePrincipals = $servicePrincipals; + #Count objects + if($null -ne $roleObject.effectiveUsers){ + $roleObject.totalActiveusers = $roleObject.effectiveUsers.Count + } + Else{ + $roleObject.totalActiveusers = 0; + } + #Get duplicate users + $allUsers = (@($users).Where({$_.'@odata.type' -match '#microsoft.graph.user'})) + if($allUsers.Count -gt 0){ + $roleObject.duplicateUsers = Get-MonkeyDuplicateObjectsByProperty -ReferenceObject $allUsers -Property Id + } + Else{ + #Set empty collection + $roleObject.duplicateUsers = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + } + #Add effectiveMembers to object + $roleObject.effectiveMembers = $roleObject.servicePrincipals + $roleObject.effectiveUsers; + #Count objects + $roleObject.totalActiveMembers = ($roleObject.servicePrincipals.Count + $roleObject.effectiveUsers.Count) + #Add to list + [void]$allEntraIDRoleAssignment.Add($roleObject) + } + } + Write-Output $allEntraIDRoleAssignment -NoEnumerate + } + Catch{ + Write-Error $_ + return , $allEntraIDRoleAssignment + } + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphUserDirectoryRole.ps1 b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphObjectDirectoryRole.ps1 similarity index 52% rename from core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphUserDirectoryRole.ps1 rename to core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphObjectDirectoryRole.ps1 index 85fd0b63..d20ef774 100644 --- a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphUserDirectoryRole.ps1 +++ b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphObjectDirectoryRole.ps1 @@ -13,13 +13,13 @@ # limitations under the License. -Function Get-MonkeyMSGraphUserDirectoryRole{ +Function Get-MonkeyMSGraphObjectDirectoryRole{ <# .SYNOPSIS - Get User directory role + Get user or service principal directory role .DESCRIPTION - Get User directory role + Get user or service principal directory role .INPUTS @@ -30,7 +30,7 @@ Function Get-MonkeyMSGraphUserDirectoryRole{ .NOTES Author : Juan Garrido Twitter : @tr1ana - File Name : Get-MonkeyMSGraphUserDirectoryRole + File Name : Get-MonkeyMSGraphObjectDirectoryRole Version : 1.0 .LINK @@ -38,49 +38,61 @@ Function Get-MonkeyMSGraphUserDirectoryRole{ #> [CmdletBinding()] Param ( - [Parameter(Mandatory=$true, HelpMessage="User Id")] - [string]$UserId, + [Parameter(Mandatory=$true, HelpMessage="Object Id")] + [string]$ObjectId, + + [parameter(Mandatory=$false)] + [ValidateSet("user","servicePrincipal")] + [String]$ObjectType = "user", [parameter(Mandatory=$false)] [ValidateSet("v1.0","beta")] [String]$APIVersion = "v1.0" ) try{ - #Import Localized data - $LocalizedDataParams = $O365Object.LocalizedDataParams - Import-LocalizedData @LocalizedDataParams; + $myObjectType = $null; $Environment = $O365Object.Environment #Get Graph Auth $graphAuth = $O365Object.auth_tokens.MSGraph $msg = @{ - MessageData = ($message.ObjectIdMessageInfo -f "user's", $UserId); + MessageData = ($message.ObjectIdMessageInfo -f "object's", $ObjectId); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'verbose'; InformationAction = $O365Object.InformationAction; - Tags = @('AzureGraphDirectoryRoleByUserId'); + Tags = @('AzureMSGraphDirectoryRoleByObjectId'); } Write-Verbose @msg - $objectType = ('users/{0}/transitiveMemberOf' -f $UserId) - $params = @{ - Authentication = $graphAuth; - ObjectType = $objectType; - Environment = $Environment; - ContentType = 'application/json'; - Method = "GET"; - APIVersion = $APIVersion; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; + #Check ObjectType + Switch($ObjectType.ToLower()){ + 'user'{ + $myObjectType = ('users/{0}/transitiveMemberOf' -f $ObjectId) + } + 'servicePrincipal'{ + $myObjectType = ('servicePrincipals/{0}/transitiveMemberOf' -f $ObjectId) + } + } + if($null -ne $myObjectType){ + $p = @{ + Authentication = $graphAuth; + ObjectType = $myObjectType; + Environment = $Environment; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p | Where-Object {$_.'@odata.type' -eq '#microsoft.graph.directoryRole'} } - Get-MonkeyMSGraphObject @params | Where-Object {$_.'@odata.type' -eq '#microsoft.graph.directoryRole'} } catch{ $msg = @{ - MessageData = ("Unable to get user's directory role information from id {0}" -f $UserId); + MessageData = ("Unable to get object's directory role information from id {0}" -f $ObjectId); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'warning'; InformationAction = $O365Object.InformationAction; - Tags = @('AzureGraphDirectoryRole'); + Tags = @('AzureMSGraphObjectDirectoryRoleError'); } Write-Warning @msg #Set verbose diff --git a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphServicePrincipalDirectoryRole.ps1 b/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphServicePrincipalDirectoryRole.ps1 deleted file mode 100644 index 5a0ffebc..00000000 --- a/core/api/EntraID/msgraph/helpers/directoryrole/Get-MonkeyMSGraphServicePrincipalDirectoryRole.ps1 +++ /dev/null @@ -1,91 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -Function Get-MonkeyMSGraphServicePrincipalDirectoryRole{ - <# - .SYNOPSIS - Get User directory role - - .DESCRIPTION - Get User directory role - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MonkeyMSGraphServicePrincipalDirectoryRole - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [cmdletbinding()] - Param ( - [Parameter(Mandatory=$true, HelpMessage="Principal Id")] - [String]$principalId, - - [parameter(Mandatory=$false)] - [ValidateSet("v1.0","beta")] - [String]$APIVersion = "v1.0" - ) - try{ - $Environment = $O365Object.Environment - #Get Graph Auth - $graphAuth = $O365Object.auth_tokens.MSGraph - $msg = @{ - MessageData = ($message.ObjectIdMessageInfo -f "user's", $principalId); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'verbose'; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Tags = @('AzureGraphDirectoryRoleByApplicationId'); - } - Write-Verbose @msg - $objectType = ('servicePrincipals/{0}/transitiveMemberOf' -f $principalId) - $params = @{ - Authentication = $graphAuth; - ObjectType = $objectType; - Environment = $Environment; - ContentType = 'application/json'; - Method = "GET"; - APIVersion = $APIVersion; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - Get-MonkeyMSGraphObject @params | Where-Object {$_.'@odata.type' -eq '#microsoft.graph.directoryRole'} - } - catch{ - $msg = @{ - MessageData = ("Unable to get servicePrincipal's directory role information from id {0}" -f $principalId); - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'warning'; - InformationAction = $O365Object.InformationAction; - Tags = @('AzureGraphSPDirectoryRole'); - } - Write-Warning @msg - #Set verbose - $msg.MessageData = $_ - $msg.logLevel = 'Verbose' - [void]$msg.Add('verbose',$O365Object.verbose) - Write-Verbose @msg - } -} diff --git a/core/api/EntraID/msgraph/helpers/external identity/Get-MonkeyMSGraphcrossTenantAccessPolicy.ps1 b/core/api/EntraID/msgraph/helpers/external identity/Get-MonkeyMSGraphcrossTenantAccessPolicy.ps1 index 7b602597..41e63a02 100644 --- a/core/api/EntraID/msgraph/helpers/external identity/Get-MonkeyMSGraphcrossTenantAccessPolicy.ps1 +++ b/core/api/EntraID/msgraph/helpers/external identity/Get-MonkeyMSGraphcrossTenantAccessPolicy.ps1 @@ -36,8 +36,14 @@ Function Get-MonkeyMSGraphcrossTenantAccessPolicy { https://github.com/silverhack/monkey365 #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Scope="Function")] - [CmdletBinding()] + [CmdletBinding(DefaultParameterSetName = 'Basic')] Param ( + [parameter(Mandatory=$false, ParameterSetName = 'Default', HelpMessage="API version")] + [Switch]$Default, + + [parameter(Mandatory=$false, ParameterSetName = 'Partner', HelpMessage="API version")] + [Switch]$Partner, + [parameter(Mandatory=$false, HelpMessage="API version")] [ValidateSet("v1.0","beta")] [String]$APIVersion = "v1.0" @@ -49,36 +55,66 @@ Function Get-MonkeyMSGraphcrossTenantAccessPolicy { } Process{ try{ - $p = @{ - Authentication = $graphAuth; - ObjectType = 'policies/crossTenantAccessPolicy/partners'; - Environment = $Environment; - ContentType = 'application/json'; - Method = "GET"; - APIVersion = "beta"; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - $partners = Get-MonkeyMSGraphObject @p - if($null -ne $partners){ - foreach($partner in @($partners)){ - $p = @{ - TenantId = $partner.TenantId; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - } - $tenantInfo = Find-MonkeyMSGraphTenantInformationByTenantId @p - if($null -ne $tenantInfo){ - $partner | Add-Member -type NoteProperty -name federationBrandName -value $tenantInfo.federationBrandName -Force - $partner | Add-Member -type NoteProperty -name displayName -value $tenantInfo.displayName -Force - $partner | Add-Member -type NoteProperty -name defaultDomainName -value $tenantInfo.defaultDomainName -Force + if($PSCmdlet.ParameterSetName -eq 'Partner'){ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'policies/crossTenantAccessPolicy/partners'; + Environment = $Environment; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = "beta"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $partners = Get-MonkeyMSGraphObject @p + if($null -ne $partners){ + foreach($partner in @($partners)){ + $p = @{ + TenantId = $partner.TenantId; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $tenantInfo = Find-MonkeyMSGraphTenantInformationByTenantId @p + if($null -ne $tenantInfo){ + $partner | Add-Member -type NoteProperty -name federationBrandName -value $tenantInfo.federationBrandName -Force + $partner | Add-Member -type NoteProperty -name displayName -value $tenantInfo.displayName -Force + $partner | Add-Member -type NoteProperty -name defaultDomainName -value $tenantInfo.defaultDomainName -Force + } + Start-Sleep -Milliseconds 200 } - Start-Sleep -Milliseconds 200 + #return partners + return $partners + } + } + ElseIf($PSCmdlet.ParameterSetName -eq 'Default'){ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'policies/crossTenantAccessPolicy/default'; + Environment = $Environment; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = "beta"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + Else{ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'policies/crossTenantAccessPolicy'; + Environment = $Environment; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = "beta"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; } - #return partners - return $partners + Get-MonkeyMSGraphObject @p } } catch{ diff --git a/core/api/EntraID/msgraph/helpers/groups/Get-MonkeyMSGraphGroupMember.ps1 b/core/api/EntraID/msgraph/helpers/groups/Get-MonkeyMSGraphGroupMember.ps1 index 430c78c4..2f423a80 100644 --- a/core/api/EntraID/msgraph/helpers/groups/Get-MonkeyMSGraphGroupMember.ps1 +++ b/core/api/EntraID/msgraph/helpers/groups/Get-MonkeyMSGraphGroupMember.ps1 @@ -49,9 +49,6 @@ Function Get-MonkeyMSGraphGroupMember{ [String]$APIVersion = "v1.0" ) Begin{ - #Import Localized data - $LocalizedDataParams = $O365Object.LocalizedDataParams - Import-LocalizedData @LocalizedDataParams; $Environment = $O365Object.Environment #Get Graph Auth $graphAuth = $O365Object.auth_tokens.MSGraph @@ -97,10 +94,7 @@ Function Get-MonkeyMSGraphGroupMember{ $group_members = Get-MonkeyMSGraphObject @params if($group_members){ foreach($member in $group_members){ - if($member.'@odata.type' -eq "#microsoft.graph.user"){ - $member - } - elseif($member.'@odata.type' -eq "#microsoft.graph.group"){ + If($member.'@odata.type' -eq "#microsoft.graph.group"){ if($member.id -notin $Parents){ $Parents +=$member.id $p = @{ @@ -125,6 +119,9 @@ Function Get-MonkeyMSGraphGroupMember{ Write-Debug @msg } } + Else{ + $member + } } } } diff --git a/core/api/EntraID/msgraph/helpers/groups/Get-MonkeyMSGraphGroupTransitiveMember.ps1 b/core/api/EntraID/msgraph/helpers/groups/Get-MonkeyMSGraphGroupTransitiveMember.ps1 index a6caee85..57279f34 100644 --- a/core/api/EntraID/msgraph/helpers/groups/Get-MonkeyMSGraphGroupTransitiveMember.ps1 +++ b/core/api/EntraID/msgraph/helpers/groups/Get-MonkeyMSGraphGroupTransitiveMember.ps1 @@ -79,13 +79,7 @@ Function Get-MonkeyMSGraphGroupTransitiveMember{ $group_members = Get-MonkeyMSGraphObject @params if($group_members){ foreach($member in $group_members){ - if($member.'@odata.type' -eq "#microsoft.graph.user"){ - $member - } - elseif($member.'@odata.type' -eq "#microsoft.graph.directoryRole"){ - $member - } - elseif($member.'@odata.type' -eq "#microsoft.graph.group"){ + If($member.'@odata.type' -eq "#microsoft.graph.group"){ if($member.id -notin $Parents){ $Parents +=$member.id $p = @{ @@ -97,7 +91,7 @@ Function Get-MonkeyMSGraphGroupTransitiveMember{ } Get-MonkeyMSGraphGroupTransitiveMember @p } - else{ + Else{ $msg = @{ MessageData = ($message.PotentialNestedGroupMessage -f $member.displayName, $GroupId); callStack = (Get-PSCallStack | Select-Object -First 1); @@ -109,6 +103,9 @@ Function Get-MonkeyMSGraphGroupTransitiveMember{ Write-Verbose @msg } } + Else{ + $member + } } } } diff --git a/core/api/EntraID/msgraph/helpers/identity/Get-MonkeyMSGraphIdentityProtectionNotification.ps1 b/core/api/EntraID/msgraph/helpers/identity/Get-MonkeyMSGraphIdentityProtectionNotification.ps1 new file mode 100644 index 00000000..261f1bc4 --- /dev/null +++ b/core/api/EntraID/msgraph/helpers/identity/Get-MonkeyMSGraphIdentityProtectionNotification.ps1 @@ -0,0 +1,67 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Get-MonkeyMSGraphIdentityProtectionNotification { + <# + .SYNOPSIS + Get configuration for detected alerts and recipient emails + + .DESCRIPTION + Get configuration for detected alerts and recipient emails + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyMSGraphIdentityProtectionNotification + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [CmdletBinding()] + Param ( + [parameter(Mandatory=$false, HelpMessage="API version")] + [ValidateSet("v1.0","beta")] + [String]$APIVersion = "v1.0" + ) + Begin{ + $Environment = $O365Object.Environment + #Get Graph Auth + $graphAuth = $O365Object.auth_tokens.MSGraph + } + Process{ + $p = @{ + Authentication = $graphAuth; + ObjectType = 'identityProtection/settings/notifications'; + Environment = $Environment; + ContentType = 'application/json'; + Method = "GET"; + APIVersion = $APIVersion; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + Get-MonkeyMSGraphObject @p + } + End{ + #Nothing to do here + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/utils/New-MonkeyEntraExternalCollaborationObject.ps1 b/core/api/EntraID/msgraph/utils/New-MonkeyEntraExternalCollaborationObject.ps1 new file mode 100644 index 00000000..6beba57e --- /dev/null +++ b/core/api/EntraID/msgraph/utils/New-MonkeyEntraExternalCollaborationObject.ps1 @@ -0,0 +1,71 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function New-MonkeyEntraCrossTenantAccessPolicyObject { +<# + .SYNOPSIS + Create a new Entra ID cross-tenant access policy object + + .DESCRIPTION + Create a new Entra ID cross-tenant access policy object + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : New-MonkeyEntraCrossTenantAccessPolicyObject + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Scope="Function")] + [CmdletBinding()] + Param () + Process{ + try{ + #Create ordered dictionary + $crossTenantObj = [ordered]@{ + crossTenantAccessPolicy = $null; + defaultCrossTenantAccessPolicy = $null; + partnerCrossTenantAccessPolicy = $null; + } + #Create PsObject + $_obj = New-Object -TypeName PsObject -Property $crossTenantObj + #return object + return $_obj + } + catch{ + $msg = @{ + MessageData = ($message.MonkeyObjectCreationFailed -f "Entra Id cross-tenant access policy object"); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'error'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIdCrossTenantPolicyObjectError'); + } + Write-Error @msg + $msg.MessageData = $_ + $msg.LogLevel = "Verbose" + $msg.Tags+= "EntraIdCrossTenantPolicyObjectError" + [void]$msg.Add('verbose',$O365Object.verbose) + Write-Verbose @msg + } + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/utils/New-MonkeyEntraIDRoleObject.ps1 b/core/api/EntraID/msgraph/utils/New-MonkeyEntraIDRoleObject.ps1 new file mode 100644 index 00000000..c26f7854 --- /dev/null +++ b/core/api/EntraID/msgraph/utils/New-MonkeyEntraIDRoleObject.ps1 @@ -0,0 +1,89 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function New-MonkeyEntraIDRoleObject { +<# + .SYNOPSIS + Create a new Entra ID role object + + .DESCRIPTION + Create a new Entra ID role object + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : New-MonkeyEntraIDRoleObject + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Scope="Function")] + [CmdletBinding()] + Param ( + [parameter(Mandatory= $True, ValueFromPipeline = $True, HelpMessage="Entra ID role assignment object")] + [Object]$InputObject + ) + Process{ + try{ + #Create ordered dictionary + $EntraIdRoleObject = [ordered]@{ + id = $InputObject.roleDefinition.Id; + name = $InputObject.roleDefinition.displayName; + displayName = $InputObject.roleDefinition.displayName; + description = $InputObject.roleDefinition.description; + isBuiltIn = $InputObject.roleDefinition.isBuiltIn; + isEnabled = $InputObject.roleDefinition.isEnabled; + resourceScopes = $InputObject.roleDefinition.resourceScopes; + templateId = $InputObject.roleDefinition.templateId; + version = $InputObject.roleDefinition.version; + rolePermissions = $InputObject.roleDefinition.rolePermissions; + users = $null; + groups = $null; + servicePrincipals = $null; + effectiveMembers = $null; + effectiveUsers = $null; + duplicateUsers = $null; + totalActiveusers = $null; + totalActiveMembers = $null; + } + #Create PsObject + $_obj = New-Object -TypeName PsObject -Property $EntraIdRoleObject + #return object + return $_obj + } + catch{ + $msg = @{ + MessageData = ($message.MonkeyObjectCreationFailed -f "Entra ID role object"); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'error'; + InformationAction = $O365Object.InformationAction; + Tags = @('EntraIDRoleObjectError'); + } + Write-Error @msg + $msg.MessageData = $_ + $msg.LogLevel = "Verbose" + $msg.Tags+= "EntraIDRoleObjectError" + [void]$msg.Add('verbose',$O365Object.verbose) + Write-Verbose @msg + } + } +} \ No newline at end of file diff --git a/core/api/EntraID/msgraph/utils/New-MonkeyPIMRoleObject.ps1 b/core/api/EntraID/msgraph/utils/New-MonkeyPIMRoleObject.ps1 new file mode 100644 index 00000000..46326037 --- /dev/null +++ b/core/api/EntraID/msgraph/utils/New-MonkeyPIMRoleObject.ps1 @@ -0,0 +1,96 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function New-MonkeyPIMRoleObject { +<# + .SYNOPSIS + Create a new PIM role object + + .DESCRIPTION + Create a new PIM role object + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : New-MonkeyPIMRoleObject + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Scope="Function")] + [CmdletBinding()] + Param ( + [parameter(Mandatory= $True, ValueFromPipeline = $True, HelpMessage="PIM role object")] + [Object]$InputObject + ) + Process{ + try{ + #Create ordered dictionary + $PIMObject = [ordered]@{ + id = $InputObject.Id; + templateId = $InputObject.Id; + name = $InputObject.displayName; + displayName = $InputObject.displayName; + description = $InputObject.description; + deletedDateTime = $InputObject.deletedDateTime; + policy = $null; + roleInUse = $false; + activeAssignment = [PsCustomObject]@{ + users = $null; + groups = $null; + servicePrincipals = $null; + isUsed = $false; + duplicateUsers = $null; + totalActiveMembers = $null; + } + eligibleAssignment = [PsCustomObject]@{ + users = $null; + groups = $null; + servicePrincipals = $null; + isUsed = $false; + duplicateUsers = $null; + totalEligibleMembers = $null; + } + totalMembers = $null; + } + #Create PsObject + $_obj = New-Object -TypeName PsObject -Property $PIMObject + #return object + return $_obj + } + catch{ + $msg = @{ + MessageData = ($message.MonkeyObjectCreationFailed -f "PIM role object"); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'error'; + InformationAction = $O365Object.InformationAction; + Tags = @('PIMObjectError'); + } + Write-Error @msg + $msg.MessageData = $_ + $msg.LogLevel = "Verbose" + $msg.Tags+= "PIMObjectError" + [void]$msg.Add('verbose',$O365Object.verbose) + Write-Verbose @msg + } + } +} \ No newline at end of file diff --git a/core/api/EntraID/pim/Get-MonkeyMSPIMObject.ps1 b/core/api/EntraID/pim/Get-MonkeyMSPIMObject.ps1 index 9e097f83..2bf190e5 100644 --- a/core/api/EntraID/pim/Get-MonkeyMSPIMObject.ps1 +++ b/core/api/EntraID/pim/Get-MonkeyMSPIMObject.ps1 @@ -135,7 +135,14 @@ Function Get-MonkeyMSPIMObject{ break } #Get Authorization Header - $AuthHeader = $Authentication.CreateAuthorizationHeader() + $methods = $Authentication | Get-Member | Where-Object {$_.MemberType -eq 'Method'} | Select-Object -ExpandProperty Name + #Get Authorization Header + if($null -ne $methods -and $methods.Contains('CreateAuthorizationHeader')){ + $AuthHeader = $Authentication.CreateAuthorizationHeader() + } + else{ + $AuthHeader = ("Bearer {0}" -f $Authentication.AccessToken) + } #set msgraph uri $base_uri = ("/api/{0}" -f $APIVersion) #Get internal Path diff --git a/core/api/auth/Connect-MonkeyCloud.ps1 b/core/api/auth/Connect-MonkeyCloud.ps1 index 80e56a7d..2ccac5de 100644 --- a/core/api/auth/Connect-MonkeyCloud.ps1 +++ b/core/api/auth/Connect-MonkeyCloud.ps1 @@ -39,6 +39,14 @@ Function Connect-MonkeyCloud{ #Using MSAL authentication if($null -ne $O365Object.msal_application_args){ #Connect to MSGraph + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Microsoft Graph V2") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg $O365Object.auth_tokens.MSGraph = Connect-MonkeyMSGraph if($null -ne $O365Object.auth_tokens.MSGraph){ #Check if valid TenantId @@ -91,8 +99,23 @@ Function Connect-MonkeyCloud{ #Probably cancelled connection return } + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Azure Resource Management API") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg #Connect to Resource management - $O365Object.auth_tokens.ResourceManager = Connect-MonkeyResourceManagement + $p = @{ + Resource = $O365Object.Environment.ResourceManager; + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.ResourceManager = Connect-MonkeyGenericApplication @p } #Select tenant if($null -eq $O365Object.TenantId -and $null -ne $O365Object.auth_tokens.ResourceManager){ @@ -113,14 +136,43 @@ Function Connect-MonkeyCloud{ $O365Object.AuthType = $O365Object.auth_tokens.Values.GetEnumerator() | Select-Object -ExpandProperty AuthType -Unique -ErrorAction Ignore #Check if connected to MSGraph and Resource Manager if($null -ne $O365Object.auth_tokens.ResourceManager -and $null -ne $O365Object.auth_tokens.MSGraph){ - #Connect to Microsoft old Graph - $O365Object.auth_tokens.Graph = Connect-MonkeyGraph + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Legacy Microsoft Graph") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg + #Connect to Microsoft legacy Graph + $p = @{ + Resource = $O365Object.Environment.Graph; + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.Graph = Connect-MonkeyGenericApplication @p #Connect to Azure Portal - if($O365Object.isConfidentialApp -eq $false){ - $O365Object.auth_tokens.AzurePortal = Connect-MonkeyAzurePortal + if($O365Object.isConfidentialApp -eq $false -and $O365Object.IncludeEntraID){ + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Entra ID API") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg + $p = @{ + Resource = (Get-WellKnownAzureService -AzureService AzurePortal); + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.AzurePortal = Connect-MonkeyGenericApplication @p + #$O365Object.auth_tokens.AzurePortal = Connect-MonkeyAzurePortal } - #Connect to PIM - $O365Object.auth_tokens.MSPIM = Connect-MonkeyPIM #Get Tenant Information $O365Object.Tenant = Get-TenantInformation } @@ -149,13 +201,13 @@ Function Connect-MonkeyCloud{ } #Get Azure AD permissions if($O365Object.isConfidentialApp){ - $user_permissions = Get-MonkeyMSGraphServicePrincipalDirectoryRole -principalId $O365Object.clientApplicationId - if($user_permissions){ - $O365Object.aadPermissions = $user_permissions + $app_Permissions = Get-MonkeyMSGraphObjectDirectoryRole -ObjectId $O365Object.clientApplicationId -ObjectType servicePrincipal + if($app_Permissions){ + $O365Object.aadPermissions = $app_Permissions } } else{ - $user_permissions = Get-MonkeyMSGraphUserDirectoryRole -UserId $O365Object.userId + $user_permissions = Get-MonkeyMSGraphObjectDirectoryRole -ObjectId $O365Object.userId -ObjectType user if($user_permissions){ $O365Object.aadPermissions = $user_permissions } @@ -223,6 +275,26 @@ Function Connect-MonkeyCloud{ } #Get AzureAD Licensing $O365Object.AADLicense = Get-M365AADLicense + if($null -ne $O365Object.AADLicense.azureADP2){ + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Entra ID Privileged Managament Identity API") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg + #Connect to PIM + $p = @{ + Resource = (Get-WellKnownAzureService -AzureService MSPIM); + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.MSPIM = Connect-MonkeyGenericApplication @p + #$O365Object.auth_tokens.MSPIM = Connect-MonkeyPIM + } #Get collectors $O365Object.Collectors = Get-MonkeyCollector } \ No newline at end of file diff --git a/core/api/auth/Forms/Connect-MonkeyFormsForOffice.ps1 b/core/api/auth/Forms/Connect-MonkeyFormsForOffice.ps1 deleted file mode 100644 index e6df3de5..00000000 --- a/core/api/auth/Forms/Connect-MonkeyFormsForOffice.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyFormsForOffice { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyFormsForOffice - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args){ - $p = $O365Object.msal_application_args; - Get-MSALTokenForForms @p - } -} diff --git a/core/api/auth/Teams/Connect-MonkeyTeamsForOffice.ps1 b/core/api/auth/Teams/Connect-MonkeyTeamsForOffice.ps1 deleted file mode 100644 index 2b953455..00000000 --- a/core/api/auth/Teams/Connect-MonkeyTeamsForOffice.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyTeamsForOffice { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyTeamsForOffice - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args){ - $p = $O365Object.msal_application_args; - Get-MSALTokenForTeams @p - } -} diff --git a/core/api/auth/aadrm/Connect-MonkeyAADRM.ps1 b/core/api/auth/aadrm/Connect-MonkeyAADRM.ps1 deleted file mode 100644 index da94a32a..00000000 --- a/core/api/auth/aadrm/Connect-MonkeyAADRM.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyAADRM { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyAADRM - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args){ - $p = $O365Object.msal_application_args; - Get-MsalTokenForAADRM @p - } -} diff --git a/core/api/auth/azueraad/Connect-MonkeyAzurePortal.ps1 b/core/api/auth/azueraad/Connect-MonkeyAzurePortal.ps1 deleted file mode 100644 index a74486f4..00000000 --- a/core/api/auth/azueraad/Connect-MonkeyAzurePortal.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyAzurePortal { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyAzurePortal - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args -and $null -ne $O365Object.AuthType -and $O365Object.AuthType -eq 'Interactive'){ - $app_params = $O365Object.msal_application_args; - Get-MSalTokenForAzurePortal @app_params - } -} diff --git a/core/api/auth/azure/Connect-MonkeyAzure.ps1 b/core/api/auth/azure/Connect-MonkeyAzure.ps1 index 19f6b034..a0990f7e 100644 --- a/core/api/auth/azure/Connect-MonkeyAzure.ps1 +++ b/core/api/auth/azure/Connect-MonkeyAzure.ps1 @@ -47,12 +47,12 @@ Function Connect-MonkeyAzure{ MSGraph =$O365Object.Environment.Graphv2; LogAnalytics = $O365Object.Environment.LogAnalytics; } - #Get new app params - if($null -ne $O365Object.msal_application_args){ - $app_params = $O365Object.msal_application_args; - } - else{ - $app_params = $null; + $app_params = @{ + Resource = $null; + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; } } Process{ @@ -78,9 +78,9 @@ Function Connect-MonkeyAzure{ $new_params.add($param.Key, $param.Value) } #Add resource parameter - $new_params.Add('Resource',$service.Value) + $new_params.Resource = $service.Value try{ - $O365Object.auth_tokens.$($azure_service) = Get-MSALTokenForResource @new_params + $O365Object.auth_tokens.$($azure_service) = Connect-MonkeyGenericApplication @new_params $msg = @{ MessageData = ($message.TokenAcquiredInfoMessage -f $service.Name) callStack = (Get-PSCallStack | Select-Object -First 1); diff --git a/core/api/auth/exchange/Connect-MonkeyExchangeOnline.ps1 b/core/api/auth/exchange/Connect-MonkeyExchangeOnline.ps1 deleted file mode 100644 index 9522a3cd..00000000 --- a/core/api/auth/exchange/Connect-MonkeyExchangeOnline.ps1 +++ /dev/null @@ -1,95 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyExchangeOnline { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyExchangeOnline - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param ( - [Parameter(Mandatory=$true, HelpMessage="parameters")] - [Object]$parameters - ) - #Set new params - $new_params = @{} - foreach ($param in $parameters.GetEnumerator()){ - $new_params.add($param.Key, $param.Value) - } - #Check if confidential App - if($O365Object.isConfidentialApp -eq $false){ - #Check if application is present - if(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService ExchangeOnlineV2)})).Count -gt 0){ - $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService ExchangeOnlineV2)}) | Select-Object -First 1 - } - Else{ - #Potentially first time the user is authenticating, so we use original parameters - $new_params = @{} - foreach ($param in $O365Object.msal_application_args.GetEnumerator()){ - $new_params.add($param.Key, $param.Value) - } - #Create a new msal client application - $client_app = @{} - foreach ($param in $O365Object.application_args.GetEnumerator()){ - $client_app.add($param.Key, $param.Value) - } - $p = @{ - app_params = $client_app; - Environment = $O365Object.initParams.Environment; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - InformationAction = $O365Object.InformationAction; - } - $exo_app = New-MsalApplicationForExo @p - if($null -ne $exo_app){ - $O365Object.exo_msal_application = $exo_app - $new_params.publicApp = $O365Object.exo_msal_application - #Add to Object - [void]$O365Object.msal_public_applications.Add($exo_app) - } - else{ - $msg = @{ - MessageData = "Unable to get MSAL application for Exchange Online"; - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'Warning'; - InformationAction = $O365Object.InformationAction; - Tags = @('ExchangeOnlineApplicationError'); - } - Write-Warning @msg - } - } - } - else{ - $O365Object.exo_msal_application = $O365Object.msalapplication - $new_params.confidentialApp = $O365Object.msalapplication; - } - #Connect to Exchange Online - Get-MonkeyMSALPSSessionForExchangeOnline @new_params -} diff --git a/core/api/auth/exchange/Get-TokenForEXO.ps1 b/core/api/auth/exchange/Get-TokenForEXO.ps1 index 413bd6be..9869ae1d 100644 --- a/core/api/auth/exchange/Get-TokenForEXO.ps1 +++ b/core/api/auth/exchange/Get-TokenForEXO.ps1 @@ -90,7 +90,7 @@ Function Get-TokenForEXO { #Add Exo resource parameter $new_params.Add('Resource',$O365Object.Environment.Outlook) #Get token with new params - Get-MSALTokenForResource @new_params + Get-MonkeyMSALToken @new_params } catch{ Write-Error $_ diff --git a/core/api/auth/exchangecompliance/Connect-MonkeyComplianceCenter.ps1 b/core/api/auth/exchangecompliance/Connect-MonkeyComplianceCenter.ps1 deleted file mode 100644 index 7eeaa544..00000000 --- a/core/api/auth/exchangecompliance/Connect-MonkeyComplianceCenter.ps1 +++ /dev/null @@ -1,95 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyComplianceCenter { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyComplianceCenter - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param ( - [Parameter(Mandatory=$true, HelpMessage="parameters")] - [Object]$parameters - ) - #Set new params - $new_params = @{} - foreach ($param in $parameters.GetEnumerator()){ - $new_params.add($param.Key, $param.Value) - } - #Check if confidential App - if($O365Object.isConfidentialApp -eq $false){ - #Check if application is present - if(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService ExchangeOnlineV2)})).Count -gt 0){ - $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService ExchangeOnlineV2)}) | Select-Object -First 1 - } - Else{ - #Potentially first time the user is authenticating, so we use original parameters - $new_params = @{} - foreach ($param in $O365Object.msal_application_args.GetEnumerator()){ - $new_params.add($param.Key, $param.Value) - } - #Create a new msal client application - $client_app = @{} - foreach ($param in $O365Object.application_args.GetEnumerator()){ - $client_app.add($param.Key, $param.Value) - } - $p = @{ - app_params = $client_app; - Environment = $O365Object.initParams.Environment; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - InformationAction = $O365Object.InformationAction; - } - $exo_app = New-MsalApplicationForExo @p - if($null -ne $exo_app){ - $O365Object.exo_msal_application = $exo_app - $new_params.publicApp = $O365Object.exo_msal_application - #Add to Object - [void]$O365Object.msal_public_applications.Add($exo_app) - } - else{ - $msg = @{ - MessageData = "Unable to get MSAL application for purview"; - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'Warning'; - InformationAction = $O365Object.InformationAction; - Tags = @('PurviewApplicationError'); - } - Write-Warning @msg - } - } - } - else{ - $O365Object.exo_msal_application = $O365Object.msalapplication - $new_params.confidentialApp = $O365Object.msalapplication; - } - #Connect to Exchange Online Compliance Center - Get-MonkeyMSALPSSessionForComplianceCenter @new_params -} diff --git a/core/api/auth/generic/Connect-MonkeyGenericApplication.ps1 b/core/api/auth/generic/Connect-MonkeyGenericApplication.ps1 new file mode 100644 index 00000000..d08324c1 --- /dev/null +++ b/core/api/auth/generic/Connect-MonkeyGenericApplication.ps1 @@ -0,0 +1,148 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Connect-MonkeyGenericApplication { + <# + .SYNOPSIS + + .DESCRIPTION + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Connect-MonkeyGenericApplication + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", "", Scope="Function")] + [CmdletBinding()] + Param ( + [Parameter(Mandatory=$false, HelpMessage="Azure service")] + [String]$AzureService = "AzurePowershell", + + [Parameter(Mandatory=$true, HelpMessage="Resource to connect")] + [String]$Resource, + + [Parameter(Mandatory=$false, HelpMessage="Redirect URI")] + [String]$RedirectUri + ) + Begin{ + #Set new params + $new_params = @{} + foreach ($param in $O365Object.msal_application_args.GetEnumerator()){ + $new_params.add($param.Key, $param.Value) + } + } + Process{ + if($O365Object.isConfidentialApp -eq $false){ + #Check if application is present + if(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService ("{0}" -f $AzureService))})).Count -gt 0){ + $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService ("{0}" -f $AzureService))}) | Select-Object -First 1 + #Add silent + if(-NOT $new_params.ContainsKey('Silent')){ + #Add silent auth + [ref]$null = $new_params.Add('Silent',$true) + } + } + Else{ + #Potentially first time the user is authenticating, so we use original parameters + #Set new params + $new_params = @{} + foreach ($param in $O365Object.msalAuthArgs.GetEnumerator()){ + $new_params.add($param.Key, $param.Value) + } + #Set new params for application + $client_app = @{} + foreach ($param in $O365Object.application_args.GetEnumerator()){ + $client_app.add($param.Key, $param.Value) + } + #Get ClientId from Microsoft Graph + $clientId = Get-WellKnownAzureService -AzureService $AzureService + if($clientId){ + #Add to param + [void]$client_app.add('ClientId', $clientId) + #Get application + $publicApp = New-MonkeyMsalApplication @client_app + if($publicApp){ + #Add public app to param + $new_params.publicApp = $publicApp + #Add to Object + [void]$O365Object.msal_public_applications.Add($publicApp) + } + Else{ + $msg = @{ + MessageData = ("Unable to get MSAL application for {0}" -f $clientId); + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'Warning'; + InformationAction = $O365Object.InformationAction; + Tags = @('MonkeyGenericApplicationError'); + } + Write-Warning @msg + return + } + } + Else{ + $msg = @{ + MessageData = "ClientId was not found"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'Warning'; + InformationAction = $O365Object.InformationAction; + Tags = @('MonkeyGenericApplicationClientIdError'); + } + Write-Warning @msg + return + } + } + #Add redirect URI if present + if($PSBoundParameters.ContainsKey('RedirectUri') -and $PSBoundParameters['RedirectUri']){ + $new_params.publicApp.RedirectUri = $PSBoundParameters['RedirectUri']; + } + } + #Add resource to param + [void]$new_params.add('Resource', $Resource) + #Try to get token + $access_token = Get-MonkeyMSALToken @new_params + If($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ + #Write message + $msg = @{ + MessageData = $Script:message.TokenAcquiredGenericMessage + Tags = @('MSALSuccessAuth'); + InformationAction = $O365Object.InformationAction; + } + Write-Information @msg + return $access_token + } + } + End{ + #Clean redirect uri + If(($PSBoundParameters.ContainsKey('RedirectUri') -and $PSBoundParameters['RedirectUri'])){ + if($O365Object.isConfidentialApp -eq $false){ + #Get app + $app = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService ("{0}" -f $AzureService))}) | Select-Object -First 1 + if($app){ + #Remove Redirect Uri + $app.RedirectUri = $null; + } + } + } + } +} \ No newline at end of file diff --git a/core/api/auth/graph/Connect-MonkeyGraph.ps1 b/core/api/auth/graph/Connect-MonkeyGraph.ps1 deleted file mode 100644 index cfb1346d..00000000 --- a/core/api/auth/graph/Connect-MonkeyGraph.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyGraph { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyGraph - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args){ - $app_params = $O365Object.msal_application_args; - Get-MSALTokenForGraph @app_params - } -} diff --git a/core/api/auth/m365admin/Connect-MonkeyM365AdminPortal.ps1 b/core/api/auth/m365admin/Connect-MonkeyM365AdminPortal.ps1 deleted file mode 100644 index 1b9a0ae6..00000000 --- a/core/api/auth/m365admin/Connect-MonkeyM365AdminPortal.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyM365AdminPortal { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyM365AdminPortal - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args -and $null -ne $O365Object.AuthType -and $O365Object.AuthType -eq 'Interactive'){ - $app_params = $O365Object.msal_application_args; - Get-MSALTokenForMicrosoft365AdminPortal @app_params - } -} diff --git a/core/api/auth/microsoft365/Connect-MonkeyM365.ps1 b/core/api/auth/microsoft365/Connect-MonkeyM365.ps1 index ed5eb8ea..8676a03f 100644 --- a/core/api/auth/microsoft365/Connect-MonkeyM365.ps1 +++ b/core/api/auth/microsoft365/Connect-MonkeyM365.ps1 @@ -41,6 +41,14 @@ Function Connect-MonkeyM365{ switch ($service.ToLower()) { #Connect to Exchange Online 'exchangeonline'{ + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Exchange Online") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg $O365Object.auth_tokens.ExchangeOnline = Get-TokenForEXO if($null -ne $O365Object.auth_tokens.ExchangeOnline){ #Get ExchangeOnline module file @@ -67,6 +75,14 @@ Function Connect-MonkeyM365{ } #Connect to Microsoft Purview 'purview'{ + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Microsoft Purview") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg #Add resource for ComplianceCenter $O365Object.auth_tokens.ComplianceCenter = Get-TokenForEXO #Get Backend URI @@ -142,6 +158,8 @@ Function Connect-MonkeyM365{ Write-Warning @msg continue; } + #Set null + $initialDomain = $null; #Get initial domain If($O365Object.isValidTenantGuid -eq $false){ $initialDomain = $O365Object.TenantId @@ -153,7 +171,7 @@ Function Connect-MonkeyM365{ ElseIf($null -ne $O365Object.Tenant.CompanyInfo){ $initialDomain = $O365Object.Tenant.CompanyInfo.verifiedDomains.Where({$_.capabilities -like "*OfficeCommunicationsOnline*" -and $_.isDefault -eq $true}) | Select-Object -ExpandProperty name } - Else{ + If($null -eq $initialDomain){ $msg = @{ MessageData = ($message.NotConnectedTo -f $service); callStack = (Get-PSCallStack | Select-Object -First 1); @@ -179,10 +197,34 @@ Function Connect-MonkeyM365{ Verbose = $O365Object.verbose; Debug = $O365Object.debug; } + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "SharePoint Online") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg $O365Object.auth_tokens.SharePointOnline = Connect-MonkeySPO @p -RootSite #Connect to the admin site + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "SharePoint Online admin") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg $O365Object.auth_tokens.SharePointAdminOnline = Connect-MonkeySPO @p -Admin #Connect to OneDrive site + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "OneDrive For Business") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg $O365Object.auth_tokens.OneDrive = Connect-MonkeySPO @p -OneDrive if($null -ne $O365Object.auth_tokens.SharePointOnline -and $null -ne $O365Object.auth_tokens.SharePointAdminOnline){ #Check if user is SharePoint administrator @@ -255,7 +297,23 @@ Function Connect-MonkeyM365{ } #Connect to Microsoft Teams 'microsoftteams'{ - $O365Object.auth_tokens.Teams = Connect-MonkeyTeamsForOffice + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Microsoft Teams") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg + $p = @{ + Resource = (Get-WellKnownAzureService -AzureService TeamsAdminApi); + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.Teams = Connect-MonkeyGenericApplication @p + #$O365Object.auth_tokens.Teams = Connect-MonkeyTeamsForOffice if($null -ne $O365Object.auth_tokens.Teams){ #Get Backend URI $p = @{ @@ -310,14 +368,47 @@ Function Connect-MonkeyM365{ Write-Warning @msg continue; } + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Microsoft Forms") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg #Connect to Microsoft Forms - $O365Object.auth_tokens.Forms = Connect-MonkeyFormsForOffice + $p = @{ + Resource = (Get-WellKnownAzureService -AzureService MicrosoftForms); + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.Forms = Connect-MonkeyGenericApplication @p + #$O365Object.auth_tokens.Forms = Connect-MonkeyFormsForOffice if($null -ne $O365Object.auth_tokens.Forms){ $O365Object.onlineServices.Item($service) = $true } Start-Sleep -Milliseconds 10 + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Microsoft Right Management Services") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg #Connect to Microsoft Rights Management Services - $O365Object.auth_tokens.AADRM = Connect-MonkeyAADRM + $p = @{ + Resource = $O365Object.Environment.AADRM; + AzureService = "AzurePowershell"; + RedirectUri = "https://aadrm.com/adminpowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.AADRM = Connect-MonkeyGenericApplication @p + #$O365Object.auth_tokens.AADRM = Connect-MonkeyAADRM if($null -ne $O365Object.auth_tokens.AADRM){ #Get Service locator url $service_locator = Get-AADRMServiceLocatorUrl @@ -331,8 +422,24 @@ Function Connect-MonkeyM365{ $O365Object.onlineServices.Item($service) = $true } Start-Sleep -Milliseconds 10 + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Microsoft 365 Admin Portal") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg #Connect to Admin blade - $O365Object.auth_tokens.M365Admin = Connect-MonkeyM365AdminPortal + $p = @{ + Resource = $O365Object.Environment.OfficeAdminPortal; + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.M365Admin = Connect-MonkeyGenericApplication @p + #$O365Object.auth_tokens.M365Admin = Connect-MonkeyM365AdminPortal if($null -ne $O365Object.auth_tokens.M365Admin){ #Test if connection to Admin blade is allowed $p = @{ @@ -358,7 +465,24 @@ Function Connect-MonkeyM365{ } #Connect to PowerBI 'powerbi'{ - $O365Object.auth_tokens.PowerBI = Connect-MonkeyPowerBI + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Microsoft PowerBI") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg + #Connect to PowerBI + $p = @{ + Resource = $O365Object.Environment.PowerBI; + AzureService = "AzurePowershell"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.PowerBI = Connect-MonkeyGenericApplication @p + #$O365Object.auth_tokens.PowerBI = Connect-MonkeyPowerBI if($null -ne $O365Object.auth_tokens.PowerBI){ #Get Backend URI $O365Object.PowerBIBackendUri = Get-MonkeyPowerBIBackendUri @@ -379,7 +503,23 @@ Function Connect-MonkeyM365{ } #Connect to Microsoft Intune 'intune'{ - $O365Object.auth_tokens.Intune = Connect-MonkeyIntune + $msg = @{ + MessageData = ($message.TokenRequestInfoMessage -f "Microsoft Intune") + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'info'; + InformationAction = $O365Object.InformationAction; + Tags = @('TokenRequestInfoMessage'); + } + Write-Information @msg + $p = @{ + Resource = $O365Object.Environment.Graphv2; + AzureService = "Intune"; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + $O365Object.auth_tokens.Intune = Connect-MonkeyGenericApplication @p + #$O365Object.auth_tokens.Intune = Connect-MonkeyIntune if($null -ne $O365Object.auth_tokens.Intune){ $O365Object.onlineServices.Item($service) = $true } diff --git a/core/api/auth/msgraph/Connect-MonkeyMSGraph.ps1 b/core/api/auth/msgraph/Connect-MonkeyMSGraph.ps1 index ff5cdad5..c0ac4db1 100644 --- a/core/api/auth/msgraph/Connect-MonkeyMSGraph.ps1 +++ b/core/api/auth/msgraph/Connect-MonkeyMSGraph.ps1 @@ -35,8 +35,112 @@ Function Connect-MonkeyMSGraph { #> [CmdletBinding()] Param () - if($null -ne $O365Object.msal_application_args){ - $p = $O365Object.msal_application_args; - Get-MSALTokenForGraphV2 @p + #Set new params + $new_params = @{} + foreach ($param in $O365Object.msal_application_args.GetEnumerator()){ + $new_params.add($param.Key, $param.Value) } + if($O365Object.isConfidentialApp -eq $false){ + Try{ + #Only valid for Interactive authentication + $useMgGraph = [System.Convert]::ToBoolean($O365Object.internal_config.entraId.mgGraph.useMgGraph) + $scopes = $O365Object.internal_config.entraId.mgGraph.scopes + } + Catch{ + $useMgGraph = $false + $scopes = $null + } + if($useMgGraph -and $scopes){ + #Check if application is present + if(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService MicrosoftGraph)})).Count -gt 0){ + $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService MicrosoftGraph)}) | Select-Object -First 1 + } + Else{ + #Potentially first time the user is authenticating, so we use original parameters + #Set new params + $new_params = @{} + foreach ($param in $O365Object.msalAuthArgs.GetEnumerator()){ + $new_params.add($param.Key, $param.Value) + } + #Set new params for application + $client_app = @{} + foreach ($param in $O365Object.application_args.GetEnumerator()){ + $client_app.add($param.Key, $param.Value) + } + #Get ClientId from Microsoft Graph + $clientId = Get-WellKnownAzureService -AzureService MicrosoftGraph + #Add to param + [void]$client_app.add('ClientId', $clientId) + #Get application + $publicApp = New-MonkeyMsalApplication @client_app + if($publicApp){ + #Add public app to param + $new_params.publicApp = $publicApp + #Add to Object + [void]$O365Object.msal_public_applications.Add($publicApp) + } + Else{ + $msg = @{ + MessageData = "Unable to get MSAL application for Microsoft Graph"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'Warning'; + InformationAction = $O365Object.InformationAction; + Tags = @('MicrosoftGraphApplicationError'); + } + Write-Warning @msg + return + } + } + #Add scopes + [void]$new_params.add('Scopes', $scopes) + } + Else{ + #Check if application is present + if(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService AzurePowershell)})).Count -gt 0){ + $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService AzurePowershell)}) | Select-Object -First 1 + } + Else{ + #Potentially first time the user is authenticating, so we use original parameters + #Set new params + $new_params = @{} + foreach ($param in $O365Object.msalAuthArgs.GetEnumerator()){ + $new_params.add($param.Key, $param.Value) + } + #Set new params for application + $client_app = @{} + foreach ($param in $O365Object.application_args.GetEnumerator()){ + $client_app.add($param.Key, $param.Value) + } + #Get ClientId from Microsoft Graph + $clientId = Get-WellKnownAzureService -AzureService AzurePowershell + #Add to param + [void]$client_app.add('ClientId', $clientId) + #Get application + $publicApp = New-MonkeyMsalApplication @client_app + if($publicApp){ + #Add public app to param + $new_params.publicApp = $publicApp + #Add to Object + [void]$O365Object.msal_public_applications.Add($publicApp) + } + Else{ + $msg = @{ + MessageData = "Unable to get MSAL application for Microsoft Graph V2"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'Warning'; + InformationAction = $O365Object.InformationAction; + Tags = @('MicrosoftGraphApplicationError'); + } + Write-Warning @msg + return + } + } + } + } + #Get endpoint + $msGraphEndpoint = $O365Object.Environment.Graphv2 + #Add resource to param + [void]$new_params.add('Resource', $msGraphEndpoint) + #Try to get token + Get-MonkeyMSALToken @new_params } diff --git a/core/api/auth/mspim/Connect-MonkeyPIM.ps1 b/core/api/auth/mspim/Connect-MonkeyPIM.ps1 deleted file mode 100644 index eadf71b6..00000000 --- a/core/api/auth/mspim/Connect-MonkeyPIM.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyPIM { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyPIM - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args){ - $app_params = $O365Object.msal_application_args; - Get-MSALTokenForPIM @app_params - } -} diff --git a/core/api/auth/powerbi/Connect-MonkeyPowerBI.ps1 b/core/api/auth/powerbi/Connect-MonkeyPowerBI.ps1 deleted file mode 100644 index 3aa23228..00000000 --- a/core/api/auth/powerbi/Connect-MonkeyPowerBI.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyPowerBI { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyPowerBI - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args){ - $p = $O365Object.msal_application_args; - Get-MSALTokenForPowerBI @p - } -} diff --git a/core/api/auth/resourcemanagement/Connect-MonkeyResourceManagement.ps1 b/core/api/auth/resourcemanagement/Connect-MonkeyResourceManagement.ps1 deleted file mode 100644 index af4fd1b8..00000000 --- a/core/api/auth/resourcemanagement/Connect-MonkeyResourceManagement.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyResourceManagement { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyResourceManagement - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - if($null -ne $O365Object.msal_application_args){ - $app_params = $O365Object.msal_application_args; - Get-MSALTokenForResourceManagement @app_params - } -} diff --git a/core/api/auth/servicemanagement/Connect-MonkeyServiceManagement.ps1 b/core/api/auth/servicemanagement/Connect-MonkeyServiceManagement.ps1 deleted file mode 100644 index 290d56f7..00000000 --- a/core/api/auth/servicemanagement/Connect-MonkeyServiceManagement.ps1 +++ /dev/null @@ -1,48 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Connect-MonkeyServiceManagement { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Connect-MonkeyServiceManagement - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [CmdletBinding()] - Param () - $app_params = $null - if($null -ne $O365Object.msal_application_args){ - $app_params = $O365Object.msal_application_args; - } - elseif($null -ne $O365Object.application_args){ - $app_params = $O365Object.application_args; - } - if($null -ne $app_params){ - Get-MSALTokenForServiceManagement @app_params - } -} diff --git a/core/api/auth/sharepoint/Connect-MonkeySPO.ps1 b/core/api/auth/sharepoint/Connect-MonkeySPO.ps1 index 107b97e3..a405e1bd 100644 --- a/core/api/auth/sharepoint/Connect-MonkeySPO.ps1 +++ b/core/api/auth/sharepoint/Connect-MonkeySPO.ps1 @@ -48,137 +48,135 @@ Function Connect-MonkeySPO { [Parameter(Mandatory=$false, ParameterSetName = 'oneDrive', HelpMessage="Connect OneDrive Url")] [Switch]$OneDrive ) - try{ - $sharepointUrl = $spo_app = $null; - #Get Environment - $CloudType = $O365Object.initParams.Environment - $sps_p = @{ - Endpoint = $PSBoundParameters['Endpoint']; - Environment = $CloudType; - InformationAction = $O365Object.InformationAction; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; + $sharepointUrl = $spo_app = $null; + #Get Environment + $CloudType = $O365Object.cloudEnvironment; + $sps_p = @{ + Endpoint = $PSBoundParameters['Endpoint']; + Environment = $CloudType; + InformationAction = $O365Object.InformationAction; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + } + #Get Endpoint + switch -Wildcard ($PSCmdlet.ParameterSetName) { + 'Admin' { + $sharepointUrl = Get-SharepointAdminUrl @sps_p } - #Get Endpoint - switch -Wildcard ($PSCmdlet.ParameterSetName) { - 'Admin' { - $sharepointUrl = Get-SharepointAdminUrl @sps_p - } - 'rootSite' { - $sharepointUrl = Get-SharepointUrl @sps_p - } - 'oneDrive' { - $sharepointUrl = Get-OneDriveUrl @sps_p - } - Default { - $sharepointUrl = Get-SharepointUrl @sps_p - } + 'rootSite' { + $sharepointUrl = Get-SharepointUrl @sps_p + } + 'oneDrive' { + $sharepointUrl = Get-OneDriveUrl @sps_p + } + Default { + $sharepointUrl = Get-SharepointUrl @sps_p + } + } + if($null -eq $sharepointUrl){ + $msg = @{ + MessageData = "Unable to get a valid URL for SharePoint Online"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'Warning'; + InformationAction = $O365Object.InformationAction; + Tags = @('SharePointOnlineUrlError'); } + Write-Warning @msg + return + } + #Get default application args + $new_params = @{} + foreach ($param in $O365Object.msal_application_args.GetEnumerator()){ + $new_params.add($param.Key, $param.Value) + } + if($O365Object.isConfidentialApp -eq $false){ try{ $usePnpManagementShell = [System.Convert]::ToBoolean($O365Object.internal_config.o365.SharePointOnline.UsePnPManagementShell) } catch{ $usePnpManagementShell = $false } - if($null -ne $sharepointUrl){ + #Check if application is present + if(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService SharePointOnline)})).Count -gt 0){ + $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService SharePointOnline)}) | Select-Object -First 1 + } + ElseIf(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService SharePointPnP)})).Count -gt 0){ + $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService SharePointPnP)}) | Select-Object -First 1 + } + Else{ + #Potentially first time the user is authenticating, so we use original parameters #Set new params $new_params = @{} - foreach ($param in $O365Object.msal_application_args.GetEnumerator()){ + foreach ($param in $O365Object.msalAuthArgs.GetEnumerator()){ $new_params.add($param.Key, $param.Value) } - #Check if confidential App - if($O365Object.isConfidentialApp -eq $false){ - #Check if application is present - if(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService SharePointOnline)})).Count -gt 0){ - $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService SharePointOnline)}) | Select-Object -First 1 - } - ElseIf(($O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService SharePointPnP)})).Count -gt 0){ - $new_params.publicApp = $O365Object.msal_public_applications.Where({$_.ClientId -eq (Get-WellKnownAzureService -AzureService SharePointPnP)}) | Select-Object -First 1 + #Create a new msal client application + $client_app = @{} + foreach ($param in $O365Object.application_args.GetEnumerator()){ + $client_app.add($param.Key, $param.Value) + } + $p = @{ + app_params = $client_app; + Environment = $O365Object.initParams.Environment; + Verbose = $O365Object.verbose; + Debug = $O365Object.debug; + InformationAction = $O365Object.InformationAction; + } + If($usePnpManagementShell){ + $spo_app = New-MsalApplicationForPnP @p + #Add scopes + [string[]]$scope = "AllSites.Read" + [void]$new_params.Add('Scopes',$scope); + } + Else{ + #Check if force MSAL desktop + if($null -ne $O365Object.SystemInfo -and $O365Object.SystemInfo.MsalType -eq 'Desktop'){ + $p.Item('ForceDesktop') = $true } - Else{ - #Potentially first time the user is authenticating, so we use original parameters - #Set new params - $new_params = @{} - foreach ($param in $O365Object.msalAuthArgs.GetEnumerator()){ - $new_params.add($param.Key, $param.Value) - } - #Create a new msal client application - $client_app = @{} - foreach ($param in $O365Object.application_args.GetEnumerator()){ - $client_app.add($param.Key, $param.Value) - } - $p = @{ - app_params = $client_app; - Environment = $O365Object.initParams.Environment; - Verbose = $O365Object.verbose; - Debug = $O365Object.debug; - InformationAction = $O365Object.InformationAction; - } - if($usePnpManagementShell){ - $spo_app = New-MsalApplicationForPnP @p - } - else{ - #Check if force MSAL desktop - if($null -ne $O365Object.SystemInfo -and $O365Object.SystemInfo.MsalType -eq 'Desktop'){ - $p.Item('ForceDesktop') = $true - } - #Get Application for SPO - $spo_app = New-MsalApplicationForSPO @p - } - if($null -ne $spo_app){ - #Validate .net core conflicts - try{ - if($spo_app.AppConfig.RedirectUri -match "localhost" -and $O365Object.SystemInfo.MsalType -eq "Core"){ - $dc = $new_params.Item('DeviceCode'); - if($null -eq $dc -or $dc -eq $false){ - $msg = @{ - MessageData = "Unable to connect SharePoint Online. SharePoint Online Management Shell is not supporting interactive authentication on .NET core. Use DeviceCode instead. For more info, please check the following url: https://silverhack.github.io/monkey365/authentication/limitations/"; - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'Warning'; - InformationAction = $O365Object.InformationAction; - Tags = @('MonkeySPOAuthenticationError'); - } - Write-Warning @msg - return - } + #Get Application for SPO + try{ + $spo_app = New-MsalApplicationForSPO @p + #Validate .net core conflicts + if($spo_app.AppConfig.RedirectUri -match "localhost" -and $O365Object.SystemInfo.MsalType -eq "Core"){ + $dc = $new_params.Item('DeviceCode'); + if($null -eq $dc -or $dc -eq $false){ + $msg = @{ + MessageData = "Unable to connect SharePoint Online. SharePoint Online Management Shell is not supporting interactive authentication on .NET core. Use DeviceCode instead. For more info, please check the following url: https://silverhack.github.io/monkey365/authentication/limitations/"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'Warning'; + InformationAction = $O365Object.InformationAction; + Tags = @('MonkeySPOAuthenticationError'); } - $new_params.publicApp = $spo_app - #Add to Object - [void]$O365Object.msal_public_applications.Add($spo_app) - } - Catch{ - Write-Error $_ + Write-Warning @msg return } } - else{ - $msg = @{ - MessageData = "Unable to get MSAL application for SharePoint Online"; - callStack = (Get-PSCallStack | Select-Object -First 1); - logLevel = 'Warning'; - InformationAction = $O365Object.InformationAction; - Tags = @('SPOPublicApplicationError'); - } - Write-Warning @msg - return - } + } + Catch{ + Write-Error $_ + return } } - else{ - $new_params.confidentialApp = $O365Object.msalapplication; + if($null -ne $spo_app){ + $new_params.publicApp = $spo_app + #Add to Object + [void]$O365Object.msal_public_applications.Add($spo_app) } - #Add SharePoint url to object - [void]$new_params.Add('Resource',$sharepointUrl); - #Add scopes if PnP application is used - if($usePnpManagementShell){ - [string[]]$scope = "AllSites.Read" - [void]$new_params.Add('Scopes',$scope); + Else{ + $msg = @{ + MessageData = "Unable to get MSAL application for SharePoint Online"; + callStack = (Get-PSCallStack | Select-Object -First 1); + logLevel = 'Warning'; + InformationAction = $O365Object.InformationAction; + Tags = @('SharePointOnlineApplicationError'); + } + Write-Warning @msg + return } - #Connect to SharePoint Online - Get-MSALTokenForSharePointOnline @new_params } } - catch{ - Write-Error $_ - } -} + #Add SharePoint url to object + [void]$new_params.Add('Resource',$sharepointUrl); + #Try to get token + Get-MonkeyMSALToken @new_params +} \ No newline at end of file diff --git a/core/api/m365/Purview/Invoke-DLPValidation.ps1 b/core/api/m365/Purview/Invoke-DLPValidation.ps1 index 161e143d..7f629f3f 100644 --- a/core/api/m365/Purview/Invoke-DLPValidation.ps1 +++ b/core/api/m365/Purview/Invoke-DLPValidation.ps1 @@ -72,34 +72,36 @@ Function Invoke-DLPValidation{ #Set var $sits = $null #Get Sits - $selected_sits = $element.Sits | Where-Object {$_.Geo -eq $O365Object.orgRegions -or $_.Geo -eq "INTL"} | Select-Object -ExpandProperty Name + $selected_sits = @($element.Sits).Where({$_.Geo -eq $O365Object.orgRegions -or $_.Geo -eq "INTL"}) | Select-Object -ExpandProperty Name -ErrorAction Ignore #Get Sits from Dlp Object $sitTypes = @() foreach($sit in $all_rule_sits){ - $match = $element.Sits | Where-Object {$_.Name -eq $sit -and ($_.Geo -eq $O365Object.orgRegions -or $_.Geo -eq "INTL")} - if($match){ + $match = @($element.Sits).Where({$_.Name -eq $sit -and ($_.Geo -eq $O365Object.orgRegions -or $_.Geo -eq "INTL")}) + if($match.Count -gt 0){ $sitTypes+=$match.Name } } #Compare Object - $params = @{ - ReferenceObject = $selected_sits; - DifferenceObject = $sitTypes; - IncludeEqual= $false; - ExcludeDifferent = $false; - } - $results = Compare-Object @params - if($null -ne $results){ - $sits = $results | Select-Object -ExpandProperty InputObject - } - #Create Dict - $DLPObject = New-Object -TypeName PsObject -Property @{ - controlName = $element.Name; - controlType = $element.Tag; - Sits = $sits; + if($null -ne $selected_sits){ + $p = @{ + ReferenceObject = $selected_sits; + DifferenceObject = $sitTypes; + IncludeEqual= $false; + ExcludeDifferent = $false; + } + $results = Compare-Object @p + if($null -ne $results){ + $sits = $results | Select-Object -ExpandProperty InputObject + } + #Create Dict + $DLPObject = New-Object -TypeName PsObject -Property @{ + controlName = $element.Name; + controlType = $element.Tag; + Sits = $sits; + } + #Add to array + [void]$dlp_analysis.Add($DLPObject) } - #Add to array - [void]$dlp_analysis.Add($DLPObject) } } } diff --git a/core/html/Invoke-HtmlReport.ps1 b/core/html/Invoke-HtmlReport.ps1 index c288cf31..2f5ef94d 100644 --- a/core/html/Invoke-HtmlReport.ps1 +++ b/core/html/Invoke-HtmlReport.ps1 @@ -45,7 +45,7 @@ Function Invoke-HtmlReport{ $all_rules = Get-Rule if($null -ne (Get-Variable -Name monkeyExportObject -ErrorAction Ignore) -and $null -ne (Get-Variable -Name matchedRules -ErrorAction Ignore)){ $exec_info = [ordered]@{ - Ruleset = (Get-Framework -Current); + Ruleset = (Get-Framework); 'Ruleset Description' = (Get-Ruleset -Info).about; 'Number of rules' = @($all_rules).Count; 'Executed Rules' = @($matchedRules).Count; diff --git a/core/init/Get-MonkeyCollector.ps1 b/core/init/Get-MonkeyCollector.ps1 index b72707d4..50164798 100644 --- a/core/init/Get-MonkeyCollector.ps1 +++ b/core/init/Get-MonkeyCollector.ps1 @@ -104,11 +104,6 @@ Function Get-MonkeyCollector{ if($O365Object.isConfidentialApp -eq $true){ #Load MSGraph plugins $discovered_plugins = @($available_collectors).Where({$_.Provider -eq "EntraID" -and $_.ApiType -eq 'MSGraph'}) - #Add PIM plugins - $PIM_plugins = @($available_collectors).Where({$_.Provider -eq "EntraID" -and ($_.ApiType -eq 'PIM')}) - if($PIM_plugins){ - $discovered_plugins+=$PIM_plugins - } } elseif($useMsGraph -eq $false -and $O365Object.isConfidentialApp -eq $false){ #Load Old Graph collectors and Azure AD internal API collectors @@ -132,11 +127,6 @@ Function Get-MonkeyCollector{ if($ad_policy_plugin){ $discovered_plugins+=$ad_policy_plugin } - #Add PIM collectors - $PIM_plugins = @($available_collectors).Where({$_.Provider -eq "EntraID" -and $_.ApiType -eq 'PIM'}) - if($PIM_plugins){ - $discovered_plugins+=$PIM_plugins - } } else{ #Load MSGraph collectors diff --git a/core/init/Initialize-AuthenticationParam.ps1 b/core/init/Initialize-AuthenticationParam.ps1 index 0610451b..9c16c408 100644 --- a/core/init/Initialize-AuthenticationParam.ps1 +++ b/core/init/Initialize-AuthenticationParam.ps1 @@ -61,8 +61,10 @@ Function Initialize-AuthenticationParam{ End{ if($O365Object.application_args){ $app_param = $O365Object.application_args; - $O365Object.msalapplication = New-MonkeyMsalApplication @app_param - $O365Object.isConfidentialApp = -NOT $O365Object.msalapplication.isPublicApp; + $newApplication = New-MonkeyMsalApplication @app_param + $O365Object.isConfidentialApp = -NOT $newApplication.isPublicApp; + #$O365Object.msalapplication = New-MonkeyMsalApplication @app_param + #$O365Object.isConfidentialApp = -NOT $O365Object.msalapplication.isPublicApp; #Get Auth params $msalAppMetadata = New-Object -TypeName "System.Management.Automation.CommandMetaData" (Get-Command -Name "Get-MonkeyMSALToken") #Set new dict @@ -75,14 +77,16 @@ Function Initialize-AuthenticationParam{ } } if($O365Object.isConfidentialApp){ - #Add confidential client + #Add confidential application + $O365Object.msalapplication = $newApplication; [void]$O365Object.msal_confidential_applications.Add($O365Object.msalapplication) [ref]$null = $newPsboundParams.Add('confidentialApp',$O365Object.msalapplication); } else{ #Add public client - [void]$O365Object.msal_public_applications.Add($O365Object.msalapplication) - [ref]$null = $newPsboundParams.Add('publicApp',$O365Object.msalapplication); + #[void]$O365Object.msal_public_applications.Add($O365Object.msalapplication) + #[ref]$null = $newPsboundParams.Add('publicApp',$O365Object.msalapplication); + [ref]$null = $newPsboundParams.Add('publicApp',$null); } #Add Verbose, informationAction and Debug parameters [ref]$null = $newPsboundParams.Add('InformationAction',$O365Object.InformationAction); diff --git a/core/modules/monkeycloudutils/public/New-MsalApplicationForPnP.ps1 b/core/modules/monkeycloudutils/public/New-MsalApplicationForPnP.ps1 index 1f838775..b1b720ec 100644 --- a/core/modules/monkeycloudutils/public/New-MsalApplicationForPnP.ps1 +++ b/core/modules/monkeycloudutils/public/New-MsalApplicationForPnP.ps1 @@ -36,6 +36,9 @@ Function New-MsalApplicationForPnP{ [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Scope="Function")] [CmdletBinding()] Param ( + [Parameter(Mandatory=$False, ParameterSetName='application params')] + [System.Collections.Hashtable]$app_params, + [parameter(Mandatory = $False)] [ValidateSet("AzurePublic","AzureGermany","AzureChina","AzureUSGovernment")] [String]$Environment= "AzurePublic" @@ -61,13 +64,34 @@ Function New-MsalApplicationForPnP{ } Process{ #Create a new app - $app_params = @{ - clientId = $clientId; - RedirectUri = $redirectUri; - Verbose = $Verbose; - Debug = $Debug; - InformationAction = $InformationAction; - Environment = $Environment; + if(-NOT $PSBoundParameters.ContainsKey('app_params')){ + #Create new application hashtable + $app_params = @{ + clientId = $clientId; + RedirectUri = $redirectUri; + Verbose = $Verbose; + Debug = $Debug; + InformationAction = $InformationAction; + Environment = $Environment; + } + } + Else{ + if(-NOT $app_params.ContainsKey('clientId')){ + #Add clientId + [ref]$null = $app_params.Add('clientId',$clientId) + } + else{ + $app_params.ClientId = $clientId + } + if($null -ne $redirectUri){ + if(-NOT $app_params.ContainsKey('redirectUri')){ + #Add redirect uri + [ref]$null = $app_params.Add('redirectUri',$redirectUri) + } + else{ + $app_params.redirectUri = $redirectUri + } + } } } End{ diff --git a/core/modules/monkeyhttpwebrequest/private/Get-HttpResponseError.ps1 b/core/modules/monkeyhttpwebrequest/private/Get-HttpResponseError.ps1 index 5029c3c6..029bf2b1 100644 --- a/core/modules/monkeyhttpwebrequest/private/Get-HttpResponseError.ps1 +++ b/core/modules/monkeyhttpwebrequest/private/Get-HttpResponseError.ps1 @@ -106,18 +106,8 @@ Function Get-HttpResponseError{ Write-Verbose @param } elseif($null -ne ($responseBody.psobject.properties.Item('error'))){ - try{ - $errorCode = $responseBody.error.code - } - catch{ - $errorCode = $null - } - try{ - $errorMessage = $responseBody.error.message - } - catch{ - $errorMessage = $null - } + $errorCode = $responseBody.error | Select-Object -ExpandProperty code -ErrorAction Ignore + $errorMessage = $responseBody.error | Select-Object -ExpandProperty message -ErrorAction Ignore if($null -ne $errorCode){ $param = @{ Message = $errorCode; @@ -134,18 +124,8 @@ Function Get-HttpResponseError{ } } elseif($null -ne ($responseBody.psobject.properties.Item('message'))){ - try{ - $errorCode = $responseBody.code - } - catch{ - $errorCode = $null - } - try{ - $errorMessage = $responseBody.message - } - catch{ - $errorMessage = $null - } + $errorCode = $responseBody | Select-Object -ExpandProperty code -ErrorAction Ignore + $errorMessage = $responseBody | Select-Object -ExpandProperty message -ErrorAction Ignore if($null -ne $errorCode){ $param = @{ Message = $errorCode; diff --git a/core/modules/monkeymsalauthassistant/Localized/en-US/monkeymsalauthassistant.psd1 b/core/modules/monkeymsalauthassistant/Localized/en-US/monkeymsalauthassistant.psd1 deleted file mode 100644 index db1be69a..00000000 --- a/core/modules/monkeymsalauthassistant/Localized/en-US/monkeymsalauthassistant.psd1 +++ /dev/null @@ -1,17 +0,0 @@ -ConvertFrom-StringData @' - UnknownResource = Unknown {0} resource - UnknownEnvironment = Unknown {0} environment - UnableToGetUPN = Unable to get UserPrincipalName - EXOSuccessfullyConnected = Successfully connected to Exchange Online - EXOErrorConnection = Unable to connect To Exchange Online - UnableToGetToken = Unable to get token for {0} - EndpointNotFound = Endpoint not found {0} - SuccessfullyConnectedTo = Successfully connected to {0} - TokenAcquiredInfoMessage = A new token was successfully acquired for {0} - ConnectionError = Unable to connect to {0} - SPSAdminUrlErrorMessage = Unable to get Sharepoint Admin Url - SPSSiteUrlErrorMessage = Unable to get Sharepoint Url - NotAllowedToAuth = Confidential application is not allowed to authenticate to {0} - TenantGuidError = TenantId cannot be a Guid, please enter the name of the tenant instead - UnableToGetTenantInfo = Unable to get tenant information. Possible errors are invalid permissions or incorrect scopes -'@ \ No newline at end of file diff --git a/core/modules/monkeymsalauthassistant/Localized/monkeymsalauthassistant.psd1 b/core/modules/monkeymsalauthassistant/Localized/monkeymsalauthassistant.psd1 deleted file mode 100644 index db1be69a..00000000 --- a/core/modules/monkeymsalauthassistant/Localized/monkeymsalauthassistant.psd1 +++ /dev/null @@ -1,17 +0,0 @@ -ConvertFrom-StringData @' - UnknownResource = Unknown {0} resource - UnknownEnvironment = Unknown {0} environment - UnableToGetUPN = Unable to get UserPrincipalName - EXOSuccessfullyConnected = Successfully connected to Exchange Online - EXOErrorConnection = Unable to connect To Exchange Online - UnableToGetToken = Unable to get token for {0} - EndpointNotFound = Endpoint not found {0} - SuccessfullyConnectedTo = Successfully connected to {0} - TokenAcquiredInfoMessage = A new token was successfully acquired for {0} - ConnectionError = Unable to connect to {0} - SPSAdminUrlErrorMessage = Unable to get Sharepoint Admin Url - SPSSiteUrlErrorMessage = Unable to get Sharepoint Url - NotAllowedToAuth = Confidential application is not allowed to authenticate to {0} - TenantGuidError = TenantId cannot be a Guid, please enter the name of the tenant instead - UnableToGetTenantInfo = Unable to get tenant information. Possible errors are invalid permissions or incorrect scopes -'@ \ No newline at end of file diff --git a/core/modules/monkeymsalauthassistant/monkeymsalauthassistant.psd1 b/core/modules/monkeymsalauthassistant/monkeymsalauthassistant.psd1 deleted file mode 100644 index a52c4f27..00000000 Binary files a/core/modules/monkeymsalauthassistant/monkeymsalauthassistant.psd1 and /dev/null differ diff --git a/core/modules/monkeymsalauthassistant/monkeymsalauthassistant.psm1 b/core/modules/monkeymsalauthassistant/monkeymsalauthassistant.psm1 deleted file mode 100644 index 850d8062..00000000 --- a/core/modules/monkeymsalauthassistant/monkeymsalauthassistant.psm1 +++ /dev/null @@ -1,17 +0,0 @@ -Set-StrictMode -Version Latest - -$listofFiles = [System.IO.Directory]::EnumerateFiles(("{0}" -f $PSScriptRoot),"*.ps1","AllDirectories") -$all_files = $listofFiles.Where({($_ -like "*public*") -or ($_ -like "*private*")}) -$content = $all_files.ForEach({ - [System.IO.File]::ReadAllText($_, [Text.Encoding]::UTF8) + [Environment]::NewLine -}) - -#Set-Content -Path $tmpFile -Value $content -. ([scriptblock]::Create($content)) - -$LocalizedDataParams = @{ - BindingVariable = 'messages'; - BaseDirectory = "{0}/{1}" -f $PSScriptRoot, "Localized"; -} -#Import localized data -Import-LocalizedData @LocalizedDataParams; \ No newline at end of file diff --git a/core/modules/monkeymsalauthassistant/private/Confirm-IfMSALPublicApp.ps1 b/core/modules/monkeymsalauthassistant/private/Confirm-IfMSALPublicApp.ps1 deleted file mode 100644 index 111acb15..00000000 --- a/core/modules/monkeymsalauthassistant/private/Confirm-IfMSALPublicApp.ps1 +++ /dev/null @@ -1,58 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Confirm-IfMSALPublicApp{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Confirm-IfMSALPublicApp - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [CmdletBinding()] - param - ( - # parameters - [Parameter(Mandatory = $false, HelpMessage = 'parameters')] - [Object]$parameters - ) - $isPublicApp = $true - $confidentialParams=@( - 'ClientSecret', - 'ClientCredentials', - 'Certificate', - 'CertficatePassword', - 'ConfidentialApp', - 'AuthorizationCode' - ) - foreach ($param in $parameters.GetEnumerator()){ - if ($param.key -in $confidentialParams) { $isPublicApp = $false } - } - #return object - return $isPublicApp -} diff --git a/core/modules/monkeymsalauthassistant/private/Get-LocalizedData.ps1 b/core/modules/monkeymsalauthassistant/private/Get-LocalizedData.ps1 deleted file mode 100644 index 71d0b6d6..00000000 --- a/core/modules/monkeymsalauthassistant/private/Get-LocalizedData.ps1 +++ /dev/null @@ -1,131 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -function Get-LocalizedData{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-LocalizedData - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [CmdletBinding()] - param - ( - [Parameter(Position = 1, ParameterSetName = 'TargetedUICulture')] - [System.String] - $UICulture, - - [Parameter()] - [System.String] - $BaseDirectory, - - [Parameter()] - [System.String] - $FileName, - - [Parameter(Position = 1, ParameterSetName = 'DefaultUICulture')] - [System.String] - $DefaultUICulture - ) - Begin{ - if (!$PSBoundParameters.ContainsKey('FileName')){ - if ($myInvocation.ScriptName){ - $file = [System.IO.FileInfo] $myInvocation.ScriptName - } - else{ - $file = [System.IO.FileInfo] $myInvocation.MyCommand.Module.Path - } - $FileName = $file.BaseName - #$PSBoundParameters.Add('FileName', $file.Name) - } - if ($PSBoundParameters.ContainsKey('BaseDirectory')){ - $callingScriptRoot = $BaseDirectory - } - else{ - $callingScriptRoot = $MyInvocation.PSScriptRoot - $PSBoundParameters.Add('BaseDirectory', $callingScriptRoot) - } - if ($PSBoundParameters.ContainsKey('DefaultUICulture') -and !$PSBoundParameters.ContainsKey('UICulture')){ - <# - We don't want the resolution to eventually return the ModuleManifest - so we run the same GetFilePath() logic than here: - https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Import-LocalizedData.cs#L302-L333 - and if we see it will return the wrong thing, set the UICulture to DefaultUI culture, and return the logic to Import-LocalizedData - #> - $currentCulture = Get-UICulture - $languageFile = $null - $localizedFileNames = @( - $FileName + '.psd1' - $FileName + '.strings.psd1' - ) - while ($null -ne $currentCulture -and $currentCulture -is [System.Globalization.CultureInfo] -and !$languageFile){ - if($currentCulture.Name.Length -gt 0){ - $cultureName = $currentCulture.Name - } - else{ - $cultureName = 'en-US' - } - foreach ($fullFileName in $localizedFileNames){ - $filePath = [io.Path]::Combine($callingScriptRoot, $cultureName, $fullFileName) - if (Test-Path -Path $filePath){ - Write-Verbose -Message "Found $filePath" - $languageFile = $filePath - # Set the filename to the file we found. - $PSBoundParameters['FileName'] = $fullFileName - $PSBoundParameters['BaseDirectory'] = [io.Path]::Combine($callingScriptRoot, $cultureName) - # Exit loop if we find the first filename. - break - } - else{ - Write-Verbose -Message "File $filePath not found" - #Write-Host "File $filePath not found" - } - } - $currentCulture = $currentCulture.Parent - } - if (!$languageFile){ - $PSBoundParameters.Add('UICulture', $DefaultUICulture) - } - $null = $PSBoundParameters.Remove('DefaultUICulture') - } - } - Process{ - #Import localized Data - if($PSBoundParameters.ContainsKey('FileName') -and $fullFileName){ - Import-LocalizedData @PSBoundParameters - } - else{ - Write-Warning "Unable to get Localized data file" - } - } - End{ - #Nothing to do here - } -} - diff --git a/core/modules/monkeymsalauthassistant/private/Get-MSALApplicationParam.ps1 b/core/modules/monkeymsalauthassistant/private/Get-MSALApplicationParam.ps1 deleted file mode 100644 index d6dee1c0..00000000 --- a/core/modules/monkeymsalauthassistant/private/Get-MSALApplicationParam.ps1 +++ /dev/null @@ -1,58 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALApplicationParam{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALApplicationParam - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [CmdletBinding()] - [OutputType([Hashtable])] - param - ( - # psboundparameters - [Parameter(Mandatory = $false, HelpMessage = 'Parameters')] - [object] $parameters - ) - $extraParams=@( - 'Silent', - 'DeviceCode', - 'PromptBehavior', - 'ForceAuth' - ) - #Remove unnecessary params - $body = @{} - foreach ($param in $parameters.GetEnumerator()){ - if($param.key -in $extraParams){ continue } - $body.add($param.Key, $param.Value) - } - return $body -} diff --git a/core/modules/monkeymsalauthassistant/private/Get-MSALAuthParam.ps1 b/core/modules/monkeymsalauthassistant/private/Get-MSALAuthParam.ps1 deleted file mode 100644 index 75040aaf..00000000 --- a/core/modules/monkeymsalauthassistant/private/Get-MSALAuthParam.ps1 +++ /dev/null @@ -1,55 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALAuthParam{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALAuthParam - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [CmdletBinding()] - [OutputType([Hashtable])] - param - ( - # psboundparameters - [Parameter(Mandatory = $false, HelpMessage = 'Parameters')] - [object] $parameters - ) - #Skip any parameters - $skip=@( - 'Admin','rootSite','Endpoint','oneDrive' - ) - $body = @{} - foreach ($param in $parameters.GetEnumerator()){ - if ($param.key -in $skip) { continue } - $body.add($param.Key, $param.Value) - } - $body -} diff --git a/core/modules/monkeymsalauthassistant/private/Remove-MSALPublicParam.ps1 b/core/modules/monkeymsalauthassistant/private/Remove-MSALPublicParam.ps1 deleted file mode 100644 index 56143d2a..00000000 --- a/core/modules/monkeymsalauthassistant/private/Remove-MSALPublicParam.ps1 +++ /dev/null @@ -1,66 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Remove-MSALPublicParam{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Remove-MSALPublicParam - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "", Scope="Function")] - [CmdletBinding()] - [OutputType([Hashtable])] - param - ( - # psboundparameters - [Parameter(Mandatory = $false, HelpMessage = 'Parameters')] - [object] $parameters - ) - Begin{ - #Public/Interactive params - $publicParams=@( - 'Silent', - 'DeviceCode', - 'PromptBehavior', - 'ForceAuth' - ) - } - Process{ - #Remove common params - $body = @{} - foreach ($param in $parameters.GetEnumerator()){ - if ($param.key -in $publicParams) { continue } - $body.add($param.Key, $param.Value) - } - } - End{ - return $body - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForAADRM.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForAADRM.ps1 deleted file mode 100644 index fba54a6b..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForAADRM.ps1 +++ /dev/null @@ -1,210 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForAADRM{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForAADRM - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Begin{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false -or $ConfidentialApp){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - #Set clientId - if($isPublicApp -or $PublicApp){ - $internal_params.Add('RedirectUri',"https://aadrm.com/adminpowershell") - } - } - Process{ - $access_token = Get-MonkeyMSALToken @internal_params -Resource $AzureEnvironment.AADRM; - } - End{ - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Right Management Services") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Right Management Services") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForAzurePortal.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForAzurePortal.ps1 deleted file mode 100644 index d77fbd4e..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForAzurePortal.ps1 +++ /dev/null @@ -1,203 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForAzurePortal{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForAzurePortal - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzurePortalWellKnownId = Get-WellKnownAzureService -AzureService AzurePortal - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - Write-Warning -Message ($Script:messages.NotAllowedToAuth -f "Azure Portal AAD") - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $access_token = Get-MonkeyMSALToken @internal_params -Resource $AzurePortalWellKnownId; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Azure AAD Portal") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Azure AAD Portal") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForForms.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForForms.ps1 deleted file mode 100644 index 16df7be3..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForForms.ps1 +++ /dev/null @@ -1,209 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForForms{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForForms - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Begin{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - #$isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $FormsWellKnownId = Get-WellKnownAzureService -AzureService MicrosoftForms - <# - if($isPublicApp -eq $false){ - #Remove common params - $PSBoundParameters = Remove-MSALPublicParam -parameters $PSBoundParameters - Write-Warning -Message ($Script:messages.NotAllowedToAuth -f "Microsoft Forms") - } - #> - } - Process{ - $access_token = Get-MonkeyMSALToken @PSBoundParameters -Resource $FormsWellKnownId; - } - End{ - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Microsoft Forms") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Microsoft Forms") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForGraph.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForGraph.ps1 deleted file mode 100644 index 4575b2e4..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForGraph.ps1 +++ /dev/null @@ -1,202 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForGraph{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForGraph - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false -or $ConfidentialApp){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $access_token = Get-MonkeyMSALToken @internal_params -Resource $AzureEnvironment.Graph; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Graph") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Graph") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForGraphV2.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForGraphV2.ps1 deleted file mode 100644 index a2e6eca0..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForGraphV2.ps1 +++ /dev/null @@ -1,202 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForGraphV2{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForGraphV2 - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $access_token = Get-MonkeyMSALToken @internal_params -Resource $AzureEnvironment.Graphv2; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Microsoft Graph") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Microsoft Graph") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForIntune.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForIntune.ps1 deleted file mode 100644 index 5af7e536..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForIntune.ps1 +++ /dev/null @@ -1,220 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForIntune{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForIntune - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Begin{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false -or $ConfidentialApp){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - #Set clientId - if($null -ne $PublicApp -and $PublicApp -is [Microsoft.Identity.Client.PublicClientApplication]){ - if($PublicApp.AppConfig.ClientId -ne (Get-WellKnownAzureService -AzureService Intune)){ - #Add clientId and RedirectUri - $app_param = @{} - $app_param.ClientId = (Get-WellKnownAzureService -AzureService Intune) - if($PSBoundParameters.ContainsKey('TenantId')){ - $app_param.TenantId = $TenantId - } - $intune_app = New-MonkeyMsalApplication @app_param - [ref]$null = $internal_params.Remove('PublicApp') - [ref]$null = $internal_params.Add('PublicApp',$intune_app) - } - } - } - Process{ - $access_token = Get-MonkeyMSALToken @internal_params -Resource $AzureEnvironment.GraphV2; - } - End{ - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Endpoint Manager") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Endpoint Manager") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForMicrosoft365AdminPortal.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForMicrosoft365AdminPortal.ps1 deleted file mode 100644 index f122cda0..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForMicrosoft365AdminPortal.ps1 +++ /dev/null @@ -1,203 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForMicrosoft365AdminPortal{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForMicrosoft365AdminPortal - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - Write-Warning -Message ($Script:messages.NotAllowedToAuth -f "Microsoft 365 admin portal") - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $access_token = Get-MonkeyMSALToken @internal_params -Resource $AzureEnvironment.OfficeAdminPortal; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Microsoft 365 admin portal") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Microsoft 365 admin portal") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForPIM.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForPIM.ps1 deleted file mode 100644 index 8b378e37..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForPIM.ps1 +++ /dev/null @@ -1,202 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForPIM{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForPIM - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $PIMWellKnownId = Get-WellKnownAzureService -AzureService MSPIM - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $access_token = Get-MonkeyMSALToken @internal_params -Resource $PIMWellKnownId; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Azure AD Privileged Identity Management") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Azure AD Privileged Identity Management") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForPowerBI.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForPowerBI.ps1 deleted file mode 100644 index c6e48b0c..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForPowerBI.ps1 +++ /dev/null @@ -1,208 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForPowerBI{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForPowerBI - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - if($PSBoundParameters.ContainsKey('Endpoint') -and $PSBoundParameters['Endpoint']){ - $resource = $PSBoundParameters['Endpoint'] - } - else{ - $resource = $AzureEnvironment.PowerBI - } - $access_token = Get-MonkeyMSALToken @internal_params -Resource $resource; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Microsoft Power BI") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Microsoft Power BI") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForResource.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForResource.ps1 deleted file mode 100644 index 195ae143..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForResource.ps1 +++ /dev/null @@ -1,208 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForResource{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForResource - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - $Verbose = $Debug = $False; - $InformationAction = 'SilentlyContinue' - if($PSBoundParameters.ContainsKey('Verbose') -and $PSBoundParameters.Verbose){ - $Verbose = $True - } - if($PSBoundParameters.ContainsKey('Debug') -and $PSBoundParameters.Debug){ - $Debug = $True - } - if($PSBoundParameters.ContainsKey('InformationAction')){ - $InformationAction = $PSBoundParameters['InformationAction'] - } - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = @{} - foreach ($param in $PSBoundParameters.GetEnumerator()){ - $internal_params.add($param.Key, $param.Value) - } - if($isPublicApp -eq $false -or $ConfidentialApp){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - #Get access token - $access_token = Get-MonkeyMSALToken @internal_params; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f $Resource) - Tags = @('MSALSuccessAuth'); - InformationAction = $InformationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f $Resource) - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForResourceManagement.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForResourceManagement.ps1 deleted file mode 100644 index 4c5c936d..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForResourceManagement.ps1 +++ /dev/null @@ -1,201 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForResourceManagement{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForResourceManagement - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $access_token = Get-MonkeyMSALToken @internal_params -Resource $AzureEnvironment.ResourceManager; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Resource Management") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Resource Management") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForServiceManagement.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForServiceManagement.ps1 deleted file mode 100644 index e5c9f328..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForServiceManagement.ps1 +++ /dev/null @@ -1,201 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForServiceManagement{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForServiceManagement - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Process{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $access_token = Get-MonkeyMSALToken @internal_params -Resource $AzureEnvironment.Servicemanagement; - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Service Management") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Service Management") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForSharepointOnline.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForSharepointOnline.ps1 deleted file mode 100644 index a6e884ff..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForSharepointOnline.ps1 +++ /dev/null @@ -1,207 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForSharePointOnline { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForSharePointOnline - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Begin{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $sps_login = $null - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $auth_params = Get-MSALAuthParam -parameters $internal_params - } - Process{ - #Get Auth token - $sps_login = Get-MonkeyMSALToken @auth_params - } - End{ - if($null -ne $sps_login -and $sps_login -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "SharePoint Online") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $sps_login - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "SharePoint Online") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForTeams.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForTeams.ps1 deleted file mode 100644 index 2f44cd2d..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MSALTokenForTeams.ps1 +++ /dev/null @@ -1,207 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MSALTokenForTeams{ - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MSALTokenForTeams - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Begin{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $TeamsApiWellKnownId = Get-WellKnownAzureService -AzureService TeamsAdminApi - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - Write-Warning -Message ($Script:messages.NotAllowedToAuth -f "Microsoft Teams") - } - } - Process{ - $access_token = Get-MonkeyMSALToken @internal_params -Resource $TeamsApiWellKnownId; - } - End{ - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Microsoft Teams") - Tags = @('MSALSuccessAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - return $access_token - } - else{ - #Write message - Write-Warning -Message ($Script:messages.UnableToGetToken -f "Microsoft Teams") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MonkeyMSALPSSessionForComplianceCenter.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MonkeyMSALPSSessionForComplianceCenter.ps1 deleted file mode 100644 index 9e593008..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MonkeyMSALPSSessionForComplianceCenter.ps1 +++ /dev/null @@ -1,313 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MonkeyMSALPSSessionForComplianceCenter { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MonkeyMSALPSSessionForComplianceCenter - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Begin{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $ComplianceSession = $null - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false -or $ConfidentialApp){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - Write-Warning -Message ($Script:messages.NotAllowedToAuth -f $AzureEnvironment.ComplianceCenter) - } - #Set clientId - if($null -ne $PublicApp -and $PublicApp -is [Microsoft.Identity.Client.PublicClientApplication]){ - if($PublicApp.AppConfig.ClientId -ne (Get-WellKnownAzureService -AzureService ExchangeOnlineV2)){ - #Add clientId and RedirectUri - $app_param = @{} - $app_param.ClientId = (Get-WellKnownAzureService -AzureService ExchangeOnlineV2) - if($PSEdition -eq "Desktop"){ - $app_param.RedirectUri = (Get-MonkeyExoRedirectUri -Environment $Environment) - } - if($PSBoundParameters.ContainsKey('TenantId')){ - $app_param.TenantId = $TenantId - } - $exo_app = New-MonkeyMsalApplication @app_param - [ref]$null = $internal_params.Remove('PublicApp') - [ref]$null = $internal_params.Add('PublicApp',$exo_app) - } - } - #Add resource - $internal_params.Add('Resource',$AzureEnvironment.Outlook) - } - Process{ - $Ctoken = $null - $exo_login = Get-MonkeyMSALToken @internal_params - #Add info to Token - if($null -ne $exo_login -and $exo_login -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Get TenantId - if(-NOT $internal_params.ContainsKey("TenantId") -and -NOT $TenantId){ - $TenantId = $exo_login.TenantId - } - #Check if interactive or client credentials - if($isPublicApp -eq $false -or $ConfidentialApp){ - $tenantName = $null - #Get Tenant Info - $internal_params.Resource = $AzureEnvironment.Graphv2 - $access_token = Get-MonkeyMSALToken @internal_params - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - $Tenant = Get-MSGraphOrganization -AuthObject $access_token - if($null -eq $Tenant){ - if($TenantId -and (Test-IsValidTenantId -TenantId $TenantId) -eq $false){ - #Potential domain name is passed as TenantId - $tenantName = $TenantId; - } - else{ - Write-Warning $Script:messages.TenantGuidError; - $tenantName = $null; - } - } - else{ - $tenantName = Get-DefaultTenantName -TenantDetails $Tenant - } - } - if($null -ne $tenantName){ - #Create PSSession - $Authorization = $exo_login.CreateAuthorizationHeader() - $Password = ConvertTo-SecureString -AsPlainText $Authorization -Force - $UPN = ("MonkeyUser@{0}" -f $tenantName) - $Ctoken = New-Object System.Management.Automation.PSCredential -ArgumentList $UPN, $Password - } - else{ - Write-Warning "Missing Tenant name" - $Ctoken= $null - } - } - else{ - #Get userPrincipalName - $userPrincipalName = $exo_login.Account.Username - if($userPrincipalName){ - #Create PSSession - $Authorization = $exo_login.CreateAuthorizationHeader() - $Password = ConvertTo-SecureString -AsPlainText $Authorization -Force - $Ctoken = New-Object System.Management.Automation.PSCredential -ArgumentList $userPrincipalName, $Password - } - else{ - Write-Verbose -Message $Script:messages.UnableToGetUPN - } - } - #Try to create a valid PSSession - if($null -ne $Ctoken){ - $params = @{ - ConfigurationName = 'Microsoft.Exchange' - ConnectionUri = ("{0}?BasicAuthToOAuthConversion=true" -f $AzureEnvironment.ComplianceCenter) - Credential = $Ctoken - Authentication = "Basic" - AllowRedirection = $true - ErrorAction = "Stop" - } - try{ - $ComplianceSession = New-PSSession @params - } - catch{ - #https://github.com/PowerShell/PowerShell/issues/7567 - #On linux systems, it seems that after receiving 302 response, no further request was sent - Write-Verbose -Message $_ - } - } - } - } - End{ - if($null -ne $ComplianceSession -and $ComplianceSession -is [System.Management.Automation.Runspaces.PSSession]){ - #Write message - $msg = @{ - MessageData = ($Script:messages.TokenAcquiredInfoMessage -f "Exchange Compliance Center"); - InformationAction = $InformationAction; - Tags = @('MSALComplianceCenterAuth'); - } - Write-Information @msg - #Add Expiration time - $ComplianceSession | Add-Member -type NoteProperty -name ExpiresOn_ -value ([System.DateTimeOffset]::Now.AddMinutes(60)) -Force - #Add renewable option - $ComplianceSession | Add-Member -type NoteProperty -name renewable -value $true -Force - #Add function to check for near expiration - $ComplianceSession | Add-Member -Type ScriptMethod -Name IsNearExpiry -Value { - return (($this.ExpiresOn_.UtcDateTime.AddMinutes(-5)) -le ((Get-Date).ToUniversalTime())) - } - #Add function to disable token renewal - $ComplianceSession | Add-Member -Type ScriptMethod -Name DisableRenew -Value { - $this.renewable = $false - } - return $ComplianceSession - } - else{ - Write-Warning -Message ($Script:messages.ConnectionError -f "Exchange Compliance Center") - return $null - } - } -} diff --git a/core/modules/monkeymsalauthassistant/public/Get-MonkeyMSALPSSessionForExchangeOnline.ps1 b/core/modules/monkeymsalauthassistant/public/Get-MonkeyMSALPSSessionForExchangeOnline.ps1 deleted file mode 100644 index 9c2bfed8..00000000 --- a/core/modules/monkeymsalauthassistant/public/Get-MonkeyMSALPSSessionForExchangeOnline.ps1 +++ /dev/null @@ -1,311 +0,0 @@ -# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -Function Get-MonkeyMSALPSSessionForExchangeOnline { - <# - .SYNOPSIS - - .DESCRIPTION - - .INPUTS - - .OUTPUTS - - .EXAMPLE - - .NOTES - Author : Juan Garrido - Twitter : @tr1ana - File Name : Get-MonkeyMSALPSSessionForExchangeOnline - Version : 1.0 - - .LINK - https://github.com/silverhack/monkey365 - #> - - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "", Scope="Function")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueForMandatoryParameter", "", Scope="Function")] - [CmdletBinding()] - Param ( - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth', HelpMessage = 'Application Id')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage = 'Application Id')] - [String]$ClientId = "1950a258-227b-4e31-a9cf-717495945fc2", - - [parameter(Mandatory= $false, ParameterSetName = 'Implicit', HelpMessage= "User for access to the O365 services")] - [String]$UserPrincipalName, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [System.Management.Automation.PSCredential]$UserCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App', HelpMessage = 'Client Secret')] - [Security.SecureString]$ClientSecret = [Security.SecureString]::new(), - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject', HelpMessage = 'PsCredential')] - [Alias('client_credentials')] - [ValidateNotNull()] - [System.Management.Automation.PSCredential]$ClientCredentials, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate file path')] - [ValidateScript( - { - if( -Not ($_ | Test-Path) ){ - throw ("The cert file does not exist in {0}" -f (Split-Path -Path $_)) - } - if(-Not ($_ | Test-Path -PathType Leaf) ){ - throw "The argument must be a PFX file. Folder paths are not allowed." - } - if($_ -notmatch "(\.pfx)"){ - throw "The certificate specified argument must be of type pfx" - } - return $true - })] - [System.IO.FileInfo]$Certificate, - - [Parameter(Mandatory = $false,ParameterSetName = 'ClientAssertionCertificate-File', HelpMessage = 'Certificate password')] - [Security.SecureString]$CertficatePassword, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate', HelpMessage = 'Client assertion certificate')] - [System.Security.Cryptography.X509Certificates.X509Certificate2]$ClientAssertionCertificate, - - [parameter(Mandatory=$false, HelpMessage = 'Redirect URI')] - [System.Uri]$RedirectUri, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $true, ParameterSetName = 'ClientAssertionCertificate-File')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [String]$TenantId, - - [parameter(Mandatory=$false, HelpMessage = 'Environment')] - [Microsoft.Identity.Client.AzureCloudInstance]$Environment = [Microsoft.Identity.Client.AzureCloudInstance]::AzurePublic, - - [parameter(Mandatory=$false, HelpMessage = 'Instance')] - [String]$Instance, - - [parameter(Mandatory=$false, HelpMessage = 'Authority')] - [System.Uri]$Authority, - - [Parameter(Mandatory = $true, ParameterSetName = 'Implicit-PublicApplication')] - [Microsoft.Identity.Client.IPublicClientApplication] $PublicApp, - - [Parameter(Mandatory = $true, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Microsoft.Identity.Client.IConfidentialClientApplication] $ConfidentialApp, - - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientSecret-AuthorizationCode')] - [Parameter(Mandatory = $true, ParameterSetName = 'ConfidentialClientCertificate-AuthorizationCode')] - [String] $AuthorizationCode, - - [parameter(Mandatory= $false, HelpMessage= "Resource to connect")] - [String]$Resource, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [ValidateSet("SelectAccount", "NoPrompt", "Never", "ForceLogin")] - [String] $PromptBehavior = 'SelectAccount', - - # Ignore any access token in the user token cache and attempt to acquire new access token using the refresh token for the account if one is available. - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-ConfidentialApp')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-App')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientSecret-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate')] - [Parameter(Mandatory = $false, ParameterSetName = 'ClientAssertionCertificate-File')] - [Switch]$ForceRefresh, - - [Parameter(Mandatory=$false, HelpMessage="scopes")] - [Array]$Scopes, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String[]] $ExtraScopesToConsent, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch] $IntegratedWindowsAuth, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-IntegratedWindowsAuth')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject')] - [String] $LoginHint, - - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit')] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication', HelpMessage="Device code authentication")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-InputObject', HelpMessage="Device code authentication")] - [Switch]$DeviceCode, - - [Parameter(Mandatory=$false, HelpMessage="Force silent authentication")] - [Switch]$Silent, - - [Parameter(Mandatory=$false, ParameterSetName = 'Implicit', HelpMessage="Force Authentication Context. Only valid for user&password auth method")] - [Parameter(Mandatory = $false, ParameterSetName = 'Implicit-PublicApplication')] - [Switch]$ForceAuth - ) - Begin{ - #Get InformationAction - if($PSBoundParameters.ContainsKey('InformationAction')){ - $informationAction = $PSBoundParameters.informationAction - } - else{ - $informationAction = "SilentlyContinue" - } - $AzureEnvironment = Get-MonkeyEnvironment -Environment $Environment - $isPublicApp = Confirm-IfMSALPublicApp -parameters $PSBoundParameters - $internal_params = $PSBoundParameters - if($isPublicApp -eq $false){ - #Remove common params - $internal_params = Remove-MSALPublicParam -parameters $internal_params - } - $EXOSession = $null - #Set clientId - if($null -ne $PublicApp -and $PublicApp -is [Microsoft.Identity.Client.PublicClientApplication]){ - if($PublicApp.AppConfig.ClientId -ne (Get-WellKnownAzureService -AzureService ExchangeOnlineV2)){ - #Add clientId and RedirectUri - $app_param = @{} - $app_param.ClientId = (Get-WellKnownAzureService -AzureService ExchangeOnlineV2) - if($PSEdition -eq "Desktop"){ - $app_param.RedirectUri = (Get-MonkeyExoRedirectUri -Environment $MyParams.Environment) - } - if($PSBoundParameters.ContainsKey('TenantId')){ - $app_param.TenantId = $TenantId - } - $exo_app = New-MonkeyMsalApplication @app_param - [ref]$null = $internal_params.Remove('PublicApp') - [ref]$null = $internal_params.Add('PublicApp',$exo_app) - } - } - #Add resource - $internal_params.Add('Resource',$AzureEnvironment.Outlook) - } - Process{ - $Ctoken = $null - $exo_login = Get-MonkeyMSALToken @internal_params - #Add info to Token - if($null -ne $exo_login -and $exo_login -is [Microsoft.Identity.Client.AuthenticationResult]){ - #Get TenantId - if(-NOT $internal_params.ContainsKey("TenantId") -and -NOT $TenantId){ - $TenantId = $exo_login.TenantId - } - #Check if interactive or client credentials - if($isPublicApp -eq $false){ - $tenantName = $null - #Get Tenant Info - $internal_params.Resource = $AzureEnvironment.Graphv2 - $access_token = Get-MonkeyMSALToken @internal_params - if($null -ne $access_token -and $access_token -is [Microsoft.Identity.Client.AuthenticationResult]){ - $Tenant = Get-MSGraphOrganization -AuthObject $access_token - if($null -eq $Tenant){ - if($TenantId -and (Test-IsValidTenantId -TenantId $TenantId) -eq $false){ - #Potential domain name is passed as TenantId - $tenantName = $TenantId; - } - else{ - Write-Warning $Script:messages.TenantGuidError; - $tenantName = $null; - } - } - else{ - $tenantName = Get-DefaultTenantName -TenantDetails $Tenant - } - } - if($null -ne $tenantName){ - #Create PSSession - $Authorization = $exo_login.CreateAuthorizationHeader() - $Password = ConvertTo-SecureString -AsPlainText $Authorization -Force - $UPN = ("MonkeyUser@{0}" -f $tenantName) - $Ctoken = New-Object System.Management.Automation.PSCredential -ArgumentList $UPN, $Password - } - else{ - Write-Warning "Missing TenantName" - $Ctoken= $null - } - } - else{ - #Get userPrincipalName - $userPrincipalName = $exo_login.Account.Username - if($userPrincipalName){ - #Create PSSession - $Authorization = $exo_login.CreateAuthorizationHeader() - $Password = ConvertTo-SecureString -AsPlainText $Authorization -Force - $Ctoken = New-Object System.Management.Automation.PSCredential -ArgumentList $userPrincipalName, $Password - } - else{ - Write-Verbose -Message $Script:messages.UnableToGetUPN - } - } - #Try to create a valid PSSession - if($null -ne $Ctoken){ - $params = @{ - ConfigurationName = 'Microsoft.Exchange' - ConnectionUri = ("{0}?BasicAuthToOAuthConversion=true" -f $AzureEnvironment.ExchangeOnline) - Credential = $Ctoken - Authentication = "Basic" - AllowRedirection = $true - ErrorAction = "Stop" - } - try{ - $EXOSession = New-PSSession @params - } - catch{ - Write-Verbose -Message $_ - } - } - } - } - End{ - if($null -ne $EXOSession -and $EXOSession -is [System.Management.Automation.Runspaces.PSSession]){ - #Write message - $msg = @{ - MessageData = $Script:messages.EXOSuccessfullyConnected; - Tags = @('MSALEXOAuth'); - InformationAction = $informationAction; - } - Write-Information @msg - #Add Expiration time - $EXOSession | Add-Member -type NoteProperty -name ExpiresOn_ -value ([System.DateTimeOffset]::Now.AddMinutes(60)) -Force - #Add renewable option - $EXOSession | Add-Member -type NoteProperty -name renewable -value $true -Force - #Add function to check for near expiration - $EXOSession | Add-Member -Type ScriptMethod -Name IsNearExpiry -Value { - return (($this.ExpiresOn_.UtcDateTime.AddMinutes(-5)) -le ((Get-Date).ToUniversalTime())) - } - #Add function to disable token renewal - $EXOSession | Add-Member -Type ScriptMethod -Name DisableRenew -Value { - $this.renewable = $false - } - return $EXOSession - } - else{ - #Write message - Write-Warning $Script:messages.EXOErrorConnection - return $null - } - } -} diff --git a/core/modules/monkeyruleset/Localized/en-US/monkeyruleset.psd1 b/core/modules/monkeyruleset/Localized/en-US/monkeyruleset.psd1 index 1358db75..36cd76f2 100644 --- a/core/modules/monkeyruleset/Localized/en-US/monkeyruleset.psd1 +++ b/core/modules/monkeyruleset/Localized/en-US/monkeyruleset.psd1 @@ -27,6 +27,7 @@ BuildQueryErrorMessage = Unable to build query for {0} ElementNotFound = Unable to find element {0} on object UpdatingComlianceMessage = Updating compliance for {0} rule + UpdatingPropertyMessage = Updating {0} for {1} rule FailedQueryMessage = The "{0}" query failed to complete its execution on "{1}" rule UnitItemNotFound = Removing rules for "{0}" as it was not found on dataset FalsePositiveDetected = Potentially false positive detected on "{0}" diff --git a/core/modules/monkeyruleset/Localized/monkeyruleset.psd1 b/core/modules/monkeyruleset/Localized/monkeyruleset.psd1 index 1358db75..36cd76f2 100644 --- a/core/modules/monkeyruleset/Localized/monkeyruleset.psd1 +++ b/core/modules/monkeyruleset/Localized/monkeyruleset.psd1 @@ -27,6 +27,7 @@ BuildQueryErrorMessage = Unable to build query for {0} ElementNotFound = Unable to find element {0} on object UpdatingComlianceMessage = Updating compliance for {0} rule + UpdatingPropertyMessage = Updating {0} for {1} rule FailedQueryMessage = The "{0}" query failed to complete its execution on "{1}" rule UnitItemNotFound = Removing rules for "{0}" as it was not found on dataset FalsePositiveDetected = Potentially false positive detected on "{0}" diff --git a/core/modules/monkeyruleset/private/Get-File.ps1 b/core/modules/monkeyruleset/private/Get-File.ps1 index c8142b72..b8feca30 100644 --- a/core/modules/monkeyruleset/private/Get-File.ps1 +++ b/core/modules/monkeyruleset/private/Get-File.ps1 @@ -75,16 +75,16 @@ Function Get-File{ if(@($file).Count -gt 0){ if($PSCmdlet.ParameterSetName -eq 'Filename'){ If(@($file).Count -eq 1){ - return $file + $file } else{ Write-Warning -Message ($Script:messages.DuplicateFileFound -f $fileName, $rulepath) #return full name - return ($file | Select-Object -First 1) + ($file | Select-Object -First 1) } } else{ - return $file + $file } } else{ diff --git a/core/modules/monkeyruleset/private/Get-MonkeyRule.ps1 b/core/modules/monkeyruleset/private/Get-MonkeyRule.ps1 index 1fecbe49..15073d1d 100644 --- a/core/modules/monkeyruleset/private/Get-MonkeyRule.ps1 +++ b/core/modules/monkeyruleset/private/Get-MonkeyRule.ps1 @@ -54,10 +54,20 @@ Function Get-MonkeyRule{ if($ValidRule){ foreach ($element in $Rule.Value){ $raw_rule = (Get-Content $Rule.File.FullName -Raw) + #Check for args $found_args = $element | Select-Object -ExpandProperty args -ErrorAction Ignore + #Check for level $level = $element | Select-Object -ExpandProperty level -ErrorAction Ignore + #Check if rule enabled $is_rule_enabled = $element | Select-Object -ExpandProperty enabled -ErrorAction Ignore + #Check for displayName + $displayName = $element | Select-Object -ExpandProperty displayName -ErrorAction Ignore + #Check for compliance $compliance = $element | Select-Object -ExpandProperty compliance -ErrorAction Ignore + #Check for description + $description = $element | Select-Object -ExpandProperty description -ErrorAction Ignore + #Check for rationale + $rationale = $element | Select-Object -ExpandProperty rationale -ErrorAction Ignore if($null -ne $is_rule_enabled -and $is_rule_enabled){ if($null -ne $found_args){ $count = 0; @@ -88,11 +98,26 @@ Function Get-MonkeyRule{ else{ #nothing to do here } - #Updating Compliance + #Update displayName + if($null -ne $displayName){ + Write-Verbose -Message ($Script:messages.UpdatingPropertyMessage -f "displayName", $Rule.File.Name) + $new_json_rule | Add-Member -Type NoteProperty -name displayName -value $displayName -Force + } + #Update Compliance if($null -ne $compliance){ Write-Verbose -Message ($Script:messages.UpdatingComlianceMessage -f $Rule.File.Name) $new_json_rule | Add-Member -Type NoteProperty -name compliance -value $compliance -Force } + #Update description + if($null -ne $description){ + Write-Verbose -Message ($Script:messages.UpdatingPropertyMessage -f "description", $Rule.File.Name) + $new_json_rule | Add-Member -Type NoteProperty -name description -value $description -Force + } + #Update rationale + if($null -ne $rationale){ + Write-Verbose -Message ($Script:messages.UpdatingPropertyMessage -f "rationale", $Rule.File.Name) + $new_json_rule | Add-Member -Type NoteProperty -name rationale -value $rationale -Force + } #Add file $new_json_rule | Add-Member -Type NoteProperty -name File -value $Rule.File -Force #return rule diff --git a/core/modules/monkeyruleset/private/Get-RuleFileContent.ps1 b/core/modules/monkeyruleset/private/Get-RuleFileContent.ps1 new file mode 100644 index 00000000..59a4d673 --- /dev/null +++ b/core/modules/monkeyruleset/private/Get-RuleFileContent.ps1 @@ -0,0 +1,66 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +Function Get-RuleFileContent{ + <# + .SYNOPSIS + + .DESCRIPTION + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-RuleFileContent + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + [CmdletBinding()] + Param ( + [parameter(Mandatory=$true, ValueFromPipeline = $True, HelpMessage="File")] + [Object]$InputObject + ) + Process{ + $fContent = $null; + Try{ + if($InputObject -isnot [System.IO.FileSystemInfo]){ + If ($InputObject.GetType() -eq [System.Management.Automation.PSCustomObject] -or $InputObject.GetType() -eq [System.Management.Automation.PSObject] -and $null -ne $InputObject.Psobject.Properties.Item('FullName')){ + $fContent = (Get-Content $InputObject.FullName -Raw) | ConvertFrom-Json; + } + Else{ + #Content is not valid + $fContent = $null; + } + } + Else{ + $fContent = (Get-Content $InputObject.FullName -Raw) | ConvertFrom-Json; + } + #Test if content if valid content + if ($null -ne $fContent -and ($fContent | Test-isValidRule)){ + $fContent | Add-Member -Type NoteProperty -name File -value $InputObject -Force; + Write-Output $fContent + } + } + Catch{ + Write-Error $_ + } + } +} diff --git a/core/modules/monkeyruleset/private/Test-isValidRule.ps1 b/core/modules/monkeyruleset/private/Test-isValidRule.ps1 index f06583be..4e1ea1ff 100644 --- a/core/modules/monkeyruleset/private/Test-isValidRule.ps1 +++ b/core/modules/monkeyruleset/private/Test-isValidRule.ps1 @@ -75,8 +75,11 @@ Function Test-isValidRule{ } else{ $missing = @($missingElements) -join ',' + if($null -ne $InputObject.PsObject.Properties.Item('displayName')){ + Write-Warning ($Script:messages.InvalidRuleMessage -f $InputObject.displayName) + } Write-Warning ($Script:messages.MissingElementsMessage -f "rule", $missing) return $false } } -} +} \ No newline at end of file diff --git a/core/modules/monkeyruleset/public/Get-Framework.ps1 b/core/modules/monkeyruleset/public/Get-Framework.ps1 index 046ccd02..addfd7c4 100644 --- a/core/modules/monkeyruleset/public/Get-Framework.ps1 +++ b/core/modules/monkeyruleset/public/Get-Framework.ps1 @@ -34,7 +34,7 @@ Function Get-Framework{ .LINK https://github.com/silverhack/monkey365 #> - [CmdletBinding()] + [CmdletBinding(DefaultParameterSetName = 'Current')] Param ( [parameter(Mandatory= $true, ParameterSetName='RuleSet', HelpMessage= "json file with all rules")] [ValidateScript({ @@ -61,10 +61,7 @@ Function Get-Framework{ } return $true })] - [System.IO.DirectoryInfo]$RulesPath, - - [Parameter(Mandatory=$true, ParameterSetName='Current', HelpMessage="Current framework")] - [Switch]$Current + [System.IO.DirectoryInfo]$RulesPath ) try{ #Set colors diff --git a/core/modules/monkeyruleset/public/Get-Rule.ps1 b/core/modules/monkeyruleset/public/Get-Rule.ps1 index b53a26ec..756d0bc7 100644 --- a/core/modules/monkeyruleset/public/Get-Rule.ps1 +++ b/core/modules/monkeyruleset/public/Get-Rule.ps1 @@ -78,7 +78,7 @@ Function Get-Rule{ [Switch]$Pretty ) Begin{ - $MyRules = $null; + $MyRules = $mrules = $null; $colors = [ordered]@{ info = 36; low = 34; @@ -107,36 +107,45 @@ Function Get-Rule{ if($PSBoundParameters.ContainsKey('InformationAction')){ $InformationAction = $PSBoundParameters['InformationAction'] } + #Get Command metadata + $MetaData = New-Object -TypeName "System.Management.Automation.CommandMetaData" (Get-Command -Name "Initialize-MonkeyRuleset") + $newPsboundParams = [ordered]@{} + if($null -ne $MetaData){ + $param = $MetaData.Parameters.Keys + foreach($p in $param.GetEnumerator()){ + if($PSBoundParameters.ContainsKey($p) -and $PSBoundParameters[$p]){ + $newPsboundParams.Add($p,$PSBoundParameters[$p]) + } + } + } + #Add verbose, debug + $newPsboundParams.Add('Verbose',$Verbose) + $newPsboundParams.Add('Debug',$Debug) + $newPsboundParams.Add('InformationAction',$InformationAction) } Process{ - If(($PSBoundParameters.ContainsKey('RulesPath') -and $PSBoundParameters['RulesPath']) -and ($PSBoundParameters.ContainsKey('RuleSet') -and $PSBoundParameters['RuleSet'])){ + If($newPsboundParams.Count -eq 5){ #Remove vars Remove-InternalVar - $p = @{ - Ruleset = $PSBoundParameters['RuleSet']; - RulesPath = $PSBoundParameters['RulesPath']; - Verbose = $Verbose; - Debug = $Debug; - InformationAction = $InformationAction; - } - [void](Initialize-MonkeyRuleset @p) + #Initialize Ruleset + [void](Initialize-MonkeyRuleset @newPsboundParams) } try{ - if($null -ne (Get-Variable -Name AllRules -ErrorAction Ignore)){ - $MyRules = $Script:AllRules - } - Elseif($PSBoundParameters.ContainsKey('RulesPath') -and $PSBoundParameters['RulesPath']){ + If($PSBoundParameters.ContainsKey('RulesPath') -and $PSBoundParameters['RulesPath'] -and !$PSBoundParameters.ContainsKey('RuleSet')){ if($RulesPath.GetDirectories('findings').Count -gt 0){ $findingsPath = $RulesPath.GetDirectories('findings') $all_rules = Get-File -Filter "*json" -Rulepath $findingsPath.FullName.ToString() $all_rules = $all_rules | Select-Object * -Unique #Get rule info - $MyRules = @($all_rules).ForEach({$r = (Get-Content $_.FullName -Raw) | ConvertFrom-Json; if ($r | Test-isValidRule){$r | Add-Member -Type NoteProperty -name File -value $_ -Force; $r}}) + $MyRules = $all_rules | Get-RuleFileContent #@($all_rules).ForEach({$r = (Get-Content $_.FullName -Raw) | ConvertFrom-Json; if ($r | Test-isValidRule){$r | Add-Member -Type NoteProperty -name File -value $_ -Force; $r}}) } else{ Write-Warning ("Findings folder was not found on {0}" -f $RulesPath.FullName) } } + ElseIf($null -ne (Get-Variable -Name AllRules -ErrorAction Ignore)){ + $MyRules = $Script:AllRules + } } catch{ Write-Verbose $_.Exception.Message @@ -147,6 +156,7 @@ Function Get-Rule{ if($null -ne $MyRules){ if($PSBoundParameters.ContainsKey('Full') -and $PSBoundParameters['Full'].IsPresent){ $MyRules + return } elseif($PSBoundParameters.ContainsKey('RuleSet') -and $PSBoundParameters['RuleSet']){ $mrules = $MyRules | Select-Object displayName,serviceType,level,IdSuffix @@ -172,7 +182,7 @@ Function Get-Rule{ $maxWidthType = $mrules | Select-Object -ExpandProperty serviceType | Group-Object {$_.Length} | Select-Object -ExpandProperty Name | Measure-Object -Maximum | Select-Object -ExpandProperty Maximum $Name = @{label="Rule Name";expression={$_.displayName};Width = [int]$maxWidthName-50}; $ResourceName = @{label="Service";expression={$_.serviceType};Width = [int]$maxWidthType}; - $Level = @{label="Level";expression={$_.level};Width = 12} + $Level = @{label="Risk";expression={$_.level};Width = 12} $IdSuffix = @{label="Id";expression={$_.idSuffix}} if($null -eq (Get-Variable -Name psISE -ErrorAction Ignore)){ foreach($r in $mrules){ diff --git a/core/modules/monkeyutils/monkeyutils.psd1 b/core/modules/monkeyutils/monkeyutils.psd1 index a07046e4..503a0f65 100644 Binary files a/core/modules/monkeyutils/monkeyutils.psd1 and b/core/modules/monkeyutils/monkeyutils.psd1 differ diff --git a/core/modules/monkeyutils/public/Get-MonkeyDuplicateObjectsByProperty.ps1 b/core/modules/monkeyutils/public/Get-MonkeyDuplicateObjectsByProperty.ps1 new file mode 100644 index 00000000..7f3cd9e3 --- /dev/null +++ b/core/modules/monkeyutils/public/Get-MonkeyDuplicateObjectsByProperty.ps1 @@ -0,0 +1,74 @@ +# Monkey365 - the PowerShell Cloud Security Tool for Azure and Microsoft 365 (copyright 2022) by Juan Garrido +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +Function Get-MonkeyDuplicateObjectsByProperty{ + <# + .SYNOPSIS + Get duplicate objects based on specific property + + .DESCRIPTION + Get duplicate objects based on specific property + + .INPUTS + + .OUTPUTS + + .EXAMPLE + + .NOTES + Author : Juan Garrido + Twitter : @tr1ana + File Name : Get-MonkeyDuplicateObjectsByProperty + Version : 1.0 + + .LINK + https://github.com/silverhack/monkey365 + #> + [CmdletBinding()] + Param ( + [parameter(Mandatory=$true, HelpMessage="Reference Object")] + [System.Collections.Generic.List[System.Management.Automation.PSObject]]$ReferenceObject, + + [parameter(Mandatory=$true, HelpMessage="Object Property")] + [String]$Property + ) + Process{ + $duplicateObjects = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new(); + Try{ + $Objects = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new(); + #Iterate objects + Foreach($obj in $ReferenceObject){ + if($Objects.Count -gt 0){ + $match = $Objects.Where({$_.$($Property) -eq $obj.$($Property)}) + if($match){ + Write-Verbose -Message ("duplicate entry found {0}" -f $obj.$($Property)); + [void]$duplicateObjects.Add($obj) + } + else{ + [void]$Objects.Add($obj) + } + } + Else{ + [void]$Objects.Add($obj) + } + } + return $duplicateObjects + } + Catch{ + Write-Error $_ + return , $duplicateObjects + } + } +} \ No newline at end of file diff --git a/core/modules/monkeyutils/public/Out-JSON.ps1 b/core/modules/monkeyutils/public/Out-JSON.ps1 index 6bf90172..2eafeb86 100644 --- a/core/modules/monkeyutils/public/Out-JSON.ps1 +++ b/core/modules/monkeyutils/public/Out-JSON.ps1 @@ -49,7 +49,7 @@ Function Out-JSON{ } catch{ Write-Debug $_ - Write-Error ($script:messages.UnableToExportObject -f $OutFile) + Write-Debug ($script:messages.UnableToExportObject -f $OutFile) } } } diff --git a/core/output/Export-MonkeyData.ps1 b/core/output/Export-MonkeyData.ps1 index ab25538c..71b48e55 100644 --- a/core/output/Export-MonkeyData.ps1 +++ b/core/output/Export-MonkeyData.ps1 @@ -134,10 +134,6 @@ Function Export-MonkeyData{ } } } - 'EXCEL' - { - Invoke-DumpExcel -ObjectData $MonkeyExportObject.Output - } "HTML" { $out_folder = ('{0}/{1}' -f $Script:Report, $ExportTo.ToLower()) diff --git a/core/utils/localized.psd1 b/core/utils/localized.psd1 index 2cf9e0d1..a43c7f86 100644 --- a/core/utils/localized.psd1 +++ b/core/utils/localized.psd1 @@ -132,7 +132,7 @@ SharepointSubSitesMessage = Getting subsites for {0} SPSObjectErrorMessage = Unable to get object type UnableToSitePropertiesForUser = Unable to get site properties using {0} account GetSitesUsingSharePointSearchApi = Getting sites using SharePoint search api -UnableToGetSubsites = Unable to get sub-sites for {0} +UnableToGetSubsites = Unable to get sub sites for {0} UnableToProcessQuery = Unable to process query on {0} SPSDetailedErrorMessage = {0} SPSAdminErrorMessage = User {0} does not have permission to access SharePoint Online @@ -182,4 +182,5 @@ MSGraphDirectoryObjectError = Unable to get directory objects NotConnectedTo = Not connected to {0} SPNotAllowedAuthFlowErrorMessage = Service principal authentication flow is not supported for {0} CompressingJob = Compressing Monkey data into {0} +TokenAcquiredGenericMessage = A new token was successfully acquired '@; \ No newline at end of file