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

Add functionality to retrieve, and use a pre-generated auth token for authentication in powershell scripts. #285

Merged
merged 5 commits into from
Jun 5, 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
72 changes: 61 additions & 11 deletions powershell/install/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,33 @@ The scripts support auto-discovery of the Falcon cloud region. If the `FalconClo

## Configuration

### Setting up Authentication

#### Using Client ID and Client Secret

Provide the required parameters:

```powershell
.\falcon_windows_install.ps1 -FalconClientId <string> -FalconClientSecret <string>
```

#### Using an Access Token

You can also specify a Falcon access token if doing a batch install across multiple machines to prevent the need to call the token endpoint multiple times. If using an access token to authenticate, you ***MUST*** also provide `FALCON_CLOUD`:

```powershell
.\falcon_windows_install.ps1 -FalconCloud us-2 -FalconAccessToken <string>
```

> [!NOTE]
> If you need to retrieve an access token, run the script with the `GET_ACCESS_TOKEN` parameter set. The Falcon sensor will NOT be installed while this parameter is provided.
>
> ```powershell
> .\falcon_windows_install.ps1 -FalconClientId <string> -FalconClientSecret <string> -GetAccessToken
> ```
>
> The script will output the access token to the console.

### Install

Uses the CrowdStrike Falcon APIs to check the sensor version assigned to a ***Windows Sensor Update policy***,
Expand All @@ -37,23 +64,28 @@ to complete.
Script options can be passed as parameters or defined in the param() block. Default values are listed in
the parameter descriptions:

```terminal
```pwsh
<#
.PARAMETER FalconCloud
CrowdStrike Falcon OAuth2 API Hostname [default: autodiscover]
.PARAMETER FalconClientId
CrowdStrike Falcon OAuth2 API Client Id [Required]
CrowdStrike Falcon OAuth2 API Client Id [Required if FalconAccessToken is not provided]
.PARAMETER FalconClientSecret
CrowdStrike Falcon OAuth2 API Client Secret [Required]
CrowdStrike Falcon OAuth2 API Client Secret [Required if FalconAccessToken is not provided]
.PARAMETER FalconCid
Manually specify CrowdStrike Customer ID (CID) [default: $null]
.PARAMETER FalconAccessToken
Manually set the access token for the Falcon API. Used to bypass the OAuth2 authentication process to cut down on rate limiting. [default: $null]
.PARAMETER GetAccessToken
Returns an access token from the API credentials provided. Used to manually set the FalconAccessToken parameter.
.PARAMETER MemberCid
Member CID, used only in multi-CID ("Falcon Flight Control") configurations and with a parent management CID.
Member CID, used only in multi-CID ("Falcon Flight Control") configurations and with a parent management CID [default: $null]
.PARAMETER SensorUpdatePolicyName
Sensor Update Policy name to check for assigned sensor version ['platform_default' if left undefined]
Sensor Update Policy name to check for assigned sensor version [default: 'platform_default']
.PARAMETER InstallParams
Sensor installation parameters, without your CID value ['/install /quiet /noreboot' if left undefined]
Additional Sensor installation parameters. Script parameters should be used instead when supported. [default: '/install /quiet /noreboot' ]
.PARAMETER LogPath
Script log location ['Windows\Temp\InstallFalcon.log' if left undefined]
Script log location [default: 'Windows\Temp\InstallFalcon.log']
.PARAMETER DeleteInstaller
Delete sensor installer package when complete [default: $true]
.PARAMETER DeleteScript
Expand All @@ -64,8 +96,16 @@ Provisioning token to use for sensor installation [default: $null]
Time to wait, in seconds, for sensor to provision [default: 1200]
.PARAMETER Tags
A comma-separated list of tags to apply to the host after sensor installation [default: $null]
.PARAMETER ProxyHost
The proxy host for the sensor to use when communicating with CrowdStrike [default: $null]
.PARAMETER ProxyPort
The proxy port for the sensor to use when communicating with CrowdStrike [default: $null]
.PARAMETER ProxyDisable
By default, the Falcon sensor for Windows automatically attempts to use any available proxy connections when it connects to the CrowdStrike cloud.
This parameter forces the sensor to skip those attempts and ignore any proxy configuration, including Windows Proxy Auto Detection.
.PARAMETER Verbose
Enable verbose logging
#>
```

***Examples***:
Expand Down Expand Up @@ -93,7 +133,8 @@ to complete.
Script options can be passed as parameters or defined in the param() block. Default values are listed in
the parameter descriptions:

