core/tasks/Initialize-MonkeyScan.ps1
# 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 Initialize-MonkeyScan { <# .SYNOPSIS Sets up a custom configuration, variables and options to create a runspacepool .DESCRIPTION Sets up a custom configuration, variables and options to create a runspacepool .INPUTS .OUTPUTS .EXAMPLE .NOTES Author : Juan Garrido Twitter : @tr1ana File Name : Initialize-MonkeyScan Version : 1.0 .LINK https://github.com/silverhack/monkey365 #> [CmdletBinding()] [OutputType([System.Collections.Generic.List[System.Collections.Hashtable]])] Param ( [parameter(Mandatory=$false, HelpMessage="Provider")] [ValidateSet("Azure","EntraID","Microsoft365")] [String]$Provider = "Azure", [Parameter(Mandatory=$false, HelpMessage="Change the threads settings. Default is 2")] [int32]$Throttle = 2, [Parameter(Mandatory=$false, HelpMessage="ApartmentState of the thread")] [ValidateSet("STA","MTA")] [String]$ApartmentState = "STA" ) Begin{ #Set scans array $all_scans = [System.Collections.Generic.List[System.Collections.Hashtable]]::new(); $scanOptions = $null; #Set lib path $_path = ("{0}{1}core{2}api{3}" -f $O365Object.Localpath,[System.IO.Path]::DirectorySeparatorChar,[System.IO.Path]::DirectorySeparatorChar,[System.IO.Path]::DirectorySeparatorChar) #Get all dirs $all_dirs = Get-MonkeyDirectory -Path $_path -Recurse #Get aad lib $aadlibs = @($all_dirs).Where({$_ -like "*EntraID*"}) #Get Azure lib $azureLib = ("{0}{1}core{2}api{3}azure" -f $O365Object.Localpath,[System.IO.Path]::DirectorySeparatorChar,[System.IO.Path]::DirectorySeparatorChar,[System.IO.Path]::DirectorySeparatorChar) if(-NOT [System.IO.Directory]::Exists($azureLib)){ throw ("Unable to locate Azure lib") } $utilsLib = ("{0}{1}core{2}utils" -f $O365Object.Localpath,[System.IO.Path]::DirectorySeparatorChar,[System.IO.Path]::DirectorySeparatorChar) if(-NOT [System.IO.Directory]::Exists($utilsLib)){ throw ("Unable to locate utils directory") } #Set vars try{ $msg = @{ MessageData = "Setting and getting variables"; callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'info'; InformationAction = $O365Object.InformationAction; Tags = @('Monkey365InitializeScan'); } Write-Information @msg #Set vars $vars = [ordered]@{ O365Object = $O365Object; WriteLog = $O365Object.WriteLog; Verbosity = $O365Object.VerboseOptions; InformationAction = $O365Object.InformationAction; VerbosePreference = $O365Object.VerboseOptions.VerbosePreference; DebugPreference = $O365Object.VerboseOptions.DebugPreference; returnData = $null; LogQueue = $null; } #Get LogQueue $Queue = (Get-Variable -Name MonkeyLogQueue -Scope Global -ErrorAction Ignore); If($null -ne $Queue){ $vars.LogQueue = $Queue.Value; } } catch{ throw ("{0}: {1}" -f "Unable to create var object",$_.Exception.Message) } #Check if collectors are available If($null -eq $O365Object.Collectors){ $abort = $true } Else{ $abort = $false } } Process{ If($abort -eq $false){ switch ($Provider.ToLower()){ { @("azure", "entraid") -contains $_ }{ $libs = [System.Collections.Generic.List[System.String]]::new(); #All of them will have the EntraID lib foreach($lib in $aadlibs){ [void]$libs.Add($lib) } $msg = @{ MessageData = ("Getting collectors for {0}" -f $Provider); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'info'; InformationAction = $O365Object.InformationAction; Tags = @('Monkey365InitializeScan'); } Write-Information @msg if($_ -eq 'entraid'){ $collectors = @($O365Object.Collectors).Where({$_.Provider -eq 'EntraID'}) } else{ $collectors = @($O365Object.Collectors).Where({$_.Provider -eq $Provider}) #Add Azure libs to array [void]$libs.Add($azureLib) } if($collectors.Count -gt 0){ #Get dependsOn $dependsOn = $collectors | Select-Object -ExpandProperty dependsOn if($null -ne $dependsOn){ foreach($depend in @($dependsOn)){ $dependslibs = @($all_dirs).Where({$_ -like ("*{0}*" -f $dependsOn)}) if($dependslibs){ foreach($lib in $dependslibs){ [void]$libs.Add($lib) } } } } #Remove folders $libs = @($libs).Where({($_ -notmatch "helpers") -and ($_ -notmatch "utils") -and ($_ -notmatch "csom" -and $_ -notmatch "rest")}) #Remove duplicate $libs = $libs | Select-Object -Unique #Add utils $libs+=$utilsLib #Get files $libs = $libs | Get-MonkeyFile -Recurse #remove duplicate $libs = $libs | Select-Object -Unique #only ps1 files $libs = @($libs).Where({$_.EndsWith('ps1')}) #Set hashtable $scanOptions = [ordered]@{ scanName = $Provider; modules = $O365Object.runspaces_modules; libCommands = $libs; vars = $vars; threads = $Throttle; collectors = $collectors; apartmentState = $ApartmentState; startUpScripts = $O365Object.runspace_init; } [void]$all_scans.Add($scanOptions); } else{ $msg = @{ MessageData = ("Collectors were not found for {0}" -f $Provider); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'warning'; InformationAction = $O365Object.InformationAction; Tags = @('Monkey365InitializeScan'); } Write-Warning @msg } } 'microsoft365'{ #Group collectors into a single resource $collectors = @($O365Object.Collectors).Where({$_.Provider -ne 'EntraID' -and $_.Provider -ne 'Azure'}) | Group-Object -Property Resource if($null -ne $collectors){ foreach($service in $collectors){ $libs = [System.Collections.Generic.List[System.String]]::new(); #All of them will have the EntraID lib foreach($lib in $aadlibs){ [void]$libs.Add($lib) } $msg = @{ MessageData = ("Getting collectors for {0}" -f $service.Name); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'info'; InformationAction = $O365Object.InformationAction; Tags = @('Monkey365InitializeScan'); } Write-Information @msg $msg = @{ MessageData = ("{0} collector(s) will be loaded within runspace" -f $service.Count); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'info'; InformationAction = $O365Object.InformationAction; Tags = @('Monkey365InitializeScan'); } Write-Information @msg $extralibs = @($all_dirs).Where({$_ -like ("*{0}*" -f $service.Name)}) foreach($lib in $extralibs){ [void]$libs.Add($lib) } #Get dependsOn $dependsOn = $service.Group | Select-Object -ExpandProperty dependsOn if($null -ne $dependsOn){ foreach($depend in @($dependsOn)){ $dependslibs = @($all_dirs).Where({$_ -like ("*{0}*" -f $dependsOn)}) if($dependslibs){ foreach($lib in $dependslibs){ [void]$libs.Add($lib) } } } } $libs = @($libs).Where({($_ -notmatch "helpers") -and ($_ -notmatch "utils") -and ($_ -notmatch "csom" -and $_ -notmatch "rest")}) #Remove duplicate $libs = $libs | Select-Object -Unique #Add utils $libs+=$utilsLib #Get files $libs = $libs | Get-MonkeyFile -Recurse #remove duplicate $libs = $libs | Select-Object -Unique #only ps1 files $libs = @($libs).Where({$_.EndsWith('ps1')}) #Set hashtable $scanOptions = [ordered]@{ scanName = $service.Name; modules = $O365Object.runspaces_modules; libCommands = $libs; vars = $vars; threads = $Throttle; apartmentState = $ApartmentState; collectors = $service.Group; startUpScripts = $O365Object.runspace_init; } [void]$all_scans.Add($scanOptions); } } Else{ $msg = @{ MessageData = ("Collectors were not found for {0}" -f $Provider); callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'warning'; InformationAction = $O365Object.InformationAction; Tags = @('Monkey365InitializeScan'); } Write-Warning @msg } } } } Else{ $msg = @{ MessageData = "Collectors were not found for any provider" callStack = (Get-PSCallStack | Select-Object -First 1); logLevel = 'warning'; InformationAction = $O365Object.InformationAction; Tags = @('Monkey365InitializeScan'); } Write-Warning @msg } } End{ Write-Output $all_scans -NoEnumerate } } |