Example #1
0
    def serviceAuth(self):
        status = self.getConfig()
        if status:
            self.authorization = OAuth2(
                creds={
                    'client_id': self.config["falcon_client_id"],
                    'client_secret': self.config["falcon_client_secret"]
                },
                base_url=self.config["falcon_base_url"])

            try:
                check = self.authorization.token()
                if check["status_code"] == 429:
                    pytest.skip("Rate limit hit")
                self.token = check['body']['access_token']
                # Force a token authentication
                _ = Hosts(access_token=self.token)
            except KeyError:
                self.token = False

            if self.token:
                return True
            else:
                return False
        else:
            return False
Example #2
0
    def failServiceAuth(self):
        self.authorization = Hosts(client_id="BadClientID",
                                   client_secret="BadClientSecret",
                                   member_cid="123456789ABCDEFG",
                                   base_url="us3")
        # self.authorization.auth_object.base_url = "nowhere"
        try:
            self.token = self.authorization.auth_object.token(
            )['body']['access_token']
        except KeyError:
            self.token = False

        self.authorization.auth_object.revoke(self.token)

        if self.token:
            return False
        else:
            return True
def get_install_params(events, context):
    """Retrieve necessary installation detail from CrowdStrike cloud."""
    api_base_url, api_client_id, api_client_secret = get_ssm_params(events)

    try:
        auth = OAuth2(client_id=api_client_id,
                      client_secret=api_client_secret,
                      base_url=api_base_url
                      )
    except Exception as err:
        raise ValueError(f"Failure while interacting with CrowdStrike backend. Error: {err}") from err

    try:
        print('Requesting Customer ID from CrowdStrike backend.')
        sensor = SensorDownload(auth_object=auth)
        get_ccid = sensor.get_sensor_installer_ccid()
        if get_ccid["status_code"] != 200:
            error_detail = get_ccid['body']['errors'][0]
            code = error_detail["code"]
            msg = error_detail["message"]
            raise ValueError(f"Received non success response {code}. Error: {msg}")
        customer_ccid = get_ccid['body']['resources'][0]
        print('Successfully received Customer ID.')
    except Exception as err:
        raise ValueError(f"Failure while interacting with CrowdStrike backend. Error {err}") from err

    try:
        hosts = Hosts(auth_object=auth)

        id_to_retrieve = events["InstanceIds"][0]
        host_aid = hosts.query_devices_by_filter(filter=f"instance_id:'{id_to_retrieve}'")

        skip_install = "NO"
        if host_aid["status_code"] == 200:
            if host_aid["body"]["resources"]:
                skip_install = "YES"
        print('Checked for a skipped install')

        return {
            'CCID': customer_ccid,
            'SkipInstall': skip_install
            }
    except Exception as err:
        raise ValueError(f"Failure while interacting with CrowdStrike backend. Error {err}") from err
def hide_falcon_instance(events, context):
    """Hide the host from the Falcon Console."""
    try:
        api_base_url, api_client_id, api_client_secret = get_ssm_params(events)

        print("Hiding terminated instance in Falcon")
        hosts = Hosts(client_id=api_client_id,
                      client_secret=api_client_secret,
                      base_url=api_base_url
                      )

        for id_to_retrieve in events["InstanceIds"]:
            host_aid = hosts.query_devices_by_filter(filter=f"instance_id:'{id_to_retrieve}'")

            if host_aid["status_code"] != 200:
                returned = f"AWS instance: {id_to_retrieve} was not found in your Falcon tenant"

            if host_aid["body"]["resources"]:
                falcon_host_id = host_aid["body"]["resources"][0]
                hide_result = hosts.perform_action(action_name="hide_host", ids=falcon_host_id)
                if hide_result["status_code"] == 202:
                    returned = (
                        f"AWS Instance: {id_to_retrieve} | Falcon Resource ID: {falcon_host_id} was "
                        "successfully hidden"
                    )
                elif hide_result["status_code"] == 404:
                    returned = (
                        f"AWS Instance: {id_to_retrieve} does not have a sensor installed."
                    )
                else:
                    err_detail = hide_result["body"]["errors"][0]
                    code = err_detail["code"]
                    msg = err_detail["message"]
                    raise ValueError(f"Received non success response {code} while attempting to hide host. Error: {msg}")

            else:
                returned = f"AWS instance: {id_to_retrieve} was not found in your Falcon tenant"

            return returned
    except Exception as err:
        raise ValueError(f"Failure while interacting with CrowdStrike backend. Error {err}") from err
