diff --git a/.github/wordlist.txt b/.github/wordlist.txt index 8234715a9..31ac3e0d7 100644 --- a/.github/wordlist.txt +++ b/.github/wordlist.txt @@ -1382,3 +1382,10 @@ QueryCasesIdsByFilter SDKDEMO kube KPA +argparse +colorama +Oke +Okumo +Moomaw +Esha +Kumar \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md index 84a4e73f6..ac318d10e 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -97,6 +97,9 @@ This has been a critical element in the development of the FalconPy project. + Nick, `nickforsythbarr` + `nesies` + `David-M-Berry` ++ Oke Okumo, `@okewoma` ++ Alexander Moomaw, `@alhumaw` ++ Esha Kumar, `@exk200006` ## Sponsors diff --git a/samples/authentication/README.md b/samples/authentication/README.md index 8f4dbb6f6..b92be4674 100644 --- a/samples/authentication/README.md +++ b/samples/authentication/README.md @@ -7,7 +7,8 @@ The examples in this folder focus on authentication to CrowdStrike's APIs. - [Azure Key Vault Authentication](#azure-key-vault-authentication) - CrowdStrike API authentication leveraging Azure Key Vault for credential storage. - [AES Authentication](#aes-authentication) - Leverage AES/CBC to encrypt credentials for use with authentication to the CrowdStrike API. -- [AES File Crypt](#aes-file-crypt) - Encrypt arbitrary files with AES/CBC. +- [AES File Crypt](#aes-file-crypt) - Encrypt arbitrary files with AES/CBC +- [AWS Parameter Store](#aws-parameter-store) - CrowdStrike API authentication leveraging AWS Parameter Store for credential storage - [Token Authentication](#token-authentication) - Token Authentication is the original solution for authenticating to a Service Class, and is still fully supported. This example demonstrates how to use Token Authentication to interact with multiple Service Classes. ## Azure Key Vault Authentication @@ -458,6 +459,64 @@ file arguments: Source code for this example can be found [here](aes_file_crypt.py). --- +## AWS Parameter store +This application demonstrates storing CrowdStrike API credentials within the AWS Parameter Store service, and retrieving them to access the CrowdStrike API. + +### Running the program +In order to run this demonstration, you will need access to CrowdStrike API keys. You will also need to set your specific AWS location + +#### Command line arguments +This program accepts the following command line arguments. + +| Argument | Long Argument | Description | +| :-- | :-- | :-- | +| `-h` | `--help` | Display command line help and exit | +| `-k` _CLIENT_ID_PARAMETER_ | `--client_id_parameter` _CLIENT_ID_PARAMETER_ | Name of the Key Vault Secrets parameter storing your API client ID | +| `-s` _CLIENT_SECRET_PARAMETER_ | `--client_secret_parameter` _CLIENT_SECRET_PARAMETER_ | Name of the Key Vault Secrets parameter storing your API client secret | +| `-d` | `--debug`| Enables debugging functionality | + +#### Basic usage + +##### Use this command to test out the sample. + +```shell +python3 aws_parameter_store.py -k FALCON_CLIENT_ID -s FALCON_CLIENT_SECRET +``` +##### Use this command to activate debugging. + +```shell +python3 aws_parameter_store.py -k FALCON_CLIENT_ID -s FALCON_CLIENT_SECRET -d +``` +#### Command-line help +Command-line help is available via the `-h` argument. + +```shell +usage: aws_parameter_store.py [-h] [-k] CLIENT_ID [-s] CLIENT_SECRET [-d] DEGUG + + + ___ ____ __ ____ _______. + / \ \ \ / \ / / / | + / ^ \ \ \/ \/ / | (----` + / /_\ \ \ / \ \ + / _____ \ \ /\ / .----) | +/__/ \__\ \__/ \__/ |_______/ + + ____ __ _____ __ + / __ \____ __________ _____ ___ ___ / /____ _____ / ___// /_____ ________ + / /_/ / __ `/ ___/ __ `/ __ `__ \/ _ \/ __/ _ \/ ___/ \__ \/ __/ __ \/ ___/ _ \ + / ____/ /_/ / / / /_/ / / / / / / __/ /_/ __/ / ___/ / /_/ /_/ / / / __/ + /_/ \__,_/_/ \__,_/_/ /_/ /_/\___/\__/\___/_/ /____/\__/\____/_/ \___/ + + +optional arguments: + -h, --help show this help message and exit + -d, --debug enables degugging + +required arguments: + -k CLIENT_ID, --client_id_parameter CLIENT_ID + -s CLIENT_SECRET, --client_secret_parameter CLIENT_SECRET +``` + ## Token Authentication [Token authentication](https://www.falconpy.io/Usage/Authenticating-to-the-API.html#legacy-authentication) (also referred to as _legacy authentication_) is the process of authenticating to a FalconPy Service Class by providing a previously assigned bearer token directly to the [`auth_token`](https://www.falconpy.io/Usage/Basic-Service-Class-usage.html#legacy-authentication) keyword when instantiating the Service Class. This is the original method of authentication provided by Service Classes, and while it is frequently eschewed in preference to [Direct](https://www.falconpy.io/Usage/Authenticating-to-the-API.html#direct-authentication) and [Object](https://www.falconpy.io/Usage/Authenticating-to-the-API.html#object-authentication) [Authentication](https://www.falconpy.io/Usage/Authenticating-to-the-API.html), there are multiple scenarios where it is still the best option for the situation. diff --git a/samples/authentication/aws_parameter_store.py b/samples/authentication/aws_parameter_store.py index f03882c70..6ba4627cc 100644 --- a/samples/authentication/aws_parameter_store.py +++ b/samples/authentication/aws_parameter_store.py @@ -34,6 +34,7 @@ This application demonstrates storing CrowdStrike API credentials within the AWS Parameter Store service, and retrieving them to access the CrowdStrike API. """ +import logging from argparse import ArgumentParser, RawTextHelpFormatter, Namespace try: import boto3 @@ -64,8 +65,19 @@ def consume_arguments() -> Namespace: default="FALCON_CLIENT_SECRET", dest="client_secret_parameter" ) + parser.add_argument("-d", "--debug", + help="Enable API debugging", + action="store_true", + default=False + ) + + parsed = parser.parse_args() + if parsed.debug: + logging.basicConfig(level=logging.DEBUG) + + + return parsed - return parser.parse_args() def get_parameter_store_params(cmd_line: Namespace): @@ -101,9 +113,9 @@ def get_parameter_store_params(cmd_line: Namespace): return returned_client_id, returned_client_secret -def perform_simple_demonstration(client_id: str, client_secret: str): +def perform_simple_demonstration(client_id: str, client_secret: str, debug: bool): """Perform a simple API demonstration using the credentials retrieved.""" - falcon = Hosts(client_id=client_id, client_secret=client_secret) + falcon = Hosts(client_id=client_id, client_secret=client_secret, debug=debug) # Retrieve 500 hosts and sort ascending by hostname aid_lookup = falcon.query_devices_by_filter_scroll(sort="hostname.asc", limit=500) if not aid_lookup["status_code"] == 200: @@ -120,6 +132,9 @@ def perform_simple_demonstration(client_id: str, client_secret: str): if __name__ == "__main__": - # Consume our command line, retrieve our credentials from AWS parameter store + # Consume our command line arguments + args = consume_arguments() + # retrieve our credentials from AWS parameter store + client_id, client_secret = get_parameter_store_params(args) # and then execute a simple API demonstration to prove functionality. - perform_simple_demonstration(*get_parameter_store_params(consume_arguments())) + perform_simple_demonstration(client_id, client_secret) diff --git a/samples/authentication/requirements_aws_parameter_store.txt b/samples/authentication/requirements_aws_parameter_store.txt new file mode 100644 index 000000000..b1876066a --- /dev/null +++ b/samples/authentication/requirements_aws_parameter_store.txt @@ -0,0 +1,2 @@ +boto3 +crowdstrike-falconpy \ No newline at end of file diff --git a/samples/authentication/requirements_token_authentication_example.txt b/samples/authentication/requirements_token_authentication_example.txt new file mode 100644 index 000000000..295ff972a --- /dev/null +++ b/samples/authentication/requirements_token_authentication_example.txt @@ -0,0 +1,4 @@ +boto3 +click +colorama +crowdstrike-falconpy \ No newline at end of file diff --git a/samples/authentication/token_authentication_example.py b/samples/authentication/token_authentication_example.py index 1a3c450ec..95f8a0f49 100644 --- a/samples/authentication/token_authentication_example.py +++ b/samples/authentication/token_authentication_example.py @@ -34,9 +34,11 @@ This sample should run using any version of FalconPy and requires the colorama and click libraries. """ +import logging import os import click import colorama +from argparse import ArgumentParser, RawTextHelpFormatter, Namespace from falconpy import ( CloudConnectAWS, Detects, @@ -54,9 +56,27 @@ BOLD = colorama.Style.BRIGHT ENDMARK = colorama.Style.RESET_ALL - +def consume_arguments() -> Namespace: + parser = ArgumentParser(description=__doc__, fromatter_class=RawTextHelpFormatter) + parser.add_argument("-d", "--debug", + help="Enable API debugging", + action="store_true", + default=False + ) + parser.add_argument("-b", "--base-url", + dest="base_url", + help="CrowdStrike cloud region. (auto or usgov1, Default: auto)", + required=False, + default="usgov1" + ) + parsed = parser.parse_args() + if parsed.debug: + logging.basicConfig(level=logging.DEBUG) + + + return parsed # ### BEGIN token simulation -def get_token(): +def get_token(debug=False): """ Generate a token to use for authentication. @@ -95,7 +115,8 @@ def get_token(): ) auth = OAuth2( client_id=falcon_client_id, - client_secret=falcon_client_secret + client_secret=falcon_client_secret, + debug=debug ) # Generate a token auth.token() @@ -176,6 +197,10 @@ def passed(svc_class: str): if __name__ == "__main__": + # Parse command-line arguments and retrieve debug mode setting + args = consume_arguments() + # Authenticate using Falcon API OAuth2 with debug mode enabled if specified + get_token(debug=args.debug) # Test each of these classes to confirm cross collection authentication for Service Classes classes_to_test = [CloudConnectAWS, Detects, Hosts, IOC, Incidents, Intel] # Grab a simulated token and execute the test series diff --git a/samples/cspm_registration/README.md b/samples/cspm_registration/README.md index a398816b8..c960ee01d 100644 --- a/samples/cspm_registration/README.md +++ b/samples/cspm_registration/README.md @@ -48,6 +48,10 @@ python3 get_cspm_policies.py -f $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET -o fi python3 get_cspm_policies.py -f $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET -c aws ``` +```shell +python3 get_cspm_policies.py -f $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET -d +``` +> To activate debugging, use the `-d` argument. #### Command-line help Command-line help is available via the `-h` argument. @@ -98,7 +102,8 @@ optional arguments: Policy report output file (CSV format) -c CLOUD, --cloud CLOUD Cloud provider (aws, azure, gcp) + -d, --debug, Activates debugging ``` ### Example source code -The source code for this example can be found [here](get_cspm_policies.py). \ No newline at end of file +The source code for this example can be found [here](get_cspm_policies.py). diff --git a/samples/cspm_registration/get_cspm_policies.py b/samples/cspm_registration/get_cspm_policies.py index 7efb1e73f..3d071ab52 100644 --- a/samples/cspm_registration/get_cspm_policies.py +++ b/samples/cspm_registration/get_cspm_policies.py @@ -39,7 +39,7 @@ import os import sys import logging -from argparse import ArgumentParser, RawTextHelpFormatter +from argparse import ArgumentParser, RawTextHelpFormatter, Namespace from tabulate import tabulate try: from falconpy import CSPMRegistration @@ -49,17 +49,42 @@ ) from no_falconpy +def consume_arguments() -> Namespace: # Capture command line arguments -parser = ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter) -parser.add_argument("-f", "--falcon_client_id", - help="Falcon Client ID", default=None, required=False) -parser.add_argument("-s", "--falcon_client_secret", - help="Falcon Client Secret", default=None, required=False) -parser.add_argument("-o", "--output_file", - help="Policy report output file (CSV format)", required=False) -parser.add_argument( - "-c", "--cloud", help="Cloud provider (aws, azure, gcp)", required=False) -args = parser.parse_args() + parser = ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter) + parser.add_argument("-f", "--falcon_client_id", + help="Falcon Client ID", + default=None, + required=False) + parser.add_argument("-s", "--falcon_client_secret", + help="Falcon Client Secret", + default=None, + required=False) + parser.add_argument("-o", "--output_file", + help="Policy report output file (CSV format)", + required=False) + parser.add_argument("-c", "--cloud", + help="Cloud provider (aws, azure, gcp)", + required=False) + parser.add_argument("-d", "--debug", + help="Enable API debugging", + action="store_true", + default=False + ) + + parsed = parser.parse_args() + return parsed + + +cmd_line = consume_arguments() + +# Activate debugging if requested +if cmd_line.debug: + logging.basicConfig(level=logging.DEBUG) + + + +# pylint: disable=E0606 # Grab our client_id and client_secret or exit CONFIG_FILE = '../config.json' @@ -68,20 +93,22 @@ config = json.loads(file_config.read()) falcon_client_id = config['falcon_client_id'] falcon_client_secret = config['falcon_client_secret'] -elif args.falcon_client_id is not None and args.falcon_client_secret is not None: - falcon_client_id = args.falcon_client_id - falcon_client_secret = args.falcon_client_secret +elif cmd_line.falcon_client_id is not None and cmd_line.falcon_client_secret is not None: + falcon_client_id = cmd_line.falcon_client_id + falcon_client_secret = cmd_line.falcon_client_secret + debug = cmd_line.debug if cmd_line.debug else False # Set debug mode based on argument else: logging.error( " Please specify Falcon API Credentials with config.json or script arguments") sys.exit() -data_file = args.output_file -cloud = args.cloud +data_file = cmd_line.output_file +cloud = cmd_line.cloud # Instantiate CSPM_Registration service class falcon = CSPMRegistration(client_id=falcon_client_id, - client_secret=falcon_client_secret + client_secret=falcon_client_secret, + debug=debug ) diff --git a/samples/cspm_registration/requirements_get_cspm_policies.txt b/samples/cspm_registration/requirements_get_cspm_policies.txt new file mode 100644 index 000000000..598e20cb7 --- /dev/null +++ b/samples/cspm_registration/requirements_get_cspm_policies.txt @@ -0,0 +1,2 @@ +crowdstrike-falconpy +tabulate \ No newline at end of file diff --git a/samples/ioc/create_ioc.py b/samples/ioc/create_ioc.py index 3d3b77878..df39099ae 100644 --- a/samples/ioc/create_ioc.py +++ b/samples/ioc/create_ioc.py @@ -24,6 +24,7 @@ "applied_globally": true } """ +import logging import json import os from argparse import ArgumentParser, RawTextHelpFormatter @@ -32,12 +33,34 @@ def consume_command_line(): parser = ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter) - parser.add_argument("-k", "--falcon_client_id", help="Falcon API Client ID", required=True) - parser.add_argument("-s", "--falcon_client_secret", help="Falcon API Client Secret", required=True) - parser.add_argument("-m", "--method", help="SDK method to use ('service' or 'uber').", required=False, default="service") - parser.add_argument("-i", "--indicator", help="Path to the file representing the indicator (JSON format).", default="example_indicator.json", required=False) + parser.add_argument("-k", "--falcon_client_id", + help="Falcon API Client ID", + required=True) + parser.add_argument("-s", "--falcon_client_secret", + help="Falcon API Client Secret", + required=True) + parser.add_argument("-m", "--method", + help="SDK method to use ('service' or 'uber').", + required=False, + default="service") + parser.add_argument("-i", "--indicator", + help="Path to the file representing the indicator (JSON format).", + default="example_indicator.json", + required=False) + parser.add_argument("-d", "--debug", + help="Enable API debugging", + action="store_true", + default=False + ) + + + parsed = parser.parse_args() - return parser.parse_args() + if parsed.debug: + logging.basicConfig(level=logging.DEBUG) + + + return parsed def connect_api(class_type: str = "service", creds: dict = None): @@ -58,7 +81,7 @@ def connect_api(class_type: str = "service", creds: dict = None): if args.method not in ["service", "uber"]: args.method = "service" -falcon = connect_api(args.method, credentials) +falcon = connect_api(args.method, credentials, args.debug) if not os.path.exists(args.indicator): raise SystemExit("Unable to load indicator file.") diff --git a/samples/prevention_policy/README.md b/samples/prevention_policy/README.md index eaa970d48..c7accf5e0 100644 --- a/samples/prevention_policy/README.md +++ b/samples/prevention_policy/README.md @@ -270,7 +270,7 @@ In order to run this demonstration, you will need access to CrowdStrike API keys This example accepts the following input parameters. | Parameter | Purpose | Category | | :--- | :--- | :--- | -| `-h`, `--help` | Show help message and exit | optional | +| `-h`, `--help` | Show help message and exit | optional | | `-r`, `--show_settings` | Display policy settings | display | | `-z`, `--verbose` | Show all settings, including disabled | display | | `-e`, `--enable` | Enable the policy | administration | @@ -517,6 +517,7 @@ optional management arguments: -e, --enable Enable the policy -d, --disable Disable the policy -x, --delete Delete the policy + -debug, --debug Enable API debugging optional update arguments: -i POLICY_ID, --policy_id POLICY_ID diff --git a/samples/prevention_policy/prevention_policy_hawk.py b/samples/prevention_policy/prevention_policy_hawk.py index f7d76aaf8..be0711907 100644 --- a/samples/prevention_policy/prevention_policy_hawk.py +++ b/samples/prevention_policy/prevention_policy_hawk.py @@ -20,7 +20,7 @@ | | | | | | | | \ / | |\ \ |___| |___| |___| |___| \____/\/\____/ |___| \___\ |0\/0| - \/\/ FalconPy v1.0 + \/\/ FalconPy v1.4.4 \/ Creation date: 2022.02.11 Modification: 2022.05.11 @@ -33,6 +33,7 @@ This solution requires the FalconPy SDK. This project can be accessed here: https://github.com/CrowdStrike/falconpy """ +import logging from argparse import ArgumentParser, RawTextHelpFormatter from enum import Enum from tabulate import tabulate @@ -352,6 +353,11 @@ def consume_command_line(): parser = ArgumentParser(description=shiny_description(__doc__), formatter_class=RawTextHelpFormatter ) + parser.add_argument("-debug", "--debug", + help="Enable API debugging", + action="store_true", + default=False + ) # Display view = parser.add_argument_group("optional display arguments") view.add_argument("-r", "--show_settings", @@ -414,11 +420,19 @@ def consume_command_line(): ) # Always required req = parser.add_argument_group("required arguments") - req.add_argument("-f", "--falcon_client_id", help="Falcon Client ID", required=True) - req.add_argument("-s", "--falcon_client_secret", help="Falcon Client Secret", required=True) + req.add_argument("-f", "--falcon_client_id", + help="Falcon Client ID", + required=True) + req.add_argument("-s", "--falcon_client_secret", + help="Falcon Client Secret", + required=True) - return parser.parse_args() + parsed = parser.parse_args() + if parsed.debug: + logging.basicConfig(level=logging.DEBUG) + + return parsed def do_policy_delete(pol_id: str = None): """Delete the policy using the provided ID.""" @@ -603,9 +617,10 @@ def process_arguments(command, # Retrieve any provided command line arguments args = consume_command_line() - # Authenticate using our provided falcon client_id and client_secret + # Authenticate using our provided falcon client_id and client_secret and debugging if activated falcon_policy = PreventionPolicy(client_id=args.falcon_client_id, - client_secret=args.falcon_client_secret + client_secret=args.falcon_client_secret, + debug=args.debug ) # Review the provided arguments and then perform the request diff --git a/samples/prevention_policy/requiremts_prevention_policy_hawk.txt b/samples/prevention_policy/requiremts_prevention_policy_hawk.txt new file mode 100644 index 000000000..6e933ceee --- /dev/null +++ b/samples/prevention_policy/requiremts_prevention_policy_hawk.txt @@ -0,0 +1,4 @@ +argparse +enum34 +crowdstrike-falconpy +tabulate diff --git a/samples/recon/email_monitoring_recon.py b/samples/recon/email_monitoring_recon.py index 9dec83274..f94cc93d5 100644 --- a/samples/recon/email_monitoring_recon.py +++ b/samples/recon/email_monitoring_recon.py @@ -8,6 +8,7 @@ Creation: 06.21.2022, wozboz@CrowdStrike """ +import logging from csv import reader from argparse import ArgumentParser, RawTextHelpFormatter from falconpy import Recon @@ -33,15 +34,21 @@ help="File with email-addresses to use as input", required=True, ) - +parser.add_argument("-d", "--debug", + help="Enable API debugging", + action="store_true", + default=False + ) args = parser.parse_args() +if args.debug: + logging.basicConfig(level=logging.DEBUG) EMAIL_FILE = args.file falcon = Recon(client_id=args.falcon_client_id, client_secret=args.falcon_client_secret, - base_url=args.base_url + base_url=args.base_url, debug=args.debug ) QUERY = "(" diff --git a/samples/sensor_download/README.md b/samples/sensor_download/README.md index 18846bb74..5b3befb7b 100644 --- a/samples/sensor_download/README.md +++ b/samples/sensor_download/README.md @@ -41,7 +41,9 @@ This program accepts the following command-line arguments. | `-o` _OS_ | `--os` _OS_ | Sensor operating system | | `-v` _OSVER_ | `--osver` _OSVER_ | Sensor operating system version | | `-f` _FILENAME_ | `--filename` _FILENAME_ | Name to use for downloaded file | -| `-t` _TABLE_FORMAT_ | `--table_format` _TABLE_FORMAT_ | Table format to use for display. | +| `-t` _TABLE_FORMAT_ | `--table_format` _TABLE_FORMAT_ | Table format to use for display. +|`-debug`|`--debug`|`Enable API debugging`| +|`-b`|`--base-url`|`GovCloud access to Crowdstrike API`| | #### Basic usage The only required command line arguments are `-k` (CrowdStrike Falcon API Client ID) and `-s` (CrowdStrike Falcon API Client Secret). @@ -89,7 +91,18 @@ Filters described above are applied to select the appropriate version to downloa ```shell python3 download_sensor.py -k $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET -o centos -v 7 -d ``` +##### Activating Debugging +This example shows how you can activate debugging functionality when you run download_senor.py. +```shell +python3 download_sensor.py -k $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET -debug +``` +##### Allowing Access to GovCloud Users +This example shows how you GovCloud user can access sensor_download.py. + +```shell +python3 download_sensor.py -k $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET -b +``` ##### Specifying `N-1` or `N-2` versions. You can specify the previous, or 2nd previous version to download by leveraging the `-n` argument. @@ -138,11 +151,13 @@ optional arguments: CrowdStrike API Secret -a, --all Show all columns / Download all versions -d, --download Shortcut for '--command download' + -b, --base-url Allows access to usgov1 -n NMINUS, --nminus NMINUS Download previous version (n-1, n-2, 0 = current, 2 = n-2) -c COMMAND, --command COMMAND Command to perform. (list or download, defaults to list) -o OS, --os OS Sensor operating system + -debug, --debug Command to activate debugging -v OSVER, --osver OSVER Sensor operating system version -f FILENAME, --filename FILENAME @@ -152,7 +167,8 @@ optional arguments: (plain, simple, github, grid, fancy_grid, pipe, orgtbl, jira, presto, pretty, psql, rst, mediawiki, moinmoin, youtrack, html, unsafehtml, latext, latex_raw, latex_booktabs, latex_longtable, textile, tsv) + ``` ### Example source code -Source code for this example can be found [here](download_sensor.py). \ No newline at end of file +Source code for this example can be found [here](download_sensor.py). diff --git a/samples/sensor_download/requirements_download_sensor.txt b/samples/sensor_download/requirements_download_sensor.txt new file mode 100644 index 000000000..790cddc1f --- /dev/null +++ b/samples/sensor_download/requirements_download_sensor.txt @@ -0,0 +1,2 @@ +crowdstrike-falconpy +tabulate diff --git a/samples/sensor_update_policies/policy_wonk.py b/samples/sensor_update_policies/policy_wonk.py index 82b7be152..162be925b 100644 --- a/samples/sensor_update_policies/policy_wonk.py +++ b/samples/sensor_update_policies/policy_wonk.py @@ -9,7 +9,7 @@ __/ | |___/ for Sensor Update Policies - FalconPy v1.0 + FalconPy v1.4.4 Creation date: 05.06.2022 - jshcodes@CrowdStrike @@ -20,6 +20,7 @@ Multiple simultaneous actions may be performed against multiple Sensor Update Policy records using this utility. """ +import logging from argparse import ArgumentParser, RawTextHelpFormatter from tabulate import tabulate try: @@ -107,18 +108,39 @@ def consume_arguments(): """Consume arguments from the command line.""" desc = shiny_help_text(__doc__) parser = ArgumentParser(description=desc, formatter_class=RawTextHelpFormatter) + # Debug + parser.add_argument("-debug", "--debug", + help="Enable API debugging", + action="store_true", + default=False + ) # List disp = parser.add_argument_group("list arguments") - disp.add_argument("-l", "--list_all", help="Show all policies (Default action)", required=False, action="store_true") - disp.add_argument("-k", "--kernels", help="Show kernel build compatibility details", required=False, action="store_true") - disp.add_argument("-b", "--builds", help="Show available builds", required=False, action="store_true") - disp.add_argument("-o", "--host_groups", help="Show available host groups", required=False, action="store_true") + disp.add_argument("-l", "--list_all", + help="Show all policies (Default action)", + required=False, + action="store_true") + disp.add_argument("-k", "--kernels", + help="Show kernel build compatibility details", + required=False, + action="store_true") + disp.add_argument("-b", "--builds", + help="Show available builds", + required=False, + action="store_true") + disp.add_argument("-o", "--host_groups", + help="Show available host groups", + required=False, + action="store_true") disp.add_argument("-m", "--maintenance", help="Show maintenance or a specific uninstall token", required=False, action="store_true" ) - disp.add_argument("-v", "--show_members", help="Show policy members in results", required=False, action="store_true") + disp.add_argument("-v", "--show_members", + help="Show policy members in results", + required=False, + action="store_true") disp.add_argument("-z", "--show_groups", help="Show host groups assigned to policies in results", required=False, @@ -126,14 +148,24 @@ def consume_arguments(): ) # Search srch = parser.add_argument_group("search arguments") - srch.add_argument("-q", "--search_string", help="String to match against policy or host group name", required=False) + srch.add_argument("-q", "--search_string", + help="String to match against policy or host group name", + required=False) # Create crt = parser.add_argument_group("create arguments") - crt.add_argument("-c", "--create", help="Create a new policy", required=False, action="store_true") + crt.add_argument("-c", "--create", + help="Create a new policy", + required=False, action="store_true") # Update upd = parser.add_argument_group("update and delete arguments") - upd.add_argument("-d", "--disable", help="Disable the policy", required=False, action="store_true") - upd.add_argument("-e", "--enable", help="Enable the policy", required=False, action="store_true") + upd.add_argument("-d", "--disable", + help="Disable the policy", + required=False, + action="store_true") + upd.add_argument("-e", "--enable", + help="Enable the policy", + required=False, + action="store_true") upd.add_argument("-x", "--disable_uninstall_protection", help="Disable uninstall protection for the policy", required=False, @@ -150,28 +182,44 @@ def consume_arguments(): required=False, action="store_true" ) - upd.add_argument("-r", "--remove", help="Remove the policy", required=False, action="store_true") - upd.add_argument("-g", "--add_host_group", help="Add host group to the specified policy\n(comma delimit)", required=False) + upd.add_argument("-r", "--remove", + help="Remove the policy", + required=False, + action="store_true") + upd.add_argument("-g", "--add_host_group", + help="Add host group to the specified policy\n(comma delimit)", + required=False) upd.add_argument("-y", "--yank_host_group", help="Remove host group from the specified policy\n(comma delimit)", required=False ) # IDs and platform names for updates idg = parser.add_argument_group("required arguments for updating or removing policies") - idg.add_argument("-i", "--policy_id", help="ID(s) of the policy to update or remove (comma delimit)", required=False) - idg.add_argument("-n", "--platform_name", help="Platform name for policy precedence configurations", required=False) + idg.add_argument("-i", "--policy_id", + help="ID(s) of the policy to update or remove (comma delimit)", + required=False) + idg.add_argument("-n", "--platform_name", + help="Platform name for policy precedence configurations", + required=False) # MSSP msp = parser.add_argument_group("MSSP arguments") - msp.add_argument("-w", "--member_cid", help="Child CID (MSSP access)", required=False) + msp.add_argument("-w", "--member_cid", + help="Child CID (MSSP access)", + required=False) # Other oth = parser.add_argument_group("other arguments") - oth.add_argument("-t", "--base_url", help="Specify the API base URL", required=False) + oth.add_argument("-t", "--base_url", + help="Specify the API base URL", + required=False) # Always required req = parser.add_argument_group("always required arguments") - req.add_argument("-f", "--falcon_client_id", help="Falcon Client ID", required=True) - req.add_argument("-s", "--falcon_client_secret", help="Falcon Client Secret", required=True) + req.add_argument("-f", "--falcon_client_id", + help="Falcon Client ID", + required=True) + req.add_argument("-s", "--falcon_client_secret", + help="Falcon Client Secret", + required=True) - return parser.parse_args() def process_command_line(): # pylint: disable=R0912,R0915 @@ -252,10 +300,13 @@ def process_command_line(): # pylint: disable=R0912,R0915 base_url = "auto" if args.base_url: base_url = args.base_url + + if args.debug: + logging.basicConfig(level=logging.DEBUG) return command_to_perform, args.falcon_client_id, args.falcon_client_secret, args.search_string,\ args.policy_id, update_type, flag_type, hide_members, args.platform_name, group_id,\ - hide_groups, mssp_access, base_url + hide_groups, mssp_access, base_url, args.debug def hide_members_column(): @@ -407,7 +458,7 @@ def update_policies(id_to_update: str, update_style: str = "", flag_style: str = if update_result["status_code"] != 200: raise SystemExit(generate_api_error_list(update_result["body"]["errors"])) - +# pylint: disable=E0606 def list_kernel_compatibility(): """List all available kernels.""" kernel_list_lookup = falcon.query_combined_kernels() @@ -663,16 +714,16 @@ def list_host_groups(search_str: str = ""): Install it with: {Color.BOLD}python3 -m pip install crowdstrike-falconpy{Color.END} """ -if int(FALCONPY_VERSION.split(".")[0]) < 1: +if int(FALCONPY_VERSION.split(".", maxsplit=1)[0]) < 1: raise SystemExit(INVALID_VERSION) INDICATOR = ["|", "/", "-", "\\"] INDICATOR_POSITION = 0 command, client_id, client_secret, API_SEARCH, policy_id, which_update, \ - enable_disable, HIDE, platform_name, hg_id, GROUP_HIDE, member_cid, base_url = process_command_line() -falcon = connect_sensor_update_api(client_id, client_secret, member_cid, base_url) -falcon_groups = connect_host_group_api(client_id, client_secret, member_cid, base_url) + enable_disable, HIDE, platform_name, hg_id, GROUP_HIDE, member_cid, base_url, debug = process_command_line() +falcon = connect_sensor_update_api(client_id, client_secret, member_cid, base_url, debug) +falcon_groups = connect_host_group_api(client_id, client_secret, member_cid, base_url, debug) if "kernel" in command: list_kernel_compatibility() diff --git a/samples/sensor_update_policies/requirements_policy_wonk.txt b/samples/sensor_update_policies/requirements_policy_wonk.txt new file mode 100644 index 000000000..790cddc1f --- /dev/null +++ b/samples/sensor_update_policies/requirements_policy_wonk.txt @@ -0,0 +1,2 @@ +crowdstrike-falconpy +tabulate