Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Slack Committ #29

Merged
merged 1 commit into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 227 additions & 0 deletions Scripts/SecretServer/Slack/Discovery/Slack-Discovery.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
<#
Slack User Role Definitions
is_admin = Indicates whether the user is an Admin of the current workspace
is_owner = Indicates whether the user is an Owner of the current workspace.
is_restricted = Indicates whether or not the user is a guest user.
is_ultra_restricted = Indicates whether the restricted user is a single-channel guest.
Is_app_user = Indicates whether the user is an authorized user of the calling app.
Is_bot = Indicates whether the user is actually a bot user. Bleep bloop. Note that Slackbot is special, so is_bot will be false for it.
#>

[string]$baseURL = "https://slack.com"
[string]$api = "$baseURL/api"
[string]$DiscoveryMode = $args[0] #Select "Default" or "Advanced"
[string]$OAuthToken = $args[1]
[string]$adminrole = $args[2]
[string]$svcacctrole = $args[3]


$accessToken = $OauthToken


#Script Constants
[string]$LogFile = "$env:ProgramFiles\Thycotic Software Ltd\Distributed Engine\log\Slack-Discovery.log"
[int32]$LogLevel = 3
[string]$logApplicationHeader = "Slack Discovery"

#region Error Handling Functions
function Write-Log {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[ValidateSet(0,1,2,3)]
[Int32]$ErrorLevel,
[Parameter(Mandatory,ValueFromPipeline)]
[string]$Message
)
# Evaluate Log Level based on global configuration
if ($ErrorLevel -le $LogLevel) {
# Format message
[string]$Timestamp = Get-Date -Format "yyyy-MM-ddThh:mm:sszzz"
switch ($ErrorLevel) {
"0" { [string]$MessageLevel = "INF0 " }
"1" { [string]$MessageLevel = "WARN " }
"2" { [string]$MessageLevel = "ERROR" }
"3" { [string]$MessageLevel = "DEBUG" }
}
# Write Log data
$MessageString = "{0}`t| {1}`t| {2}`t| {3}" -f $Timestamp, $MessageLevel,$logApplicationHeader, $Message
$MessageString | Out-File -FilePath $LogFile -Encoding utf8 -Append -ErrorAction SilentlyContinue
# $Color = @{ 0 = 'Green'; 1 = 'Cyan'; 2 = 'Yellow'; 3 = 'Red'}
# Write-Host -ForegroundColor $Color[$ErrorLevel] -Object ( $DateTime + $Message)
}
}
#endregion Error Handling Functions



#region Slack instance details
# Build headers and get user list
try {

$headers = @{
"Authorization" = "Bearer $accessToken"
"Accept" = "application/json, application/xml"
}

# Get All Active Users
Write-Log -Errorlevel 0 -Message "Obtaining List of Users"
# Specify Slack endpoint uri for Users
$uri = "$api/users.list"

# Specify HTTP method
$method = "get"

# Perform Auth Test
$AuthTest = Invoke-RestMethod "$api/auth.test" -Method $method -Headers $headers

# Send HTTP request
$users = Invoke-RestMethod -Headers $headers -Method $method -Uri $uri
}

catch {
$Err = $_
Write-Log -ErrorLevel 0 -Message "Failed to retrieve User List"
Write-Log -ErrorLevel 2 -Message $Err.Exception
throw $Err.Exception
}
#endregion Slack instance details

<# ## Use for debug logging on returned user attributes

try {
Write-Log -Errorlevel 0 -Message "Parsing List of Users"
Write-Log -ErrorLevel 0 -Message "Successfully found $($users.members.Count) Eligible Accounts"
$admins = $users.members | where-object is_admin -like "True"
Write-Log -ErrorLevel 3 -Message "Successfully found $($admins.members.Count) Admin Accounts"
$owners = $users.members | where-object is_owner -like "True"
Write-Log -ErrorLevel 3 -Message "Successfully found $($owners.members.Count) Owner Accounts"
$appuser = $users.members | where-object is_app_user -like "True"
Write-Log -ErrorLevel 3 -Message "Successfully found $($appuser.members.Count) App User Accounts"
$guest = $users.members | where-object is_restricted -like "True"
Write-Log -ErrorLevel 3 -Message "Successfully found $($guest.members.Count) Guest Accounts"
$limitedguest = $users.members | where-object is_ultra_restricted -like "True"
Write-Log -ErrorLevel 3 -Message "Successfully found $($limitedguest.members.Count) Single Channel Guest Accounts"
$botuser = $users.members | where-object is_bot -like "True"
Write-Log -ErrorLevel 3 -Message "Successfully found $($botuser.members.Count) Bot User Accounts"
}
catch {
$Err = $_
Write-Log -ErrorLevel 0 -Message "Failed to parse User List"
Write-Log -ErrorLevel 2 -Message $Err.Exception
throw $Err.Exception
}
#>

#region get admin users