Example #5
0
    def serviceAuthNoSSL(self):
        status = self.getConfig()
        if status:
            self.authorization = Hosts(creds={
                'client_id':
                self.config["falcon_client_id"],
                'client_secret':
                self.config["falcon_client_secret"]
            },
                                       ssl_verify=False,
                                       base_url=self.config["falcon_base_url"])

            check = self.authorization.auth_object.token()
            if check["status_code"] == 429:
                pytest.skip("Rate limit hit")
            if check["body"]["access_token"]:
                self.authorization.auth_object.revoke(
                    check["body"]["access_token"])
                return True
            else:
                return False
        else:
            return False
Example #6
0
class TestAuthorization():
    def getConfigObject(self):
        status = self.getConfig()
        if status:
            os.environ["FALCONPY_DEBUG_CLIENT_ID"] = self.config[
                "falcon_client_id"]
            os.environ["FALCONPY_DEBUG_CLIENT_SECRET"] = self.config[
                "falcon_client_secret"]
            self.authorization = OAuth2(
                creds={
                    "client_id": self.config["falcon_client_id"],
                    "client_secret": self.config["falcon_client_secret"]
                },
                base_url=self.config["falcon_base_url"])
        try:
            global shared_token
            if not shared_token:
                shared_token = self.authorization.token(
                )['body']['access_token']
        except KeyError:
            shared_token = False

        return self.authorization

    def getConfigExtended(self):
        if "FALCONPY_DEBUG_TOKEN" in os.environ:
            self.token = os.getenv("FALCONPY_DEBUG_TOKEN")
            self.config = {}
            self.config["falcon_client_id"] = os.environ[
                "FALCONPY_DEBUG_CLIENT_ID"]
            self.config["falcon_client_secret"] = os.environ[
                "FALCONPY_DEBUG_CLIENT_SECRET"]
            if "DEBUG_API_BASE_URL" in os.environ:
                self.config["falcon_base_url"] = os.getenv(
                    "DEBUG_API_BASE_URL")
            else:
                self.config["falcon_base_url"] = "https://api.crowdstrike.com"
        else:
            status = self.getConfig()
            if status:
                os.environ["FALCONPY_DEBUG_CLIENT_ID"] = self.config[
                    "falcon_client_id"]
                os.environ["FALCONPY_DEBUG_CLIENT_SECRET"] = self.config[
                    "falcon_client_secret"]
                self.authorization = OAuth2(
                    creds={
                        "client_id": self.config["falcon_client_id"],
                        "client_secret": self.config["falcon_client_secret"]
                    },
                    base_url=self.config["falcon_base_url"])
            try:
                self.token = self.authorization.token()['body']['access_token']
                os.environ["FALCONPY_DEBUG_TOKEN"] = self.token
            except KeyError:
                self.token = False

        return self.token

    def clear_env_token(self):
        if "FALCONPY_DEBUG_TOKEN" in os.environ:
            os.environ["FALCONPY_DEBUG_TOKEN"] = ""
            os.environ["FALCONPY_DEBUG_CLIENT_ID"] = ""
            os.environ["FALCONPY_DEBUG_CLIENT_SECRET"] = ""
        return True

    def getConfig(self):
        # Grab our config parameters
        if "DEBUG_API_ID" in os.environ and "DEBUG_API_SECRET" in os.environ:
            self.config = {}
            self.config["falcon_client_id"] = os.getenv("DEBUG_API_ID")
            self.config["falcon_client_secret"] = os.getenv("DEBUG_API_SECRET")
            if "DEBUG_API_BASE_URL" in os.environ:
                self.config["falcon_base_url"] = os.getenv(
                    "DEBUG_API_BASE_URL")
            else:
                self.config["falcon_base_url"] = "auto"
            return True
        else:
            cur_path = os.path.dirname(os.path.abspath(__file__))
            if os.path.exists('%s/test.config' % cur_path):
                with open('%s/test.config' % cur_path, 'r') as file_config:
                    self.config = json.loads(file_config.read())
                return True
            else:
                return False

    def uberAuth(self):
        status = self.getConfig()
        if status:
            self.falcon = APIHarness(creds={
                "client_id":
                self.config["falcon_client_id"],
                "client_secret":
                self.config["falcon_client_secret"],
            },
                                     base_url=self.config["falcon_base_url"])
            self.falcon.authenticate()
            if self.falcon.authenticated:
                return True
            else:
                if self.falcon.base_url == "https://api.laggar.gcw.crowdstrike.com":
                    pytest.skip("GovCloud rate limit hit")
                else:
                    return False
        else:
            return False

    def failUberMSSPAuth(self):
        status = self.getConfig()
        if status:
            self.falcon = APIHarness(
                client_id=self.config["falcon_client_id"],
                client_secret=self.config["falcon_client_secret"],
                member_cid="1234567890ABCDEFG")
            self.falcon.authenticate()
            if not self.falcon.authenticated:
                return True
            else:
                return False
        else:
            return False

    def uberRevoke(self):
        return self.falcon.deauthenticate()

    def serviceAuth(self):
        status = self.getConfig()
        if status:
            self.authorization = OAuth2(
                creds={
                    'client_id': self.config["falcon_client_id"],
                    'client_secret': self.config["falcon_client_secret"]
                },
                base_url=self.config["falcon_base_url"])

            try:
                check = self.authorization.token()
                if check["status_code"] == 429:
                    pytest.skip("Rate limit hit")
                self.token = check['body']['access_token']
                # Force a token authentication
                _ = Hosts(access_token=self.token)
            except KeyError:
                self.token = False

            if self.token:
                return True
            else:
                return False
        else:
            return False

    def serviceAuthNoSSL(self):
        status = self.getConfig()
        if status:
            self.authorization = Hosts(creds={
                'client_id':
                self.config["falcon_client_id"],
                'client_secret':
                self.config["falcon_client_secret"]
            },
                                       ssl_verify=False,
                                       base_url=self.config["falcon_base_url"])

            check = self.authorization.auth_object.token()
            if check["status_code"] == 429:
                pytest.skip("Rate limit hit")
            if check["body"]["access_token"]:
                self.authorization.auth_object.revoke(
                    check["body"]["access_token"])
                return True
            else:
                return False
        else:
            return False

    def serviceMSSPAuth(self):
        status = self.getConfig()
        result = False
        if status:
            authorization = OAuth2(
                client_id=self.config["falcon_client_id"],
                client_secret=self.config["falcon_client_secret"],
                member_cid='1234567890ABCDEFG')
            try:
                req = authorization.token()
                if req["status_code"] in [
                        201, 403
                ]:  # Prolly an invalid MSSP cred, 403 is correct
                    result = True
            except KeyError:
                pass

        return result

    def failServiceAuth(self):
        self.authorization = Hosts(client_id="BadClientID",
                                   client_secret="BadClientSecret",
                                   member_cid="123456789ABCDEFG",
                                   base_url="us3")
        # self.authorization.auth_object.base_url = "nowhere"
        try:
            self.token = self.authorization.auth_object.token(
            )['body']['access_token']
        except KeyError:
            self.token = False

        self.authorization.auth_object.revoke(self.token)

        if self.token:
            return False
        else:
            return True

    def serviceRevoke(self):
        try:
            result = self.authorization.revoke(token=self.token)["status_code"]
            if result > 0:
                return True
            else:
                return False
        except KeyError:
            return False

    def credential_logout(self, api: object = None):
        if api:
            return bool(
                api.auth_object.revoke(api.auth_object.token(
                )["body"]["access_token"])["status_code"] in [200, 201])
        else:
            return False

    def test_uberAuth(self):
        assert self.uberAuth() is True
        self.uberRevoke()

    def test_uberRevoke(self):
        self.uberAuth()
        assert self.uberRevoke() is True

    def test_serviceAuth(self):
        assert self.serviceAuth() is True
        self.serviceRevoke()

    # This test disables SSL and will generate a warning in pytest if we don't disable it
    @pytest.mark.filterwarnings(
        "ignore:Unverified HTTPS request is being made.*")
    def test_serviceAuthNoSSL(self):
        assert self.serviceAuthNoSSL() is True

    def test_serviceMSSPAuth(self):
        assert self.serviceMSSPAuth() is True

    def test_uberMSSPAuthFailure(self):
        assert self.failUberMSSPAuth() is True

    def test_serviceRevoke(self):
        self.serviceAuth()
        assert self.serviceRevoke() is True

    def test_failServiceAuth(self):
        assert self.failServiceAuth() is True

    @pytest.mark.skipif(os.getenv("DEBUG_API_BASE_URL", "us1").lower() in [
        "https://api.laggar.gcw.crowdstrike.com", "usgov1"
    ],
                        reason="Unit testing unavailable on US-GOV-1")
    def test_base_url_lookup(self):
        _ = self.getConfig()
        test_falcon = OAuth2(client_id=self.config["falcon_client_id"],
                             client_secret=self.config["falcon_client_secret"],
                             base_url="us1")
        assert bool(test_falcon.token()["status_code"] == 201)

    def test_fail_base_url_lookup(self):
        _ = self.getConfig()
        test_falcon = OAuth2(client_id=self.config["falcon_client_id"],
                             client_secret=self.config["falcon_client_secret"],
                             base_url="nowhere")
        assert bool(test_falcon.token()["status_code"] != 201)
