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.