function get-adminusers{
param(
$user
)
try{
Write-Log -ErrorLevel 0 -Message "Parsing List of Admin Users as defined by Admin Roles parameter: $($adminrole)"
$isadmin = $false

foreach($role in $adminrole.split(",")){
$filter = $role.split("=")[0]
$switch = $role.split("=")[1]
if($user.$filter -eq $switch)
{
$isadmin = $true
break
}
}
}
catch {
$Err = $_
Write-Log -ErrorLevel 0 -Message "Failed to parse Admin Role List"
Write-Log -ErrorLevel 2 -Message $Err.Exception
throw $Err.Exception
}
return $isadmin
}

function get-svcacctusers{
param(
$user
)
try{
Write-Log -ErrorLevel 0 -Message "Parsing List of Service Account Users as defined by Service Account Roles parameter: $($svcacctrole)"
$issvcacct = $false

foreach($role in $svcacctrole.split(",")){
$filter = $role.split("=")[0]
$switch = $role.split("=")[1]
if($user.$filter -eq $switch)
{
$issvcacct = $true
break
}
}
}
catch {
$Err = $_
Write-Log -ErrorLevel 0 -Message "Failed to parse Service Account Role List"
Write-Log -ErrorLevel 2 -Message $Err.Exception
throw $Err.Exception
}
return $issvcacct
}
#endregion Get Admin Users

#region Main Process
if($DiscoveryMode -eq "Default")
{

$foundAccounts = @()
foreach ($user in $users.members)
{
if($user.team_id -eq $AuthTest.team_id){$WorkspaceName = $AuthTest.team; $WorkspaceURL = $AuthTest.url}

if($user)
{
$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name Workspace-Name -Value $WorkspaceName
$object | Add-Member -MemberType NoteProperty -Name Workspace-URL -Value $WorkspaceURL
$object | Add-Member -MemberType NoteProperty -Name Username -Value $user.name
$object | Add-Member -MemberType NoteProperty -Name Global-UserId -Value $user.id
$object | Add-Member -MemberType NoteProperty -Name Admin-Account -Value $user.is_admin
$object | Add-Member -MemberType NoteProperty -Name Workspace-Owner -Value $user.is_owner
$object | Add-Member -MemberType NoteProperty -Name Bot-User -Value $user.is_bot
$object | Add-Member -MemberType NoteProperty -Name App-User-Account -Value $user.is_app_user
$object | Add-Member -MemberType NoteProperty -Name Guest-Account -Value $user.is_restricted
$object | Add-Member -MemberType NoteProperty -Name Restricted-Guest-Account -Value $user.is_ultra_restricted

$foundAccounts += $object
}
}
}

if($DiscoveryMode -eq "Advanced")
{

$foundAccounts = @()
foreach($user in $users.members)
{
$isadmin = get-adminusers -user $user
$issvcacct = get-svcacctusers -user $user
if($user.team_id -eq $AuthTest.team_id){$WorkspaceName = $AuthTest.team; $WorkspaceURL = $AuthTest.url}

$object = New-Object -TypeName PSObject
$object | Add-Member -MemberType NoteProperty -Name Workspace-Name -Value $WorkspaceName
$object | Add-Member -MemberType NoteProperty -Name Workspace-URL -Value $WorkspaceURL
$object | Add-Member -MemberType NoteProperty -Name Username -Value $user.name
$object | Add-Member -MemberType NoteProperty -Name Admin-Account -Value $isadmin
$object | Add-Member -MemberType NoteProperty -Name Service-Account -Value $issvcacct
$object | Add-Member -MemberType NoteProperty -Name Local-Account -Value $true

$foundAccounts += $object

}
}
#endregion Main Process

# Use for Debugging Discovery
# Add-Content -Path "c:\temp\results.txt" -Value $foundAccounts
return $foundAccounts
133 changes: 133 additions & 0 deletions Scripts/SecretServer/Slack/Discovery/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Slack Admin and Service Account Discovery

## Create Discovery Source

This scanner can help perform an Scan for user accounts within a Slack workspace. Account types will be destinguished by the appropriate roles designated by Slack.