Example #7
0
parser.add_argument(  # CrowdStrike API Client ID
    '-k',
    '--key',
    help='Your CrowdStrike API key ID\n'
    '     Required Scopes\n'
    '     Hosts:     READ\n'
    '     RTR:       WRITE\n'
    '     RTR Admin: WRITE',
    required=True)
parser.add_argument(  # CrowdStrike API Client secret
    '-s',
    '--secret',
    help='Your CrowdStrike API key secret',
    required=True)
args = parser.parse_args()  # Retrieve our provided command line arguments
hostname = args.target  # Grab the hostname of our target from the user
falcon_auth = OAuth2(  # Create an instance of our authentication class
    client_id=args.key,  # and authenticate to the API
    client_secret=args.secret,
)
falcon_hosts = Hosts(
    auth_object=falcon_auth)  # Connect to the Hosts API using our auth object
falcon_rtr = RealTimeResponse(
    auth_object=falcon_auth)  # Connect to the RTR API using our auth object
falcon_rtra = RealTimeResponseAdmin(
    auth_object=falcon_auth
)  # Connect to the RTR Admin API using our auth object

if __name__ == "__main__":
    main()
import platform
# Authentication via the test_authorization.py
from tests import test_authorization as Authorization
# Import our sibling src folder into the path
sys.path.append(os.path.abspath('src'))
# Classes to test - manually imported from sibling folder
# flake8: noqa: E402
from falconpy import RealTimeResponse
from falconpy import Hosts

