From 861340b4ff925e65df90b5c49236e3ebe7953472 Mon Sep 17 00:00:00 2001 From: danstadler-LW <87735718+danstadler-LW@users.noreply.github.com> Date: Tue, 5 Apr 2022 21:28:18 -0700 Subject: [PATCH 1/2] add --python when publishing avoids this error: Can't determine project language from files. Please use one of [--csharp, --javascript, --typescript, --java, --python, --powershell, --custom] Your Azure Function App has 'FUNCTIONS_WORKER_RUNTIME' set to 'python' while your local project is set to 'None'. You can pass --force to update your Azure app with 'None' as a 'FUNCTIONS_WORKER_RUNTIME' --- azure_loganalytics_sentinel/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure_loganalytics_sentinel/README.md b/azure_loganalytics_sentinel/README.md index 535627b..8c65242 100644 --- a/azure_loganalytics_sentinel/README.md +++ b/azure_loganalytics_sentinel/README.md @@ -39,7 +39,7 @@ function-app-name = "function-app-functacclc7f" Now execute the Function App Code Review ``` -cd ../azure_function && func azure functionapp publish function-app-functacclc7f +cd ../azure_function && func azure functionapp publish function-app-functacclc7f --python ``` Copy the webhook URL @@ -56,4 +56,4 @@ You'll have to create a webhook using the previous URL, and also an Alert Rule t If the table name is LaceworkEvents, log analytics will show it as a custom log field, so the queries must be done against the LaceworkEvents_CL ``` LaceworkEvents_CL -``` \ No newline at end of file +``` From 37cb7b79e5d04c6ce0e44240a7a96cb1abe74796 Mon Sep 17 00:00:00 2001 From: danstadler-LW <87735718+danstadler-LW@users.noreply.github.com> Date: Sun, 10 Apr 2022 16:42:54 -0700 Subject: [PATCH 2/2] commiting some demo changes for Monday THG meeting --- .../lacework-to-loganalytics/__init__.py | 95 ++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/azure_loganalytics_sentinel/azure_function/lacework-to-loganalytics/__init__.py b/azure_loganalytics_sentinel/azure_function/lacework-to-loganalytics/__init__.py index 3066a5c..7d9a150 100644 --- a/azure_loganalytics_sentinel/azure_function/lacework-to-loganalytics/__init__.py +++ b/azure_loganalytics_sentinel/azure_function/lacework-to-loganalytics/__init__.py @@ -42,6 +42,20 @@ def main(req: func.HttpRequest) -> func.HttpResponse: logging.debug(req.get_body()) body = req.get_body() #body = json.dumps(req.get_body().decode()) + + + ######################################################################### + ## patch in LW calls here + lacework_client = LaceworkClient(api_key=os.getenv("LW_API_KEY"), + api_secret=os.getenv("LW_API_SECRET"), + account=os.getenv("LW_ACCOUNT")) + + event_id = body["event_id"] + event_details = get_event_details_for_id(lacework_client, event_id) + merge_details_into_event_body(body, event_details) + ######################################################################### + + post_data(customer_id, shared_key, body, log_type) logging.info("Message was forwarded to Log Analytics workspace "+customer_id) @@ -55,11 +69,13 @@ def main(req: func.HttpRequest) -> func.HttpResponse: 'get_body': req.get_body().decode() }) ) + + + # https://medium.com/slalom-build/reading-and-writing-to-azure-log-analytics-c78461056862 # Required Function to build the Authorization signature for the Azure Log Analytics Data Collector API. # References: https://docs.microsoft.com/azure/azure-monitor/platform/data-collector-api # and https://docs.microsoft.com/azure/azure-functions/functions-reference-python#environment-variables - def build_signature(customer_id, shared_key, date, content_length, method, content_type, resource): x_headers = 'x-ms-date:' + date string_to_hash = method + "\n" + str(content_length) + "\n" + content_type + "\n" + x_headers + "\n" + resource @@ -97,3 +113,80 @@ def post_data(customer_id, shared_key, body, log_type): else: logging.error("Error during sending logs to Azure Sentinel. Response code: {}".format(response.status_code)) + + + + + +def get_event_details_for_id(lacework_client, event_id): + # Get event details for specified ID + event_details = lacework_client.events.get_details(event_id) + return event_details + + +## for demoing events generated by Polygraph on AWS CloudTrail +def demo_aws_anomaly_event(lacework_client): + event_id = 131174 + + ## This is an example webhook payload, prior to any additional decoration. + body = { + "event_title": "User used service in Region", + "event_link": "https://customerdemo.lacework.net/ui/investigation/recents/EventDossier-131174", + "lacework_account": "customerdemo", + "event_source": "AWSCloudTrail", + "event_description":"For account: 463783698038 ( tech-ally) : User IAMUser/463783698038:teresa.oreilly used api UntagResource for service kms.amazonaws.com in region us-west-2", + "event_timestamp":"04 Apr 2022 16:00 GMT", + "event_type": "Anomaly", + "event_id": "131174", + "event_severity": "4", + "rec_id": "" + } + print (body) + + # call back to the LW API for more details + event_details = get_event_details_for_id(lacework_client, event_id) + + # dive into the data + entity_map = event_details["data"][0]["ENTITY_MAP"] + # print (entity_map) + + # these are sections of this specific type of event data + user_list = entity_map["CT_User"] + region_list = entity_map["Region"] + api_list = entity_map["API"] + source_ip_address_list = entity_map["SourceIpAddress"] + + ## now we'll actually add some values to the payload, before shipping to Sentinel + username = user_list[0]["USERNAME"] + body["username"] = username + + region = region_list[0]["REGION"] + body["region"] = region + + service = api_list[0]["SERVICE"] + api = api_list[0]["API"] + body["service"] = service + body["api"] = api + + ip_address = source_ip_address_list[0]["IP_ADDRESS"] + country = source_ip_address_list[0]["COUNTRY"] + region = source_ip_address_list[0]["REGION"] + + body["ip_address"] = ip_address + body["country"] = country + body["region"] = region + + print ("") + print ("-----------------------") + print ("modified body: ") + print ("") + print (body) + + return body + + + +## not yet built +def merge_details_into_event_body(body, event_details): + return {} + ##raise RuntimeError('function not yet ready')