diff --git a/samples/hosts/README.md b/samples/hosts/README.md index e30d0c9dc..8f184691a 100644 --- a/samples/hosts/README.md +++ b/samples/hosts/README.md @@ -106,6 +106,115 @@ The source code for these examples can be found [here](bulk_add_falcon_tag.py). --- +## Default groups +This script was developed to setup the default groups in a new CID. It should be run once to create the necessary groups and populate them with the appropriate assignment rules. + +> Note: This sample also demonstrates [pythonic response handling](https://www.falconpy.io/Usage/Response-Handling.html#pythonic-responses) using the Advanced Uber Class (APIHarnessV2). + +### Running the program +In order to run this demonstration, you will need access to CrowdStrike API keys with the following scopes: + +| Service Collection | Scope | +| :---- | :---- | +| Hosts | __READ__ | + +> [!IMPORTANT] +> This script should be reviewed and updated to match your environment needs. +> Review the `groups` dictionary to identify group names and assignment rules that will be created. (lines 89 - 102, shown below) + +```python +#### UPDATE THE FOLLOWING DICTIONARY TO MATCH YOUR ENVIRONMENT ########## +# One group will be created for each dictionary item. +# Groups are defined as "Group Name": "Assignment Rule" +groups = { + "Sensor Uninstall Group": "staticByID", + "Phase 0": "none", + "Phase 1": "hostname:*'*'", + "Active Policy": "none", + "Windows Servers": "platform_name:'Windows'+product_type_desc:'Server'", + "DEV Updates": "tags:'SensorGroupingTags/DEV'", + "Golden Images": "tags:'FalconGroupingTags/GoldenImage'", + "Windows 7 and Server 2008 R2 Hosts": "(os_version:'Windows Server 2008 R2',os_version:'Windows 7')" +} +######################################################################### +``` + +### Execution syntax +This samples leverages simple command-line arguments to implement functionality. + +> Execute the default example. This will create the groups as defined by the `groups` dictionary within the current tenant (non-MSSP). + +```shell +python3 default_groups.py -k $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET +``` + +> This sample supports [Environment Authentication](https://falconpy.io/Usage/Authenticating-to-the-API.html#environment-authentication), meaning you can execute any of the command lines shown below without providing credentials if you have the values `FALCON_CLIENT_ID` and `FALCON_CLIENT_SECRET` defined in your environment. + +```shell +python3 default_groups.py +``` + +> Enable MSSP mode and create the groups within all child CIDs. + +```shell +python3 default_groups.py -k $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET -m +``` + +> Enable MSSP mode and create the groups within a specific child CID. + +```shell +python3 default_groups.py -k $FALCON_CLIENT_ID -s $FALCON_CLIENT_SECRET -c CHILD_CID +``` + +> API debugging can be enabled using the `-d` argument. + +```shell +python3 default_groups.py -d +``` + +#### Command-line help +Command-line help is available via the `-h` argument. + +```shell +usage: default_groups.py [-h] [-d] [-o OUTPUT_PATH] [-m] [-k CLIENT_ID] [-s CLIENT_SECRET] + + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | |::.. . | FalconPy +`-------' `-------' + +·▄▄▄▄ ▄▄▄ .·▄▄▄ ▄▄▄· ▄• ▄▌▄▄▌ ▄▄▄▄▄ ▄▄ • ▄▄▄ ▄• ▄▌ ▄▄▄·.▄▄ · +██▪ ██ ▀▄.▀·▐▄▄·▐█ ▀█ █▪██▌██• •██ ▐█ ▀ ▪▀▄ █·▪ █▪██▌▐█ ▄█▐█ ▀. +▐█· ▐█▌▐▀▀▪▄██▪ ▄█▀▀█ █▌▐█▌██▪ ▐█.▪ ▄█ ▀█▄▐▀▀▄ ▄█▀▄ █▌▐█▌ ██▀·▄▀▀▀█▄ +██. ██ ▐█▄▄▌██▌.▐█ ▪▐▌▐█▄█▌▐█▌▐▌ ▐█▌· ▐█▄▪▐█▐█•█▌▐█▌.▐▌▐█▄█▌▐█▪·•▐█▄▪▐█ +▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ .▀▀▀ ▀▀▀ ·▀▀▀▀ .▀ ▀ ▀█▄▀▪ ▀▀▀ .▀ ▀▀▀▀ + +This script was developed to setup the default groups in a new CID. +It should be run once to create the necessary groups and populate +them with the appropriate assignment rules. + +optional arguments: + -h, --help show this help message and exit + -d, --debug Enable API debugging + -o OUTPUT_PATH, --output_path OUTPUT_PATH + Location to store CSV output + -m, --mssp Return RFM details for child CIDs (MSSP parents only). + +Required arguments: + -k CLIENT_ID, --client_id CLIENT_ID + CrowdStrike Falcon API key + -s CLIENT_SECRET, --client_secret CLIENT_SECRET + CrowdStrike Falcon API secret +``` + +### Example source code +The source code for these examples can be found [here](default_groups.py). + +--- + ## Hosts Report This script replaces the manual daily export of hosts from the Falcon Console that was required to audit host compliance. It was developed to be run as a recurring job and will output a CSV with all hosts in the CID along with other required info that can then be imported into a compliance dashboard or tool. diff --git a/samples/hosts/default_groups.py b/samples/hosts/default_groups.py index 546bdc4d9..68674f948 100755 --- a/samples/hosts/default_groups.py +++ b/samples/hosts/default_groups.py @@ -1,20 +1,69 @@ #!/usr/bin/env python3 -#Please establish an "auth.py" file in the same directory as this script with the "clientid" and "clientsec" variables defined. -#This script was developed to setup the default groups in a new CID. It was developed to be run once and will create the groups and populate them with the appropriate assignment rules. -#Developed by Don-Swanson-Adobe +r""" + _______ __ _______ __ __ __ +| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----. +|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__| +|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____| +|: 1 | |: 1 | +|::.. . | |::.. . | FalconPy +`-------' `-------' -####REPLACE THE FOLLOWING EXAMPLE VARIABLES#### -groups = {"Sensor Uninstall Group": "staticByID", "Phase 0": "none", "Phase 1": "hostname:*'*'","Active Policy": "none", "Windows Servers": "platform_name:'Windows'+product_type_desc:'Server'", "DEV Updates": "tags:'SensorGroupingTags/DEV'", "Golden Images": "tags:'FalconGroupingTags/GoldenImage'", "Windows 7 and Server 2008 R2 Hosts": "(os_version:'Windows Server 2008 R2',os_version:'Windows 7')"} -#Groups are defined as "Group Name": "Assignment Rule" -############################################### +·▄▄▄▄ ▄▄▄ .·▄▄▄ ▄▄▄· ▄• ▄▌▄▄▌ ▄▄▄▄▄ ▄▄ • ▄▄▄ ▄• ▄▌ ▄▄▄·.▄▄ · +██▪ ██ ▀▄.▀·▐▄▄·▐█ ▀█ █▪██▌██• •██ ▐█ ▀ ▪▀▄ █·▪ █▪██▌▐█ ▄█▐█ ▀. +▐█· ▐█▌▐▀▀▪▄██▪ ▄█▀▀█ █▌▐█▌██▪ ▐█.▪ ▄█ ▀█▄▐▀▀▄ ▄█▀▄ █▌▐█▌ ██▀·▄▀▀▀█▄ +██. ██ ▐█▄▄▌██▌.▐█ ▪▐▌▐█▄█▌▐█▌▐▌ ▐█▌· ▐█▄▪▐█▐█•█▌▐█▌.▐▌▐█▄█▌▐█▪·•▐█▄▪▐█ +▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ .▀▀▀ ▀▀▀ ·▀▀▀▀ .▀ ▀ ▀█▄▀▪ ▀▀▀ .▀ ▀▀▀▀ +This script was developed to setup the default groups in a new CID. +It should be run once to create the necessary groups and populate +them with the appropriate assignment rules. -#Import API Harness and Auth File -from falconpy import APIHarness -from auth import * +Note: This sample demonstrates pythonic response handling using the + Advanced Uber Class (APIHarnessV2). -#Function to add groups -def add_group(name,rule): +Developed by @Don-Swanson-Adobe +""" +import os +import logging +from argparse import ArgumentParser, RawTextHelpFormatter, Namespace +from falconpy import APIHarnessV2, APIError + + +def consume_arguments() -> Namespace: + """Consume any provided command line arguments.""" + parser = ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter) + parser.add_argument("-d", "--debug", + help="Enable API debugging", + action="store_true", + default=False + ) + parser.add_argument("-m", "--mssp", + help="Create groups for all child CIDs (MSSP parents only).", + action="store_true", + default=False + ) + parser.add_argument("-c", "--child", + help="Create groups in a specific child CID (MSSP parents only).", + default=None + ) + req = parser.add_argument_group("Required arguments") + req.add_argument("-k", "--client_id", + help="CrowdStrike Falcon API key", + default=os.getenv("FALCON_CLIENT_ID") + ) + req.add_argument("-s", "--client_secret", + help="CrowdStrike Falcon API secret", + default=os.getenv("FALCON_CLIENT_SECRET") + ) + parsed = parser.parse_args() + if not parsed.client_id or not parsed.client_secret: + parser.error("You must provide CrowdStrike API credentials using the '-k' and '-s' arguments.") + + return parsed + + +def add_group(sdk: APIHarnessV2, name: str, rule: str): + """Add the group the the CID.""" if rule == "staticByID": BODY = {"resources": [{ "group_type": "staticByID", @@ -31,17 +80,76 @@ def add_group(name,rule): "name": name, "assignment_rule": rule }]} - response = falcon.command("createHostGroups", body=BODY) - print(response) + try: + sdk.command("createHostGroups", body=BODY) + print(f"{name} group created successfully") + except APIError as api_error: + print(api_error.message) + + + +#### UPDATE THE FOLLOWING DICTIONARY TO MATCH YOUR ENVIRONMENT ########## +# One group will be created for each dictionary item. +# Groups are defined as "Group Name": "Assignment Rule" +groups = { + "Sensor Uninstall Group": "staticByID", + "Phase 0": "none", + "Phase 1": "hostname:*'*'", + "Active Policy": "none", + "Windows Servers": "platform_name:'Windows'+product_type_desc:'Server'", + "DEV Updates": "tags:'SensorGroupingTags/DEV'", + "Golden Images": "tags:'FalconGroupingTags/GoldenImage'", + "Windows 7 and Server 2008 R2 Hosts": "(os_version:'Windows Server 2008 R2',os_version:'Windows 7')" +} +######################################################################### + +# Consume the command line +cmd_line = consume_arguments() + +# Activate debugging if requested +if cmd_line.debug: + logging.basicConfig(level=logging.DEBUG) -#Do the needful for each CID in the auth file -for key, value in cids.items(): - print("\n"+value) - falcon = APIHarness(client_id=clientid, client_secret=clientsec, member_cid=key) +# Create our base authentication dictionary (parent / child) +auth = { + "client_id": cmd_line.client_id, + "client_secret": cmd_line.client_secret, + "debug": cmd_line.debug, + "pythonic": True +} +# If we are in MSSP mode, retrieve our child CID details +if cmd_line.mssp: + parent = APIHarnessV2(**auth) + cids = parent.command("getChildren", ids=parent.command("queryChildren").data) +elif cmd_line.child: + parent = APIHarnessV2(**auth) + try: + cid_name = parent.command("getChildren", ids=cmd_line.child) + except APIError as api_error: + # Throw an error if they provided us an invalid CID + raise SystemExit(api_error.message) + cids = [{"name": cid_name[0]["name"]}] +else: + # If not, we'll just run this in our current tenant + cids = [{"name": "CrowdStrike"}] - #Add groups with variable names dependent on CID Name(Useful for at a glance reporting of All Hosts and RFM Hosts): - groups.update({value + " - All":"hostname:*'*'", value + " - RFM": "reduced_functionality_mode:'yes'"}) +# Do the needful for each CID +for cid in cids: + print(f"Processing {cid['name']}") + if cmd_line.mssp: + # If we're a parent, add this child's CID to our authentication request + auth["member_cid"] = cid["child_cid"] + elif cmd_line.child: + auth["member_cid"] = cmd_line.child + # Authenticate to the API + falcon = APIHarnessV2(**auth) + # Add groups with variable names dependent on CID Name + # (Useful for at a glance reporting of All Hosts and RFM Hosts) + groups.update({ + cid["name"] + " - All": "hostname:*'*'", + cid["name"] + " - RFM": "reduced_functionality_mode:'yes'" + }) - #Add Groups + # Create the groups in the CID for name,rule in groups.items(): - add_group(name,rule) \ No newline at end of file + add_group(falcon, name, rule)