auth = Authorization.TestAuthorization()
config = auth.getConfigObject()
falcon = RealTimeResponse(auth_object=config)
# Testing direct credential specification here - jshcodes 08.14.21
falcon_hosts = Hosts(client_id=auth.config["falcon_client_id"],
                     client_secret=auth.config["falcon_client_secret"],
                     base_url=auth.config["falcon_base_url"])
AllowedResponses = [200, 204, 400, 404,
                    429]  # Adding rate-limiting as an allowed response for now


class TestRTR:
    def rtr_list_all_sessions(self):
        if falcon.RTR_ListAllSessions(
                parameters={"limit": 1})["status_code"] in AllowedResponses:
            return True
        else:
            return False

    def rtr_session_tester(self):
        returned = False
Example #9
0
        "updated_on", "hostname", "local_ip", "os_version", "service_provider",
        "remediation"
    ]
    sort_type = args.sort.strip().lower()
    if sort_type in sort_types:
        SORT = sort_type

SORT_REVERSE = args.reverse
PROGRESS = args.show_progress

# Connect to the API and create instances of the SpotlightVulnerabilities and Hosts Service Classes
auth = OAuth2(client_id=args.client_id,
              client_secret=args.client_secret,
              base_url=BASE)
spotlight = SpotlightVulnerabilities(auth_object=auth)
hosts = Hosts(auth_object=auth)