```terminal
```pwsh
<#
.PARAMETER MaintenanceToken
Sensor uninstall maintenance token. If left undefined, the script will attempt to retrieve the token from the API assuming the FalconClientId|FalconClientSecret are defined.
.PARAMETER UninstallParams
Expand All @@ -107,17 +148,26 @@ Delete sensor uninstaller package when complete [default: $true]
.PARAMETER DeleteScript
Delete script when complete [default: $false]
.PARAMETER RemoveHost
Remove host from CrowdStrike Falcon
Remove host from CrowdStrike Falcon [requires either FalconClientId|FalconClientSecret or FalconAccessToken]
.PARAMETER FalconCloud
CrowdStrike Falcon OAuth2 API Hostname [default: autodiscover]
.PARAMETER FalconClientId
CrowdStrike Falcon OAuth2 API Client Id [Required if RemoveHost is $true]
CrowdStrike Falcon OAuth2 API Client Id
.PARAMETER FalconClientSecret
CrowdStrike Falcon OAuth2 API Client Secret [Required if RemoveHost is $true]
CrowdStrike Falcon OAuth2 API Client Secret
.PARAMETER FalconAccessToken
Manually set the access token for the Falcon API. Used to bypass the OAuth2 authentication process to cut down on rate limiting. [default: $null]
.PARAMETER GetAccessToken
Returns an access token from the API credentials provided. Used to manually set the FalconAccessToken parameter.
.PARAMETER MemberCid
Member CID, used only in multi-CID ("Falcon Flight Control") configurations and with a parent management CID.
.PARAMETER ProxyHost
The proxy host for the sensor to use when communicating with CrowdStrike [default: $null]
.PARAMETER ProxyPort
The proxy port for the sensor to use when communicating with CrowdStrike [default: $null]
.PARAMETER Verbose
Enable verbose logging
#>
```

***Examples***:
Expand Down
102 changes: 62 additions & 40 deletions powershell/install/falcon_windows_install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@ the parameter descriptions.
The script must be run as an administrator on the local machine in order for the Falcon Sensor installation
to complete, and the OAuth2 API Client being used requires 'sensor-update-policies:read' and
'sensor-download:read' permissions.

.PARAMETER FalconCloud
CrowdStrike Falcon OAuth2 API Hostname [default: autodiscover]
.PARAMETER FalconClientId
CrowdStrike Falcon OAuth2 API Client Id [Required]
CrowdStrike Falcon OAuth2 API Client Id [Required if FalconAccessToken is not provided]
.PARAMETER FalconClientSecret
CrowdStrike Falcon OAuth2 API Client Secret [Required]
CrowdStrike Falcon OAuth2 API Client Secret [Required if FalconAccessToken is not provided]
.PARAMETER FalconCid
Manually specify CrowdStrike Customer ID (CID) [default: $null]
.PARAMETER FalconAccessToken
Manually set the access token for the Falcon API. Used to bypass the OAuth2 authentication process to cut down on rate limiting. [default: $null]
.PARAMETER GetAccessToken
Returns an access token from the API credentials provided. Used to manually set the FalconAccessToken parameter.
.PARAMETER MemberCid
Member CID, used only in multi-CID ("Falcon Flight Control") configurations and with a parent management CID [default: $null]
.PARAMETER SensorUpdatePolicyName
Expand Down Expand Up @@ -48,6 +53,7 @@ By default, the Falcon sensor for Windows automatically attempts to use any avai
This parameter forces the sensor to skip those attempts and ignore any proxy configuration, including Windows Proxy Auto Detection.
.PARAMETER Verbose
Enable verbose logging

.EXAMPLE
PS>.\falcon_windows_install.ps1 -FalconClientId <string> -FalconClientSecret <string>

Expand Down Expand Up @@ -115,7 +121,13 @@ param(
[int] $ProxyPort,

[Parameter(Position = 16)]
[switch] $ProxyDisable
[switch] $ProxyDisable,

[Parameter(Position = 17)]
[switch] $GetAccessToken,

[Parameter(Position = 18)]
[string] $FalconAccessToken
)
begin {
if ($PSVersionTable.PSVersion -lt '3.0')
Expand Down Expand Up @@ -181,57 +193,67 @@ begin {
function Invoke-FalconAuth([hashtable] $WebRequestParams, [string] $BaseUrl, [hashtable] $Body, [string] $FalconCloud) {
$Headers = @{'Accept' = 'application/json'; 'Content-Type' = 'application/x-www-form-urlencoded'; 'charset' = 'utf-8' }
$Headers.Add('User-Agent', 'crowdstrike-falcon-scripts/1.4.1')
try {
$response = Invoke-WebRequest @WebRequestParams -Uri "$($BaseUrl)/oauth2/token" -UseBasicParsing -Method 'POST' -Headers $Headers -Body $Body
$content = ConvertFrom-Json -InputObject $response.Content
Write-VerboseLog -VerboseInput $content -PreMessage 'Invoke-FalconAuth - $content:'
if ($FalconAccessToken){
$Headers.Add('Authorization', "bearer $($FalconAccessToken)")
}
else{
try {
$response = Invoke-WebRequest @WebRequestParams -Uri "$($BaseUrl)/oauth2/token" -UseBasicParsing -Method 'POST' -Headers $Headers -Body $Body
$content = ConvertFrom-Json -InputObject $response.Content
Write-VerboseLog -VerboseInput $content -PreMessage 'Invoke-FalconAuth - $content:'

if ([string]::IsNullOrEmpty($content.access_token)) {
$message = 'Unable to authenticate to the CrowdStrike Falcon API. Please check your credentials and try again.'
throw $message
}
if ([string]::IsNullOrEmpty($content.access_token)) {
$message = 'Unable to authenticate to the CrowdStrike Falcon API. Please check your credentials and try again.'
throw $message
}

$Headers.Add('Authorization', "bearer $($content.access_token)")
}
catch {
# Handle redirects
Write-Verbose "Invoke-FalconAuth - CAUGHT EXCEPTION - `$_.Exception.Message`r`n$($_.Exception.Message)"
$response = $_.Exception.Response
if ($GetAccessToken -eq $true){
Write-Output $content.access_token | out-host
exit
}