### Create SaaS Scan Template
If this Script has already been created in another Delinea Integration package please skip to the [Create Account Scan Template](#create-account-scan-template)

- Log in to Secret Server Tenant
- Navigate to **ADMIN** > **Discovery** > **Configuration** > **Scanner Definition** > **Scan Templates**
- Click **Create Scan Template**
- Fill out the required fields with the information
- **Name:** (Example: SaaS Tenant)
- **Active:** (Checked)
- **Scan Type:** Host
- **Parent Scan Template:** Host Range
- **Fields**
- Change HostRange to **tenant-url**
- Click Save
- This completes the creation of the Saas Scan Template Creation


### Create Account Scan Template

- Log in to Secret Server Tenant
- Navigate to **ADMIN** > **Discovery** > **Configuration** > **Scanner Definition** > **Scan Templates**
- Click **Create Scan Template**
- Fill out the required fields with the information
- **Name:** (Example: Slack Account)
- **Active:** (Checked)
- **Scan Type:** Account
- **Parent Scan Template:** Account(Basic)
- **Fields**
- Change Resource to **workspace-url**
- Add field: Admin-Account (Leave Parent and Include in Match Blank)
- Add field: Service-Account (Leave Parent and Include in Match Blank)
- Add field: Local-Account (Leave Parent and Include in Match Blank)
- Click Save
- This completes the creation of the Account Scan Template Creation

### Create Discovery Script

- Log in to Secret Server Tenant
- Navigate to**ADMIN** > **Scripts**
- Click on **Create Script**
- Fill out the required fields with the information from the application registration
- Name: ( example -Slack User Account Scanner)
- Description: (Enter something meaningful to your Organization)
- Active: (Checked)
- Script Type: Powershell
- Category: Discovery Scanner
- Merge Fields: Leave Blank
- Script: Copy and paste the Script included in the file [Slack User Account Discoverey.ps1](./Slack-Discovery.ps1)
- Click Save
- This completes the creation of the Account Discovery Script

### Create SaaS Tenant Scanner

If this Script has already been created in another Delinea Integration package please skip to the [Create Account Scanner Section](#create-slack-account-scanner )

- Log in to Secret Server Tenant
- Navigate to **ADMIN** > **Discovery** > **Configuration** >
- Click **Discovery Configuration Options** > **Scanner Definitions** > **Scanners**
- Click **Create Scanner**
- Fill out the required fields with the information
- **Name:** > SaaS Tenant Scanner
- **Description:** (Example - Base scanner used to discover SaaS applications)
- **Discovery Type:** Host
- **Base Scanner:** Host
- **Input Template**: Manual Input Discovery
- **Output Template:**: Saas Tenant (Use Temaplte that Was Created in the [SaaS Scan Template Section](#create-saas-scan-template))
- Click Save
- This completes the creation of the Saas Tenant Scanner

### Create Slack Account Scanner

- Log in to Secret Server Tenant
- Navigate to **ADMIN** > **Discovery** > **Configuration** >
- Click **Discovery Configuration Options** > **Scanner Definitions** > **Scanners**
- Click **Create Scanner**
- Fill out the required fields with the information
- **Name:** (Example - Slack User Account Scanner)
- **Description:** (Example - Discovers Slack User accounts according to configured privileged account template )
- **Discovery Type:** Account
- **Base Scanner:** PowerShell Discovery
- **Input Template**: SaaS Tenant (Use Temaplte that Was Created in the [SaaS Scan Template Section](#create-saas-scan-template))
- **Output Template:**: Slack Account (Use Template that Was Created in the [Create Account Scan Template Section](#create-account-scan-template))
- **Script:** Slack User Account Scanner (Use Script Created in the [Create Discovery Script Section](#create-discovery-script))
- **Script Arguments: ``` Advanced $[1]$OAuthToken $[1]$admin-roles $[1]$svcacct-roles ```
- Click Save
- This completes the creation of the ServiceNow Account Scanner

### Create Discovery Source

- Navigate to **Admin | Discovery | Configuration**
- Click **Create** drop-down
- Click **Empty Discovery Source**
-Enter the Values below
- **Name:** (example: Slack Tenant [Workspace Name])
- **Site** (Select Site Where Discovery will run)
- **Source Type** Empty
- Click Save
- Click Cancel on the Add Flow Screen
- Click **Add Scanner**
- Find the Saas Tenant Scanner or the Scanner Created in the [Create Saas Tenant Scanner Section](#create-saas-tenant-scanner) and Click **Add Scanner**
- Select the Scanner just Created and Click **Edit Scanner**
- In the **lines Parse Format** Section Enter the Source Name (example: Slack Tenant)
- Click **Save**

- Click **Add Scanner**
- Find the Slack User Account Scanner or the Scanner Created in the [Create Slack User Account Scanner Section](#create-slack-account-scanner) and Click **Add Scanner**
- Select the Scanner just Created and Click **Edit Scanner**
- Click **Edit Scanner**
- Click the **Add Secret** Link
- Search for the Privileged Account Secret created in the [Instructions.md file](../Instructions.md)
- Check the Use Site Run As Secret Check box to enable it
**Note Default Site run as Secret had to ne setup in the Site configuration.
See the [Setting the Default PowerShell Credential for a Site](https://docs.delinea.com/online-help/secret-server/authentication/secret-based-credentials-for-scripts/index.htm?Highlight=site) Section in the Delinea Documentation
- Click Save
- Click on the Discovery Source tab and Click the Active check box
- This completes the creation of theDiscovery Source


### Next Steps

The Slack Discovery configuration is now complete. The next step is to run a manual discovery scan.
- Navigate to **Admin | Discovery**
- Click the **Run Discovery Now** (Dropdown) and select **Run Discovery Now**
- Click on the **Network view** Button in the upper right corner
- Click on the newly created discovery source
- Click the **Domain \ Cloud Accounts** tab to view the discovered accounts

Loading