# Headers used for our results display
HEADERS = {
    "cve": "CVE",
    "score": "Score",
    "severity": "Severity",
    "cve_description": "Description",
    "created_on": "Created",
    "updated_on": "Updated",
    "hostname": "Host",
    "local_ip": "IP Address",
    "os_version": "Operating System",
    "service_provider": "Service Provider",
    "remediation": "Remediation"
}
Example #10
0
HOSTNAME = "HOSTNAME_HERE"

mssp = FlightControl(client_id=args.client_id,
                     client_secret=args.client_secret,
                     base_url=BASE)

children = mssp.query_children()
if children["status_code"] == 200:
    if children["body"]["resources"]:
        CIDS = children["body"]["resources"]
        AUTH = []
        for cid in CIDS:
            AUTH.append(
                OAuth2(client_id=args.client_id,
                       client_secret=args.client_secret,
                       base_url=BASE,
                       member_cid=cid))
        for auth in AUTH:
            hosts = Hosts(auth_object=auth)
            lookup = hosts.query_devices_by_filter(
                filter=f"hostname:'{HOSTNAME}'")
            if lookup["body"]["resources"]:
                for host in lookup["body"]["resources"]:
                    detail = hosts.get_device_details(ids=host)
                    host_cid = detail["body"]["resources"][0]["cid"]
                    print(f"Host identified on CID: {host_cid}")
    else:
        print("No children identified.")
else:
    print("No children identified, check permissions.")
Example #11
0

args = parse_command_line()

if args.base_url:
    BASE = args.base_url
else:
    BASE = "us1"

if args.reverse:
    SORT = "hostname.desc"
else:
    SORT = "hostname.asc"

falcon = Hosts(client_id=args.client_id,
               client_secret=args.client_secret,
               base_url=BASE)

OFFSET = 0  # Start at the beginning
DISPLAYED = 0  # This is just so we can show a running count
TOTAL = 1  # Assume there is at least one
LIMIT = 500  # Quick limit to prove pagination
while OFFSET < TOTAL:
    OFFSET, TOTAL, devices = device_list(OFFSET, LIMIT, SORT)
    details = device_detail(devices)
    for detail in details:
        DISPLAYED += 1
        print(
            f"{DISPLAYED}: {detail['hostname']} is on version {detail['agent_version']}"
        )
Example #12
0
def connect_api(key: str, secret: str, base_url: str) -> Hosts:
    """
    Connects to the API and returns an instance of the Hosts Service Class.
    """
    return Hosts(client_id=key, client_secret=secret, base_url=base_url)
Example #13
0
"""
import platform
import os
import sys
import pytest
# Authentication via the test_authorization.py
from tests import test_authorization as Authorization

# Import our sibling src folder into the path
sys.path.append(os.path.abspath('src'))
# Classes to test - manually imported from sibling folder
from falconpy import Hosts

auth = Authorization.TestAuthorization()
config = auth.getConfigObject()
falcon = Hosts(auth_object=config)
AllowedResponses = [200, 202, 400, 404,
                    429]  # Adding rate-limiting as an allowed response for now


class TestHosts:
    """
    Hosts Service Class test harness
    """
    def hosts_add_tag(self):
        """
        Tests tagging functionality
        """
        id_list = "1234567890"
        id_lookup = falcon.QueryDevicesByFilter(parameters={"limit": 1})
        if id_lookup["status_code"] != 429:
Example #14
0
        else:
            # Set the value of offset to be the offset returned
            offset = offset_value
        # This will be the same every time,
        # overrides our init value of 1
        total = result["meta"]["pagination"]["total"]
        # Retrieve the list of IDs returned
        id_list = result["resources"]
        # Append this list to our running list of all IDs
        returning.extend(id_list)

    return returning


# Connect to the Hosts API
falcon = Hosts(client_id=os.environ["FALCON_CLIENT_ID"],
               client_secret=os.environ["FALCON_CLIENT_SECRET"])

# Dictionary to hold our results
compare = {}
# Number of records to return per call, max is 5000
LIMIT = 100

# Standard offset handling using QueryDevicesByFilter
indicator = Indicator(msg="Offset method )( ")
indicator.display()
compare["offset_style"] = get_query_results("offset_style", LIMIT)

# "After" style offset handling using QueryDevicesByFilterScroll
indicator = ind_message(indicator, "Token method")
indicator.display()
compare["token_style"] = get_query_results("token_style", LIMIT)