if (!$response) {
$message = "Unhandled error occurred while authenticating to the CrowdStrike Falcon API. Error: $($_.Exception.Message)"
Write-FalconLog -Source 'Invoke-FalconAuth' -Message $message
throw $message
$Headers.Add('Authorization', "bearer $($content.access_token)")
}
catch {
# Handle redirects
Write-Verbose "Invoke-FalconAuth - CAUGHT EXCEPTION - `$_.Exception.Message`r`n$($_.Exception.Message)"
$response = $_.Exception.Response

if (!$response) {
$message = "Unhandled error occurred while authenticating to the CrowdStrike Falcon API. Error: $($_.Exception.Message)"
Write-FalconLog -Source 'Invoke-FalconAuth' -Message $message
throw $message
}

if ($response.StatusCode -in @(301, 302, 303, 307, 308)) {
# If autodiscover is enabled, try to get the correct cloud
if ($FalconCloud -eq 'autodiscover') {
if ($response.Headers.Contains('X-Cs-Region')) {
$region = $response.Headers.GetValues('X-Cs-Region')[0]
Write-Verbose "Received a redirect to $region. Setting FalconCloud to $region"
}
else {
$message = 'Received a redirect but no X-Cs-Region header was provided. Unable to autodiscover the FalconCloud. Please set FalconCloud to the correct region.'
Write-FalconLog -Source 'Invoke-FalconAuth' -Message $message
throw $message
}

$BaseUrl = Get-FalconCloud($region)
$BaseUrl, $Headers = Invoke-FalconAuth -WebRequestParams $WebRequestParams -BaseUrl $BaseUrl -Body $Body -FalconCloud $FalconCloud

if ($response.StatusCode -in @(301, 302, 303, 307, 308)) {
# If autodiscover is enabled, try to get the correct cloud
if ($FalconCloud -eq 'autodiscover') {
if ($response.Headers.Contains('X-Cs-Region')) {
$region = $response.Headers.GetValues('X-Cs-Region')[0]
Write-Verbose "Received a redirect to $region. Setting FalconCloud to $region"
}
else {
$message = 'Received a redirect but no X-Cs-Region header was provided. Unable to autodiscover the FalconCloud. Please set FalconCloud to the correct region.'
$message = "Received a redirect. Please set FalconCloud to 'autodiscover' or the correct region."
Write-FalconLog -Source 'Invoke-FalconAuth' -Message $message
throw $message
}

$BaseUrl = Get-FalconCloud($region)
$BaseUrl, $Headers = Invoke-FalconAuth -WebRequestParams $WebRequestParams -BaseUrl $BaseUrl -Body $Body -FalconCloud $FalconCloud

}
else {
$message = "Received a redirect. Please set FalconCloud to 'autodiscover' or the correct region."
$message = "Received a $($response.StatusCode) response from $($BaseUrl)oauth2/token. Please check your credentials and try again. Error: $($response.StatusDescription)"
Write-FalconLog -Source 'Invoke-FalconAuth' -Message $message
throw $message
}
}
else {
$message = "Received a $($response.StatusCode) response from $($BaseUrl)oauth2/token. Please check your credentials and try again. Error: $($response.StatusDescription)"
Write-FalconLog -Source 'Invoke-FalconAuth' -Message $message
throw $message
}
}

return $BaseUrl, $Headers
Expand Down Expand Up @@ -417,7 +439,7 @@ process {
}

# Configure OAuth2 authentication
if ($credsProvided) {
if ($credsProvided -or $FalconAccessToken) {
$BaseUrl = Get-FalconCloud $FalconCloud

$Body = @{}
Expand Down Expand Up @@ -460,7 +482,7 @@ process {
# Get sensor version from policy
$message = "Retrieving sensor policy details for '$($SensorUpdatePolicyName)'"
Write-FalconLog 'GetPolicy' $message
$filter = "platform_name:'Windows'+name.raw:'$($SensorUpdatePolicyName)'"
$filter = "platform_name:'Windows'+name.raw:'$($SensorUpdatePolicyName.ToLower())'"
$url = "${BaseUrl}/policy/combined/sensor-update/v2?filter=$([System.Web.HttpUtility]::UrlEncode($filter)))"
$policy_scope = @{
'Sensor update policies' = @('Read')
Expand Down
Loading