diff --git a/.script/tests/KqlvalidationsTests/CustomTables/CiscoETD_CL.json b/.script/tests/KqlvalidationsTests/CustomTables/CiscoETD_CL.json new file mode 100644 index 00000000000..ef05996d6c2 --- /dev/null +++ b/.script/tests/KqlvalidationsTests/CustomTables/CiscoETD_CL.json @@ -0,0 +1,169 @@ +{ + "Name": "CiscoETD_CL", + "Properties": [ + { + "Name": "TenantId", + "Type": "guid" + }, + { + "Name": "SourceSystem", + "Type": "String" + }, + { + "Name": "MG", + "Type": "guid" + }, + { + "Name": "ManagementGroupName", + "Type": "String" + }, + { + "Name": "TimeGenerated", + "Type": "DateTime" + }, + { + "Name": "Computer", + "Type": "String" + }, + { + "Name": "RawData", + "Type": "String" + }, + { + "Name": "attachments_s", + "Type": "String" + }, + { + "Name": "senderName_s", + "Type": "String" + }, + { + "Name": "action_type_s", + "Type": "String" + }, + { + "Name": "action_isAutoRemediated_b", + "Type": "Boolean" + }, + { + "Name": "action_folder_s", + "Type": "String" + }, + { + "Name": "action_timestamp_t", + "Type": "DateTime" + }, + { + "Name": "action_publicApiClientId_s", + "Type": "String" + }, + { + "Name": "fromAddress_s", + "Type": "String" + }, + { + "Name": "clientIP_s", + "Type": "String" + }, + { + "Name": "direction_s", + "Type": "String" + }, + { + "Name": "domain_s", + "Type": "String" + }, + { + "Name": "id_g", + "Type": "guid" + }, + { + "Name": "mailboxes_s", + "Type": "String" + }, + { + "Name": "internetMessageId_s", + "Type": "String" + }, + { + "Name": "returnPath_s", + "Type": "String" + }, + { + "Name": "serverIP_s", + "Type": "String" + }, + { + "Name": "subject_s", + "Type": "String" + }, + { + "Name": "toAddresses_s", + "Type": "String" + }, + { + "Name": "timestamp_t", + "Type": "DateTime" + }, + { + "Name": "urls_s", + "Type": "String" + }, + { + "Name": "verdict_isManualVerdict_b", + "Type": "Boolean" + }, + { + "Name": "verdict_userId_s", + "Type": "String" + }, + { + "Name": "verdict_isRetroVerdict_b", + "Type": "Boolean" + }, + { + "Name": "verdict_techniques_s", + "Type": "String" + }, + { + "Name": "verdict_timestamp_t", + "Type": "DateTime" + }, + { + "Name": "verdict_originalVerdict_s", + "Type": "String" + }, + { + "Name": "verdict_latestVerdict_s", + "Type": "String" + }, + { + "Name": "verdict_category_s", + "Type": "String" + }, + { + "Name": "verdict_publicApiClientId_s", + "Type": "String" + }, + { + "Name": "verdict_businessRisk_s", + "Type": "String" + }, + { + "Name": "secureEmailGateway_originalCIP_s", + "Type": "String" + }, + { + "Name": "secureEmailGateway_headerName_s", + "Type": "String" + }, + { + "Name": "envelopeTo_s", + "Type": "String" + }, + { + "Name": "deliveredTo_s", + "Type": "String" + } + ] +} \ No newline at end of file diff --git a/Sample Data/Custom/CiscoETD_CL.json b/Sample Data/Custom/CiscoETD_CL.json new file mode 100644 index 00000000000..cb2d2326621 --- /dev/null +++ b/Sample Data/Custom/CiscoETD_CL.json @@ -0,0 +1,912 @@ +[ + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/25/2023, 7:59:35.000 AM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "bff96714-a763-4b92-ad74-3c830272d88f", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.8.36", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/25/2023, 7:59:30.000 AM", + "urls_s": [ + "http://www.w3.org/1999/xhtml", + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/25/2023, 7:59:34.000 AM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/25/2023, 7:00:04.000 AM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "58c3e48f-7bef-4440-8c88-34f4a788285e", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.36", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/25/2023, 7:00:00.000 AM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/25/2023, 7:00:02.000 AM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/25/2023, 5:00:04.000 AM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "01ffc902-7676-49bf-8f87-32c90ce05741", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.102", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/25/2023, 4:59:59.000 AM", + "urls_s": [ + "http://www.w3.org/1999/xhtml", + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/25/2023, 5:00:02.000 AM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/25/2023, 2:59:37.000 AM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "46a083d2-c11b-4bd4-a3db-37664f3c74fd", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.70", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/25/2023, 2:59:10.000 AM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/25/2023, 2:59:34.000 AM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/25/2023, 2:00:07.000 AM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "d60caf51-f27d-4dfd-9595-3fc2f5b36c3c", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.39", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/25/2023, 2:00:02.000 AM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/25/2023, 2:00:05.000 AM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + }, + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/24/2023, 11:00:06.000 PM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "cf68658c-af90-4ab7-bb83-33ab1c3fbfad", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.8.132", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/24/2023, 10:59:58.000 PM", + "urls_s": [ + "http://www.w3.org/1999/xhtml", + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/24/2023, 11:00:05.000 PM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + }, + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/24/2023, 9:01:10.000 PM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "1a6eb9dc-4c27-40f0-8acc-3b3fb40af221", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.86", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/24/2023, 9:01:06.000 PM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/24/2023, 9:01:08.000 PM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/24/2023, 9:00:30.000 PM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "26c11e53-2a7e-4dec-ba7a-3c67c146972c", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.120", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/24/2023, 9:00:00.000 PM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/24/2023, 9:00:29.000 PM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/24/2023, 8:01:15.000 PM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "bbc1acd3-c284-4175-8987-319d9d23d8da", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.8.169", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/24/2023, 8:01:05.000 PM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/24/2023, 8:01:14.000 PM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/24/2023, 8:00:04.000 PM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "cc11433f-9495-4e7b-8240-3f067202d8bf", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.104", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/24/2023, 7:59:59.000 PM", + "urls_s": [ + "http://www.w3.org/1999/xhtml", + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/24/2023, 8:00:03.000 PM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/24/2023, 6:01:10.000 PM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "122d115e-d63d-4c47-baaa-32f85ddf73e1", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.41", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/24/2023, 6:01:06.000 PM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/24/2023, 6:01:09.000 PM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + }, + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/24/2023, 6:00:27.000 PM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "0d351e35-87c4-4a0d-893b-3e6b537d6296", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.16.25", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/24/2023, 6:00:00.000 PM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/24/2023, 6:00:25.000 PM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + }, + { + "TenantId": "50698fc4-c87e-49da-9ec9-e9be573f1878", + "SourceSystem": "RestAPI", + "MG": "", + "ManagementGroupName": "", + "TimeGenerated [UTC]": "1/30/2024, 9:24:14.251 AM", + "Computer": "", + "RawData": "", + "action_publicApiClientId_s": "", + "action_timestamp_t [UTC]": "12/24/2023, 3:59:22.000 PM", + "action_type_s": "move", + "action_isAutoRemediated_b": true, + "action_folder_s": "quarantine", + "attachments_s": [ + { + "SHA256": "a4ffe1a4596218df2ac34138dbb2787cd9972c8753a5579c4736ea5eb6ce58a4", + "filename": "image.png" + } + ], + "clientIP_s": "62.48.148.140", + "direction_s": "incoming", + "domain_s": "sanitized.com", + "id_g": "f506a68d-5cb1-4fd4-9d15-34d8e93aa006", + "mailboxes_s": [ + "sanitized@sanitized.com" + ], + "internetMessageId_s": "sanitized@sanitized.com", + "returnPath_s": "sanitized@sanitized.com", + "serverIP_s": "10.167.8.136", + "subject_s": "Please read - Action is required - Security", + "toAddresses_s": [ + "sanitized@sanitized.com" + ], + "timestamp_t [UTC]": "12/24/2023, 3:59:09.000 PM", + "urls_s": [ + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd", + "http://www.w3.org/1999/xhtml" + ], + "verdict_isManualVerdict_b": false, + "verdict_publicApiClientId_s": "", + "verdict_timestamp_t [UTC]": "12/24/2023, 3:59:16.000 PM", + "verdict_userId_s": "", + "verdict_businessRisk_s": "", + "verdict_techniques_s": [ + { + "type": "References to cryptocurrency", + "severity": "high", + "description": "References to cryptocurrency (Bitcoin) address 15DMMwLTqV4RmYpJZDoNUZvzNikX1m6j4R" + }, + { + "type": "Low content reputation", + "severity": "high", + "description": "Email content has a bad reputation" + } + ], + "verdict_category_s": "scam", + "verdict_isRetroVerdict_b": false, + "verdict_latestVerdict_s": "scam", + "verdict_originalVerdict_s": "scam", + "secureEmailGateway_headerName_s": "X-IronPort-RemoteIP", + "secureEmailGateway_originalCIP_s": "216.71.143.11", + "envelopeTo_s": [ + "sanitized@sanitized.com" + ], + "deliveredTo_s": [ + "sanitized@sanitized.com" + ], + "Type": "CiscoETD_CL", + "_ResourceId": "" + } +] \ No newline at end of file diff --git a/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureFunction.zip b/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureFunction.zip new file mode 100644 index 00000000000..9d3556a960b Binary files /dev/null and b/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureFunction.zip differ diff --git a/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/__init__.py b/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/__init__.py new file mode 100644 index 00000000000..a1773dce819 --- /dev/null +++ b/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/__init__.py @@ -0,0 +1,279 @@ +""" +Azure Function to fetch Email Threat Detection messages from the Cisco ETD Api and send the mesages to Sentinel to be able to analyze them on Log Analytics. +""" +import logging +import datetime +import json +import requests +import hashlib +import hmac +import base64 +import os +from http import HTTPStatus +import azure.functions as func + +# Global variables for Connector +APIKEY = os.environ.get("ApiKey","") +CLIENTID = os.environ.get("ClientId","") +CLIENTSECRET = os.environ.get("ClientSecret","") +WORKSPACEID = os.environ.get("WorkspaceID","") +WORKSPACESHAREDKEY= os.environ.get("SharedKey","") +VERDICTS = os.environ.get("Verdicts","malicious").split(",") +REGION = os.environ.get("Region","us") +TABLENAME = "CiscoETD" +CHUNKSIZE = 20 +PAGESIZE = 50 +APISCHEME = "https://api." +APITOKENENDPOINT = ".etd.cisco.com/v1/oauth/token" +APIMESSAGEENDPOINT = ".etd.cisco.com/v1/messages/search" +LAST = "Last" +NEXT = "Next" +UTCZONE = "Z" + +def retryRequest(url, headers, jsonData=None, retryCount=3): + """ + Function to post messages and retry on failure + :param url: url to post messages to + :param headers: headers to add to the post call + :param jsonData: payload for the post call + :param retryCount: number of retries on failure, default value is set to 3 + :return: response if successful, None otherwise + """ + while retryCount > 0: + try: + response = requests.post(url, headers=headers, json=jsonData, timeout=5) + except Exception as err: + logging.error(f"Error during the request: {err}") + retryCount -= 1 + else: + if response.status_code == HTTPStatus.OK: + logging.info("Post request successful") + return response + elif response.status_code == HTTPStatus.UNAUTHORIZED: + logging.error("Authorization Error while calling post request") + return response + else: + logging.error(f"Post request failed, retrying... status code: {response.status_code}") + retryCount -= 1 + return None + +class ETD(): + """ + Class ETD is responsible for fetching the messages from ETD API + """ + def __init__(self, apiKey, clientId, clientSecret, verdicts, region, lastExecutedTime, currentTime): + self.apiKey = apiKey + self.clientId = clientId + self.clientSecret = clientSecret + self.messageFilter = [v.strip() for v in verdicts] + self.secretToken = "" + self.region = region + self.lastExecutedTime = lastExecutedTime + self.currentUtcTime = currentTime + self.tokenUrl = APISCHEME + self.region + APITOKENENDPOINT + self.messageUrl = APISCHEME + self.region + APIMESSAGEENDPOINT + + def generateToken(self): + """ + Function to generate the token for ETD message search api + :return: True if successful, False otherwise + """ + # Construct token URL + credentials = CLIENTID + ":" + CLIENTSECRET + # Create signature + signature = base64.b64encode(credentials.encode()).decode() + # Construct Headers + headers = { + "Host": "api." + self.region + ".etd.cisco.com", + "clientId": self.clientId, + "secret": self.clientSecret, + "x-api-key": self.apiKey, + "Authorization": "Basic " + signature + } + tokenResponse = retryRequest(url=self.tokenUrl, headers=headers) + if tokenResponse: + if tokenResponse.status_code == HTTPStatus.OK: + self.secretToken = tokenResponse.json().get('accessToken') + return True + return False + + def fetchMessage(self,nextPageToken=None): + """ + Function to fetch messages from ETD message search api + :param nextPageToken: token to fetch messages from next page, default value is None + :return: messages fetched if successful, else empty dictionary + """ + # Construct headers + messageHeaders = { + "Host": "api." + self.region + ".etd.cisco.com", + "x-api-key": self.apiKey, + "Accept": "application/json", + "Authorization": "Bearer "+ self.secretToken + } + # Construct body + messageJson = { + "timestamp":[self.lastExecutedTime, self.currentUtcTime], + "verdicts": self.messageFilter, + "pageSize": PAGESIZE #Each page will consist of PAGESIZE messages + } + # Append pageToken to body, if "nextPageToken" field contains value + if nextPageToken: + messageJson["pageToken"] = nextPageToken + + messageResponse = retryRequest(self.messageUrl, messageHeaders, messageJson) + if messageResponse: + if messageResponse.status_code == HTTPStatus.OK: + logging.info("Message search API call successful") + return messageResponse.json() + elif messageResponse.status_code == HTTPStatus.UNAUTHORIZED: + if not self.generateToken(): + logging.error("Error in generating token for the request") + return {} + messageHeaders["Authorization"] = "Bearer " + self.secretToken + messageResponse = retryRequest(self.messageUrl, messageHeaders, messageJson) + if messageResponse: + if messageResponse.status_code == HTTPStatus.OK: + logging.info("Message search API call successful") + return messageResponse.json() + else: + return {} + else: + return {} + else: + logging.error("Message search API call failed") + return {} + +class Sentinel(): + """ + Class Sentinel is responsible for sending the messages to Log Analytics + """ + @staticmethod + def buildSignature(date, contentLength, method, contentType, resource): + """ + Function to build signature for Authorization for Log Analytics Workspace + :param date: current time in UTC + :param contentLength: length of content + :param method: http method (POST) + :param contentType: type of content in payload(application/json) + :param resource: endpoint for messages to be posted + :return: computed authorization key + """ + xHeaders = 'x-ms-date:' + date + stringToHash = method + "\n" + str(contentLength) + "\n" + contentType + "\n" + xHeaders + "\n" + resource + bytesToHash = bytes(stringToHash, encoding="utf-8") + decodedKey = base64.b64decode(WORKSPACESHAREDKEY) + encodedHash = base64.b64encode(hmac.new(decodedKey, bytesToHash, digestmod=hashlib.sha256).digest()).decode() + authorization = "SharedKey {}:{}".format(WORKSPACEID, encodedHash) + return authorization + + def sendMessagesToSentinel(self,etdMessages): + """ + Function to batch messages received from ETD api + :param etdMessages: Messages retrived from ETD api + """ + messages = etdMessages.get("data").get("messages") + for i in range(0, len(messages), CHUNKSIZE): + batchedMessages = messages[i:i+CHUNKSIZE] + self.postMessages(batchedMessages) + + def postMessages(self, body): + """ + Function to post messages to log analytics + :param body: payload body for post call + """ + method = 'POST' + contentType = 'application/json' + resource = '/api/logs' + rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT') + contentLength = len(json.dumps(body)) + signature = self.buildSignature(rfc1123date, contentLength , method, contentType, resource) + uri = "https://" + WORKSPACEID + ".ods.opinsights.azure.com" + resource + "?api-version=2016-04-01" + headers = { + 'content-type': contentType, + 'Authorization': signature, + 'Log-Type': TABLENAME, + 'x-ms-date': rfc1123date + } + try: + response = retryRequest(uri, headers, body) + except Exception as err: + logging.error("Error during sending logs to Azure Sentinel: {}".format(err)) + else: + if response: + if response.status_code == HTTPStatus.OK: + logging.info("Messages have been successfully sent to Azure Sentinel.") + else: + logging.error("Error during sending messages to Azure Sentinel. Response code: {}".format(response.status_code)) + else: + logging.error("Failed to post data to Azure Sentinel") + +def setAndValidateEnvConfigurations(): + """ + Function to validate the environment variables set + :return: True is all configurations are set, else False + """ + missingConfigurations = [] + invalidVerdicts = [] + verdicts = ['spam', 'malicious', 'phishing', 'graymail', 'neutral', 'bec', 'scam', 'noVerdict'] + defaultValues = {"Region": "us", "Verdicts":"malicious"} + requiredConfigurations = ['ApiKey', 'ClientId', 'ClientSecret', 'WorkspaceID', 'SharedKey', 'Region', 'Verdicts' ] + for config in requiredConfigurations: + if os.environ.get(config) is None or len(os.environ.get(config)) == 0: + if config not in defaultValues: + missingConfigurations.append(config) + else: + logging.error(f"Configuration is not set for {config}, using default value {defaultValues[config]}" ) + if os.environ.get(config) and config == "Verdicts": + verdictList = os.environ.get(config).split(",") + verdictList = [v.strip() for v in verdictList] + for verdict in verdictList: + if verdict not in verdicts: + invalidVerdicts.append(verdict) + if invalidVerdicts: + strOfVerdicts = ','.join([str(elem) for elem in invalidVerdicts]) + logging.error(f"Encountered invalid verdict, {strOfVerdicts}") + if missingConfigurations: + strOfConfig = ','.join([str(ele) for ele in missingConfigurations]) + logging.error(f"Please set the required configurations as environment variables {strOfConfig}") + return False + return True + +def ciscoEtdConnector(last_timestamp_utc, next_timestamp_utc): + """ + Entry point of the code, responsible for fetching ETD messages and post it to Microsoft Sentinel + """ + # Check if env variables are configured + if not setAndValidateEnvConfigurations(): + return + # Create Sentinel class object + sentinelObj = Sentinel() + # Create ETD class object + etdObj = ETD(APIKEY, CLIENTID, CLIENTSECRET, VERDICTS, REGION, last_timestamp_utc, next_timestamp_utc) + nextPageToken = None + #Generate Token for ETD api + if not etdObj.generateToken(): + logging.error("Error in generating token for etd message search") + return + while True: + # Fetch messages from ETD + etdMessages = etdObj.fetchMessage(nextPageToken) + # Check for pageToken in retrieved messages + nextPageToken = etdMessages.get("nextPageToken") + if not etdMessages.get("data") or not nextPageToken: + break + # Posting ETD messages to Sentinel + sentinelObj.sendMessagesToSentinel(etdMessages) + +def main(mytimer: func.TimerRequest) -> None: + utc_timestamp = datetime.datetime.utcnow().replace( + tzinfo=datetime.timezone.utc).isoformat() + + # get last and next execution time + last_timestamp_utc = mytimer.schedule_status[LAST].replace("+00:00", UTCZONE) + next_timestamp_utc = mytimer.schedule_status[NEXT].replace("+00:00", UTCZONE) + + if mytimer.past_due: + logging.info('The timer is past due!') + + logging.info('Python timer trigger function ran at %s', utc_timestamp) + ciscoEtdConnector(last_timestamp_utc, next_timestamp_utc) diff --git a/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/function.json b/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/function.json new file mode 100644 index 00000000000..6cac0b43ff9 --- /dev/null +++ b/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/function.json @@ -0,0 +1,11 @@ +{ + "scriptFile": "__init__.py", + "bindings": [ + { + "name": "mytimer", + "type": "timerTrigger", + "direction": "in", + "schedule": "0 */5 * * * *" + } + ] +} \ No newline at end of file diff --git a/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/host.json b/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/host.json new file mode 100644 index 00000000000..fd4bee790b9 --- /dev/null +++ b/Solutions/Cisco ETD/Data Connectors/CiscoETDAzureSentinelConnector/host.json @@ -0,0 +1,15 @@ +{ + "version": "2.0", + "logging": { + "applicationInsights": { + "samplingSettings": { + "isEnabled": true, + "excludedTypes": "Request" + } + } + }, + "extensionBundle": { + "id": "Microsoft.Azure.Functions.ExtensionBundle", + "version": "[3.*, 4.0.0)" + } +} \ No newline at end of file diff --git a/Solutions/Cisco ETD/Data Connectors/CiscoETD_API_FunctionApp.json b/Solutions/Cisco ETD/Data Connectors/CiscoETD_API_FunctionApp.json new file mode 100644 index 00000000000..38934bbdb16 --- /dev/null +++ b/Solutions/Cisco ETD/Data Connectors/CiscoETD_API_FunctionApp.json @@ -0,0 +1,123 @@ +{ + "id": "CiscoETD", + "title": "Cisco ETD", + "publisher": "Cisco", + "descriptionMarkdown": "The connector fetches data from ETD api for threat analysis", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "CiscoETD_CL", + "baseQuery": "CiscoETD_CL" + } + ], + "sampleQueries": [ + { + "description" : "Incidents aggregated over a period on verdict type", + "query": "CiscoETD_CL | summarize ThreatCount = count() by verdict_category_s, TimeBin = bin(TimeGenerated, 1h) | project TimeBin, verdict_category_s, ThreatCount | render columnchart" + } + ], + "dataTypes": [ + { + "name": "CiscoETD_CL", + "lastDataReceivedQuery": "CiscoETD_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "CiscoETD_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)" + ] + } + ], + "availability": { + "status": 1, + "isPreview": true + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + + "customs": [ + { + "name": "Microsoft.Web/sites permissions", + "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)." + }, + { + "name": "Email Threat Defense API, API key, Client ID and Secret", + "description": "Ensure you have the API key, Client ID and Secret key." + } + ] + }, + "instructionSteps": [ + { + "title": "", + "description": ">**NOTE:** This connector uses Azure Functions to connect to the ETD API to pull its logs into Microsoft Sentinel." + }, + { + "title": "", + "description": "**Follow the deployment steps to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the ETD data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following).\n", + "instructions": [ + { + "parameters": { + "fillWith": [ + "WorkspaceId" + ], + "label": "Workspace ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "fillWith": [ + "PrimaryKey" + ], + "label": "Primary Key" + }, + "type": "CopyableLabel" + } + ] + }, + { + "title": "Azure Resource Manager (ARM) Template", + "description": "Use this method for automated deployment of the Cisco ETD data connector using an ARM Template.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-CiscoETD-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Region**. \n3. Enter the **WorkspaceID**, **SharedKey**, **ClientID**, **ClientSecret**, **ApiKey**, **Verdicts**, **ETD Region**\n4. Click **Create** to deploy." + } + ], + "metadata": { + "id": "CiscoETD_connector", + "version": "1.0.0", + "kind": "dataConnector", + "source": { + "kind": "ETD API", + "name": "ETD API" + }, + "author": { + "name": "Cisco" + }, + "support": { + "tier": "Developer Support", + "name": "Cisco" + + } + } +} diff --git a/Solutions/Cisco ETD/Data Connectors/azuredeploy_CiscoETD_API_FunctionApp.json b/Solutions/Cisco ETD/Data Connectors/azuredeploy_CiscoETD_API_FunctionApp.json new file mode 100644 index 00000000000..22580a5a548 --- /dev/null +++ b/Solutions/Cisco ETD/Data Connectors/azuredeploy_CiscoETD_API_FunctionApp.json @@ -0,0 +1,326 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "FunctionName": { + "defaultValue": "CiscoETD", + "minLength": 1, + "type": "string" + }, + "WorkspaceName": { + "type": "string", + "defaultValue": "", + "minLength": 1, + "metadata": { + "description": "Log analytics workspace name" + } + }, + "WorkspaceID": { + "type": "string", + "defaultValue": "", + "minLength": 1 + }, + "SharedKey": { + "type": "securestring", + "defaultValue": "", + "minLength": 1 + }, + "ApiKey": { + "type": "securestring", + "defaultValue": "", + "minLength": 1 + }, + "ClientId": { + "type": "securestring", + "defaultValue": "" + }, + "ClientSecret": { + "type": "securestring", + "defaultValue": "" + }, + "Region": { + "type": "string", + "allowedValues": ["Australia", "Beta", "Europe", "India", "United States (US)"], + "metadata": { + "description": "Select the ETD region", + "displayName": "Region" + } + }, + "Verdicts": { + "type": "string", + "metadata": { + "description": "Supported verdicts are: bec, graymail, malicious, neutral, phishing, scam, spam", + "displayName": "Verdicts" + } + }, + "workbookId": { + "type": "string", + "defaultValue": "[newGuid()]", + "metadata": { + "description": "The unique guid for this workbook instance, do not edit the field" + } + } + }, + "variables": { + "suffix": "[substring(toLower(uniqueString(resourceGroup().id, concat('[resourceGroup().locatio', 'n]'))),0,5)]", + "FunctionName": "[toLower(parameters('FunctionName'))]", + "StorageName": "[concat(variables('FunctionName'), variables('suffix'))]", + "ETDregion": { + "Beta": "beta", + "Australia": "au", + "Europe": "de", + "India": "in", + "United States (US)": "us" + }, + "workbookDisplayName": "[concat('EmailThreatDefenseDashboard','-',variables('FunctionName'),'-',variables('suffix'))]", + "workbookType": "sentinel", + "workbookSourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + }, + "resources": [ + { + "type": "Microsoft.Insights/components", + "apiVersion": "2015-05-01", + "name": "[variables('FunctionName')]", + "location": "[resourceGroup().location]", + "kind": "web", + "properties": { + "Application_Type": "web", + "ApplicationId": "[variables('FunctionName')]" + } + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2019-06-01", + "name": "[variables('StorageName')]", + "location": "[resourceGroup().location]", + "sku": { + "name": "Standard_LRS", + "tier": "Standard" + }, + "kind": "StorageV2", + "properties": { + "networkAcls": { + "bypass": "AzureServices", + "virtualNetworkRules": [], + "ipRules": [], + "defaultAction": "Allow" + }, + "supportsHttpsTrafficOnly": true, + "encryption": { + "services": { + "blob": { + "keyType": "Account", + "enabled": true + } + }, + "keySource": "Microsoft.Storage" + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces", + "apiVersion": "2015-11-01-preview", + "name": "[parameters('WorkspaceName')]", + "location": "[resourceGroup().location]" + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD Mailboxes query')]", + "properties": { + "etag": "*", + "displayName": "Top 10 mailboxes", + "category": "ETD", + "query": "CiscoETD_CL | project Mailbox = parse_json(tostring(mailboxes_s)) | mv-expand Mailbox | summarize ThreatCount = count() by tostring(Mailbox) | top 10 by ThreatCount desc | project Mailbox, ThreatCount | render columnchart", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD Verdicts query')]", + "properties": { + "etag": "*", + "displayName": "Distribution of Verdict type", + "category": "ETD", + "query": "CiscoETD_CL | summarize TotalMessages = count() by verdict_category_s | extend Categories = coalesce(verdict_category_s, 'No Verdict') | project Verdicts = Categories, TotalMessages | render piechart title = 'Email Threat Defense Messages by Verdict'", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD Incidents query')]", + "properties": { + "etag": "*", + "displayName": "Incidents aggregated over a period based on verdicts ", + "category": "ETD", + "query": "CiscoETD_CL | summarize ThreatCount = count() by verdict_category_s, TimeBin = bin(TimeGenerated, 1h) | project TimeBin, verdict_category_s, ThreatCount | render columnchart", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD Malicious URL query')]", + "properties": { + "etag": "*", + "displayName": "Malicious URLs", + "category": "ETD", + "query": "CiscoETD_CL | where parse_json(verdict_techniques_s)[6].type == 'Malicious URL'", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD QR Codes query')]", + "properties": { + "etag": "*", + "displayName": "QR Codes", + "category": "ETD", + "query": "CiscoETD_CL | where parse_json(verdict_techniques_s)[6].type == 'QR code'", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD Malicious Sender Domains query')]", + "properties": { + "etag": "*", + "displayName": "Top 10 Malicious Sender Domains", + "category": "ETD", + "query": "CiscoETD_CL | extend Domain = tostring(split(fromAddress_s, '@')[1]) | where isnotnull(Domain) and trim(' ', Domain) != '' | summarize Count = count() by Domain | top 10 by Count desc", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD Malicious Senders query')]", + "properties": { + "etag": "*", + "displayName": "Top 10 Malicious Senders", + "category": "ETD", + "query": "CiscoETD_CL | extend Email = fromAddress_s | where isnotnull(Email) and trim(' ', Email) != '' | summarize Count = count() by Email | top 10 by Count desc", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD Targeted users query')]", + "properties": { + "etag": "*", + "displayName": "Top 10 Targeted users", + "category": "ETD", + "query": "CiscoETD_CL | project Mailbox = parse_json(tostring(mailboxes_s)) | mv-expand Mailbox | summarize Count = count() by tostring(Mailbox) | top 10 by Count desc | project Mailbox", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "name": "[format('{0}/{1}', parameters('WorkspaceName'), 'ETD User Impersonation query')]", + "properties": { + "etag": "*", + "displayName": "User Impersonation", + "category": "ETD", + "query": "CiscoETD_CL | where parse_json(verdict_techniques_s)[6].type == 'User Impersonation'", + "version": 1 + }, + "dependsOn": [ + "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('WorkspaceName'))]" + ] + }, + { + "name": "[parameters('workbookId')]", + "type": "microsoft.insights/workbooks", + "location": "[resourceGroup().location]", + "apiVersion": "2022-04-01", + "dependsOn": [], + "kind": "shared", + "properties": { + "displayName": "[variables('workbookDisplayName')]", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CiscoETD_CL | summarize TotalMessages = count() by verdict_category_s | extend Categories = coalesce(verdict_category_s, 'No Verdict') | project Verdicts = Categories, TotalMessages | render piechart title = 'Email Threat Defense Messages by Verdict'\",\"size\":0,\"title\":\"Total Messages by Threat Type\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 0\",\"styleSettings\":{\"margin\":\"10px\"}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Top 10 Malicious Senders Domains\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CiscoETD_CL\\n| extend Domain = tostring(split(fromAddress_s, '@')[1])\\n| where isnotnull(Domain) and trim(' ', Domain) != ''\\n| summarize Count = count() by Domain\\n| top 10 by Count desc\\n\",\"size\":0,\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"Domain\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"name\":\"query - 0\"}]},\"customWidth\":\"50\",\"name\":\"group - 9\",\"styleSettings\":{\"margin\":\"10px\"}}]},\"customWidth\":\"100\",\"name\":\"group - 6\",\"styleSettings\":{\"margin\":\"10px\",\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CiscoETD_CL\\n| extend Email = fromAddress_s\\n| where isnotnull(Email) and trim(' ', Email) != ''\\n| summarize Count = count() by Email\\n| top 10 by Count desc\",\"size\":0,\"title\":\"Top 10 Malicious Senders\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"margin\":\"10px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CiscoETD_CL\\n| summarize Count = count() by mailboxes_s\\n| top 10 by Count desc\\n| extend Email = tostring(replace(\\\"[\\\\\\\"\\\\\\\"\\\\\\\\[\\\\\\\\]]\\\", \\\"\\\", mailboxes_s))\\n| project Email, Count\",\"size\":0,\"title\":\"Top 10 Targetd users\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"margin\":\"10px\"}}]},\"name\":\"Group_Top 10\"}],\"isLocked\":false,\"fallbackResourceIds\":[\"[variables('workbookSourceId')]\"],\"fromTemplateId\":\"sentinel-UserWorkbook\"}", + "version": "1.0", + "sourceId": "[variables('workbookSourceId')]", + "category": "[variables('workbookType')]" + } + }, + { + "type": "Microsoft.Web/sites", + "apiVersion": "2018-11-01", + "name": "[variables('FunctionName')]", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[resourceId('Microsoft.Storage/storageAccounts', variables('StorageName'))]", + "[resourceId('Microsoft.Insights/components', variables('FunctionName'))]" + ], + "kind": "functionapp,linux", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "name": "[variables('FunctionName')]", + "httpsOnly": true, + "clientAffinityEnabled": true, + "alwaysOn": true, + "reserved": true, + "siteConfig": { + "linuxFxVersion": "python|3.8" + } + }, + "resources": [ + { + "apiVersion": "2018-11-01", + "type": "config", + "name": "appsettings", + "dependsOn": [ + "[concat('Microsoft.Web/sites/', variables('FunctionName'))]" + ], + "properties": { + "FUNCTIONS_EXTENSION_VERSION": "~4", + "FUNCTIONS_WORKER_RUNTIME": "python", + "APPINSIGHTS_INSTRUMENTATIONKEY": "[reference(resourceId('Microsoft.insights/components', variables('FunctionName')), '2015-05-01').InstrumentationKey]", + "APPLICATIONINSIGHTS_CONNECTION_STRING": "[reference(resourceId('microsoft.insights/components', variables('FunctionName')), '2015-05-01').ConnectionString]", + "AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=',variables('StorageName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageName')), '2015-05-01-preview').key1)]", + "WorkspaceID": "[parameters('WorkspaceID')]", + "SharedKey": "[parameters('SharedKey')]", + "ApiKey": "[parameters('ApiKey')]", + "ClientId": "[parameters('ClientId')]", + "ClientSecret": "[parameters('ClientSecret')]", + "Region": "[variables('ETDregion')[parameters('Region')]]", + "Verdicts": "[parameters('Verdicts')]", + "WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-CiscoETD-functionapp" + } + } + ] + } + ] +} diff --git a/Solutions/Cisco ETD/Data Connectors/requirements.txt b/Solutions/Cisco ETD/Data Connectors/requirements.txt new file mode 100644 index 00000000000..7bc0ff44dd6 --- /dev/null +++ b/Solutions/Cisco ETD/Data Connectors/requirements.txt @@ -0,0 +1,6 @@ +# DO NOT include azure-functions-worker in this file +# The Python Worker is managed by Azure Functions platform +# Manually managing azure-functions-worker may cause unexpected issues + +azure-functions +requests \ No newline at end of file diff --git a/Solutions/Cisco ETD/Data/Solution_CiscoETD.json b/Solutions/Cisco ETD/Data/Solution_CiscoETD.json new file mode 100644 index 00000000000..f9c6785ecce --- /dev/null +++ b/Solutions/Cisco ETD/Data/Solution_CiscoETD.json @@ -0,0 +1,17 @@ +{ + "Name": "Cisco ETD", + "Author": "Cisco", + "Logo": "", + "Description": "Cisco ETD Solution for Microsoft Microsoft Sentinel makes it easy to connect cisco email threat data to the Microsoft Sentinel, improving visibility into email threats.", + "Data Connectors": [ + "Data Connectors/CiscoETD_API_FunctionApp.json" + ], + "Workbooks": [ + "Workbooks/CiscoETD.json" + ], + "BasePath": "c:\\GitHub\\Azure-Sentinel\\Solutions\\Cisco ETD", + "Version": "3.0.0", + "Metadata": "SolutionMetadata.json", + "TemplateSpec": true, + "Is1Pconnector": false + } diff --git a/Solutions/Cisco ETD/Package/3.0.0.zip b/Solutions/Cisco ETD/Package/3.0.0.zip new file mode 100644 index 00000000000..3466ec034f6 Binary files /dev/null and b/Solutions/Cisco ETD/Package/3.0.0.zip differ diff --git a/Solutions/Cisco ETD/Package/createUiDefinition.json b/Solutions/Cisco ETD/Package/createUiDefinition.json new file mode 100644 index 00000000000..e9d115096d6 --- /dev/null +++ b/Solutions/Cisco ETD/Package/createUiDefinition.json @@ -0,0 +1,127 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", + "parameters": { + "config": { + "isWizard": false, + "basics": { + "description": "\n\n**Note:** Please refer to the following before installing the solution: \n\n• Review the solution [Release Notes](https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/Cisco%20ETD/ReleaseNotes.md)\n\n • There may be [known issues](https://aka.ms/sentinelsolutionsknownissues) pertaining to this Solution, please refer to them before installing.\n\nCisco ETD Solution for Microsoft Microsoft Sentinel makes it easy to connect cisco email threat data to the Microsoft Sentinel, improving visibility into email threats.\n\n**Data Connectors:** 1, **Workbooks:** 1\n\n[Learn more about Microsoft Sentinel](https://aka.ms/azuresentinel) | [Learn more about Solutions](https://aka.ms/azuresentinelsolutionsdoc)", + "subscription": { + "resourceProviders": [ + "Microsoft.OperationsManagement/solutions", + "Microsoft.OperationalInsights/workspaces/providers/alertRules", + "Microsoft.Insights/workbooks", + "Microsoft.Logic/workflows" + ] + }, + "location": { + "metadata": { + "hidden": "Hiding location, we get it from the log analytics workspace" + }, + "visible": false + }, + "resourceGroup": { + "allowExisting": true + } + } + }, + "basics": [ + { + "name": "getLAWorkspace", + "type": "Microsoft.Solutions.ArmApiControl", + "toolTip": "This filters by workspaces that exist in the Resource Group selected", + "condition": "[greater(length(resourceGroup().name),0)]", + "request": { + "method": "GET", + "path": "[concat(subscription().id,'/providers/Microsoft.OperationalInsights/workspaces?api-version=2020-08-01')]" + } + }, + { + "name": "workspace", + "type": "Microsoft.Common.DropDown", + "label": "Workspace", + "placeholder": "Select a workspace", + "toolTip": "This dropdown will list only workspace that exists in the Resource Group selected", + "constraints": { + "allowedValues": "[map(filter(basics('getLAWorkspace').value, (filter) => contains(toLower(filter.id), toLower(resourceGroup().name))), (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]", + "required": true + }, + "visible": true + } + ], + "steps": [ + { + "name": "dataconnectors", + "label": "Data Connectors", + "bladeTitle": "Data Connectors", + "elements": [ + { + "name": "dataconnectors1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This Solution installs the data connector for Cisco ETD. You can get Cisco ETD custom log data in your Microsoft Sentinel workspace. After installing the solution, configure and enable this data connector by following guidance in Manage solution view." + } + }, + { + "name": "dataconnectors-link2", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more about connecting data sources", + "uri": "https://docs.microsoft.com/azure/sentinel/connect-data-sources" + } + } + } + ] + }, + { + "name": "workbooks", + "label": "Workbooks", + "subLabel": { + "preValidation": "Configure the workbooks", + "postValidation": "Done" + }, + "bladeTitle": "Workbooks", + "elements": [ + { + "name": "workbooks-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "This solution installs workbook(s) to help you gain insights into the telemetry collected in Microsoft Sentinel. After installing the solution, start using the workbook in Manage solution view." + } + }, + { + "name": "workbooks-link", + "type": "Microsoft.Common.TextBlock", + "options": { + "link": { + "label": "Learn more", + "uri": "https://docs.microsoft.com/azure/sentinel/tutorial-monitor-your-data" + } + } + }, + { + "name": "workbook1", + "type": "Microsoft.Common.Section", + "label": "Cisco Email Threat Defense", + "elements": [ + { + "name": "workbook1-text", + "type": "Microsoft.Common.TextBlock", + "options": { + "text": "Analyze email threat data seamlessly with the workbook, correlating information from the Secure Email Threat Defense API to identify and mitigate suspicious activities, providing insights into trends and allowing for precise filtering and analysis" + } + } + ] + } + ] + } + ], + "outputs": { + "workspace-location": "[first(map(filter(basics('getLAWorkspace').value, (filter) => and(contains(toLower(filter.id), toLower(resourceGroup().name)),equals(filter.name,basics('workspace')))), (item) => item.location))]", + "location": "[location()]", + "workspace": "[basics('workspace')]" + } + } +} diff --git a/Solutions/Cisco ETD/Package/mainTemplate.json b/Solutions/Cisco ETD/Package/mainTemplate.json new file mode 100644 index 00000000000..99ade77b11d --- /dev/null +++ b/Solutions/Cisco ETD/Package/mainTemplate.json @@ -0,0 +1,532 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "author": "Cisco", + "comments": "Solution template for Cisco ETD" + }, + "parameters": { + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + }, + "workbook1-name": { + "type": "string", + "defaultValue": "Cisco Email Threat Defense", + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } + } + }, + "variables": { + "_solutionName": "Cisco ETD", + "_solutionVersion": "3.0.0", + "solutionId": "cisco.cisco-etd", + "_solutionId": "[variables('solutionId')]", + "uiConfigId1": "CiscoETD", + "_uiConfigId1": "[variables('uiConfigId1')]", + "dataConnectorContentId1": "CiscoETD", + "_dataConnectorContentId1": "[variables('dataConnectorContentId1')]", + "dataConnectorId1": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "_dataConnectorId1": "[variables('dataConnectorId1')]", + "dataConnectorTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-dc-',uniquestring(variables('_dataConnectorContentId1'))))]", + "dataConnectorVersion1": "1.0.0", + "_dataConnectorcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','dc','-', uniqueString(concat(variables('_solutionId'),'-','DataConnector','-',variables('_dataConnectorContentId1'),'-', variables('dataConnectorVersion1'))))]", + "workbookVersion1": "1.0", + "workbookContentId1": "CiscoETDWorkbook", + "workbookId1": "[resourceId('Microsoft.Insights/workbooks', variables('workbookContentId1'))]", + "workbookTemplateSpecName1": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat(parameters('workspace'),'-wb-',uniquestring(variables('_workbookContentId1'))))]", + "_workbookContentId1": "[variables('workbookContentId1')]", + "workspaceResourceId": "[resourceId('microsoft.OperationalInsights/Workspaces', parameters('workspace'))]", + "_workbookcontentProductId1": "[concat(take(variables('_solutionId'),50),'-','wb','-', uniqueString(concat(variables('_solutionId'),'-','Workbook','-',variables('_workbookContentId1'),'-', variables('workbookVersion1'))))]", + "_solutioncontentProductId": "[concat(take(variables('_solutionId'),50),'-','sl','-', uniqueString(concat(variables('_solutionId'),'-','Solution','-',variables('_solutionId'),'-', variables('_solutionVersion'))))]" + }, + "resources": [ + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('dataConnectorTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "Cisco ETD data connector with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('dataConnectorVersion1')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "GenericUI", + "properties": { + "connectorUiConfig": { + "id": "[variables('_uiConfigId1')]", + "title": "Cisco ETD (using Azure Functions)", + "publisher": "Cisco", + "descriptionMarkdown": "The connector fetches data from ETD api for threat analysis", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "CiscoETD_CL", + "baseQuery": "CiscoETD_CL" + } + ], + "sampleQueries": [ + { + "description": "Incidents aggregated over a period on verdict type", + "query": "CiscoETD_CL | summarize ThreatCount = count() by verdict_category_s, TimeBin = bin(TimeGenerated, 1h) | project TimeBin, verdict_category_s, ThreatCount | render columnchart" + } + ], + "dataTypes": [ + { + "name": "CiscoETD_CL", + "lastDataReceivedQuery": "CiscoETD_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "CiscoETD_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)" + ] + } + ], + "availability": { + "status": 1, + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Microsoft.Web/sites permissions", + "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)." + }, + { + "name": "Email Threat Defense API, API key, Client ID and Secret", + "description": "Ensure you have the API key, Client ID and Secret key." + } + ] + }, + "instructionSteps": [ + { + "description": ">**NOTE:** This connector uses Azure Functions to connect to the ETD API to pull its logs into Microsoft Sentinel." + }, + { + "description": "**Follow the deployment steps to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the ETD data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following).\n", + "instructions": [ + { + "parameters": { + "fillWith": [ + "WorkspaceId" + ], + "label": "Workspace ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "fillWith": [ + "PrimaryKey" + ], + "label": "Primary Key" + }, + "type": "CopyableLabel" + } + ] + }, + { + "description": "Use this method for automated deployment of the Cisco ETD data connector using an ARM Template.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-CiscoETD-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Region**. \n3. Enter the **WorkspaceID**, **SharedKey**, **ClientID**, **ClientSecret**, **ApiKey**, **Verdicts**, **ETD Region**\n4. Click **Create** to deploy.", + "title": "Azure Resource Manager (ARM) Template" + } + ], + "metadata": { + "id": "CiscoETD_connector", + "version": "1.0.0", + "kind": "dataConnector", + "source": { + "kind": "ETD API", + "name": "ETD API" + }, + "author": { + "name": "Cisco" + }, + "support": { + "tier": "Developer Support", + "name": "Cisco" + } + } + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "contentId": "[variables('_dataConnectorContentId1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion1')]", + "source": { + "kind": "Solution", + "name": "Cisco ETD", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Cisco" + }, + "support": { + "name": "Cisco Systems", + "tier": "Partner", + "email": "etd-sentinel@cisco.com" + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_dataConnectorContentId1')]", + "contentKind": "DataConnector", + "displayName": "Cisco ETD (using Azure Functions)", + "contentProductId": "[variables('_dataConnectorcontentProductId1')]", + "id": "[variables('_dataConnectorcontentProductId1')]", + "version": "[variables('dataConnectorVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2023-04-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('DataConnector-', last(split(variables('_dataConnectorId1'),'/'))))]", + "dependsOn": [ + "[variables('_dataConnectorId1')]" + ], + "location": "[parameters('workspace-location')]", + "properties": { + "parentId": "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/dataConnectors', variables('_dataConnectorContentId1'))]", + "contentId": "[variables('_dataConnectorContentId1')]", + "kind": "DataConnector", + "version": "[variables('dataConnectorVersion1')]", + "source": { + "kind": "Solution", + "name": "Cisco ETD", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Cisco" + }, + "support": { + "name": "Cisco Systems", + "tier": "Partner", + "email": "etd-sentinel@cisco.com" + } + } + }, + { + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',variables('_dataConnectorContentId1'))]", + "apiVersion": "2021-03-01-preview", + "type": "Microsoft.OperationalInsights/workspaces/providers/dataConnectors", + "location": "[parameters('workspace-location')]", + "kind": "GenericUI", + "properties": { + "connectorUiConfig": { + "title": "Cisco ETD (using Azure Functions)", + "publisher": "Cisco", + "descriptionMarkdown": "The connector fetches data from ETD api for threat analysis", + "graphQueries": [ + { + "metricName": "Total data received", + "legend": "CiscoETD_CL", + "baseQuery": "CiscoETD_CL" + } + ], + "dataTypes": [ + { + "name": "CiscoETD_CL", + "lastDataReceivedQuery": "CiscoETD_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)" + } + ], + "connectivityCriterias": [ + { + "type": "IsConnectedQuery", + "value": [ + "CiscoETD_CL\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)" + ] + } + ], + "sampleQueries": [ + { + "description": "Incidents aggregated over a period on verdict type", + "query": "CiscoETD_CL | summarize ThreatCount = count() by verdict_category_s, TimeBin = bin(TimeGenerated, 1h) | project TimeBin, verdict_category_s, ThreatCount | render columnchart" + } + ], + "availability": { + "status": 1, + "isPreview": false + }, + "permissions": { + "resourceProvider": [ + { + "provider": "Microsoft.OperationalInsights/workspaces", + "permissionsDisplayText": "read and write permissions on the workspace are required.", + "providerDisplayName": "Workspace", + "scope": "Workspace", + "requiredPermissions": { + "write": true, + "read": true, + "delete": true + } + }, + { + "provider": "Microsoft.OperationalInsights/workspaces/sharedKeys", + "permissionsDisplayText": "read permissions to shared keys for the workspace are required. [See the documentation to learn more about workspace keys](https://docs.microsoft.com/azure/azure-monitor/platform/agent-windows#obtain-workspace-id-and-key).", + "providerDisplayName": "Keys", + "scope": "Workspace", + "requiredPermissions": { + "action": true + } + } + ], + "customs": [ + { + "name": "Microsoft.Web/sites permissions", + "description": "Read and write permissions to Azure Functions to create a Function App is required. [See the documentation to learn more about Azure Functions](https://docs.microsoft.com/azure/azure-functions/)." + }, + { + "name": "Email Threat Defense API, API key, Client ID and Secret", + "description": "Ensure you have the API key, Client ID and Secret key." + } + ] + }, + "instructionSteps": [ + { + "description": ">**NOTE:** This connector uses Azure Functions to connect to the ETD API to pull its logs into Microsoft Sentinel." + }, + { + "description": "**Follow the deployment steps to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the ETD data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following).\n", + "instructions": [ + { + "parameters": { + "fillWith": [ + "WorkspaceId" + ], + "label": "Workspace ID" + }, + "type": "CopyableLabel" + }, + { + "parameters": { + "fillWith": [ + "PrimaryKey" + ], + "label": "Primary Key" + }, + "type": "CopyableLabel" + } + ] + }, + { + "description": "Use this method for automated deployment of the Cisco ETD data connector using an ARM Template.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-CiscoETD-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Region**. \n3. Enter the **WorkspaceID**, **SharedKey**, **ClientID**, **ClientSecret**, **ApiKey**, **Verdicts**, **ETD Region**\n4. Click **Create** to deploy.", + "title": "Azure Resource Manager (ARM) Template" + } + ], + "id": "[variables('_uiConfigId1')]" + } + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentTemplates", + "apiVersion": "2023-04-01-preview", + "name": "[variables('workbookTemplateSpecName1')]", + "location": "[parameters('workspace-location')]", + "dependsOn": [ + "[extensionResourceId(resourceId('Microsoft.OperationalInsights/workspaces', parameters('workspace')), 'Microsoft.SecurityInsights/contentPackages', variables('_solutionId'))]" + ], + "properties": { + "description": "CiscoETD Workbook with template version 3.0.0", + "mainTemplate": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "[variables('workbookVersion1')]", + "parameters": {}, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Insights/workbooks", + "name": "[variables('workbookContentId1')]", + "location": "[parameters('workspace-location')]", + "kind": "shared", + "apiVersion": "2021-08-01", + "metadata": { + "description": "Analyze email threat data seamlessly with the workbook, correlating information from the Secure Email Threat Defense API to identify and mitigate suspicious activities, providing insights into trends and allowing for precise filtering and analysis" + }, + "properties": { + "displayName": "[parameters('workbook1-name')]", + "serializedData": "{\"version\":\"Notebook/1.0\",\"items\":[{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CiscoETD_CL | summarize TotalMessages = count() by verdict_category_s | extend Categories = coalesce(verdict_category_s, 'No Verdict') | project Verdicts = Categories, TotalMessages | render piechart title = 'Email Threat Defense Messages by Verdict'\",\"size\":0,\"title\":\"Total Messages by Threat Type\",\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 0\",\"styleSettings\":{\"margin\":\"10px\"}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"title\":\"Top 10 Malicious Senders Domains\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CiscoETD_CL\\n| extend Domain = tostring(split(fromAddress_s, '@')[1])\\n| where isnotnull(Domain) and trim(' ', Domain) != ''\\n| summarize Count = count() by Domain\\n| top 10 by Count desc\\n\",\"size\":0,\"timeContext\":{\"durationMs\":86400000},\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"visualization\":\"categoricalbar\",\"graphSettings\":{\"type\":0,\"topContent\":{\"columnMatch\":\"Domain\",\"formatter\":1},\"centerContent\":{\"columnMatch\":\"Count\",\"formatter\":1,\"numberFormat\":{\"unit\":17,\"options\":{\"maximumSignificantDigits\":3,\"maximumFractionDigits\":2}}}}},\"name\":\"query - 0\"}]},\"customWidth\":\"50\",\"name\":\"group - 9\",\"styleSettings\":{\"margin\":\"10px\"}}]},\"customWidth\":\"100\",\"name\":\"group - 6\",\"styleSettings\":{\"margin\":\"10px\",\"showBorder\":true}},{\"type\":12,\"content\":{\"version\":\"NotebookGroup/1.0\",\"groupType\":\"editable\",\"items\":[{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CiscoETD_CL\\n| extend Email = fromAddress_s\\n| where isnotnull(Email) and trim(' ', Email) != ''\\n| summarize Count = count() by Email\\n| top 10 by Count desc\",\"size\":0,\"title\":\"Top 10 Malicious Senders\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\",\"gridSettings\":{\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"sortBy\":[{\"itemKey\":\"Count\",\"sortOrder\":2}]},\"customWidth\":\"50\",\"name\":\"query - 2\",\"styleSettings\":{\"margin\":\"10px\"}},{\"type\":3,\"content\":{\"version\":\"KqlItem/1.0\",\"query\":\"CiscoETD_CL\\n| summarize Count = count() by mailboxes_s\\n| top 10 by Count desc\\n| extend Email = tostring(replace(\\\"[\\\\\\\"\\\\\\\"\\\\\\\\[\\\\\\\\]]\\\", \\\"\\\", mailboxes_s))\\n| project Email, Count\",\"size\":0,\"title\":\"Top 10 Targetd users\",\"queryType\":0,\"resourceType\":\"microsoft.operationalinsights/workspaces\"},\"customWidth\":\"50\",\"name\":\"query - 3\",\"styleSettings\":{\"margin\":\"10px\"}}]},\"name\":\"Group_Top 10\"}],\"fromTemplateId\":\"sentinel-CiscoETD\",\"$schema\":\"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"}\r\n", + "version": "1.0", + "sourceId": "[variables('workspaceResourceId')]", + "category": "sentinel" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/metadata", + "apiVersion": "2022-01-01-preview", + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/',concat('Workbook-', last(split(variables('workbookId1'),'/'))))]", + "properties": { + "description": "@{workbookKey=CiscoETDWorkbook; logoFileName=cisco-logo-72px.svg; description=Analyze email threat data seamlessly with the workbook, correlating information from the Secure Email Threat Defense API to identify and mitigate suspicious activities, providing insights into trends and allowing for precise filtering and analysis; dataTypesDependencies=System.Object[]; dataConnectorsDependencies=System.Object[]; previewImagesFileNames=System.Object[]; version=1.0; title=Cisco Email Threat Defense; templateRelativePath=CiscoETD.json; subtitle=; provider=Cisco}.description", + "parentId": "[variables('workbookId1')]", + "contentId": "[variables('_workbookContentId1')]", + "kind": "Workbook", + "version": "[variables('workbookVersion1')]", + "source": { + "kind": "Solution", + "name": "Cisco ETD", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Cisco" + }, + "support": { + "name": "Cisco Systems", + "tier": "Partner", + "email": "etd-sentinel@cisco.com" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "contentId": "CiscoETD_CL", + "kind": "DataType" + }, + { + "contentId": "CiscoETD", + "kind": "DataConnector" + } + ] + } + } + } + ] + }, + "packageKind": "Solution", + "packageVersion": "[variables('_solutionVersion')]", + "packageName": "[variables('_solutionName')]", + "packageId": "[variables('_solutionId')]", + "contentSchemaVersion": "3.0.0", + "contentId": "[variables('_workbookContentId1')]", + "contentKind": "Workbook", + "displayName": "[parameters('workbook1-name')]", + "contentProductId": "[variables('_workbookcontentProductId1')]", + "id": "[variables('_workbookcontentProductId1')]", + "version": "[variables('workbookVersion1')]" + } + }, + { + "type": "Microsoft.OperationalInsights/workspaces/providers/contentPackages", + "apiVersion": "2023-04-01-preview", + "location": "[parameters('workspace-location')]", + "properties": { + "version": "3.0.0", + "kind": "Solution", + "contentSchemaVersion": "3.0.0", + "displayName": "Cisco ETD", + "publisherDisplayName": "Cisco Systems", + "descriptionHtml": "
Note: Please refer to the following before installing the solution:
\n• Review the solution Release Notes
\n• There may be known issues pertaining to this Solution, please refer to them before installing.
\nCisco ETD Solution for Microsoft Microsoft Sentinel makes it easy to connect cisco email threat data to the Microsoft Sentinel, improving visibility into email threats.
\nData Connectors: 1, Workbooks: 1
\nLearn more about Microsoft Sentinel | Learn more about Solutions
\n", + "contentKind": "Solution", + "contentProductId": "[variables('_solutioncontentProductId')]", + "id": "[variables('_solutioncontentProductId')]", + "icon": "", + "contentId": "[variables('_solutionId')]", + "parentId": "[variables('_solutionId')]", + "source": { + "kind": "Solution", + "name": "Cisco ETD", + "sourceId": "[variables('_solutionId')]" + }, + "author": { + "name": "Cisco" + }, + "support": { + "name": "Cisco Systems", + "email": "etd-sentinel@cisco.com", + "tier": "Partner" + }, + "dependencies": { + "operator": "AND", + "criteria": [ + { + "kind": "DataConnector", + "contentId": "[variables('_dataConnectorContentId1')]", + "version": "[variables('dataConnectorVersion1')]" + }, + { + "kind": "Workbook", + "contentId": "[variables('_workbookContentId1')]", + "version": "[variables('workbookVersion1')]" + } + ] + }, + "firstPublishDate": "2024-03-04", + "providers": [ + "Cisco" + ], + "categories": { + "domains": [ + "Security - Threat Protection" + ] + } + }, + "name": "[concat(parameters('workspace'),'/Microsoft.SecurityInsights/', variables('_solutionId'))]" + } + ], + "outputs": {} +} diff --git a/Solutions/Cisco ETD/Package/testParameters.json b/Solutions/Cisco ETD/Package/testParameters.json new file mode 100644 index 00000000000..bee1c8ca22d --- /dev/null +++ b/Solutions/Cisco ETD/Package/testParameters.json @@ -0,0 +1,32 @@ +{ + "location": { + "type": "string", + "minLength": 1, + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Not used, but needed to pass arm-ttk test `Location-Should-Not-Be-Hardcoded`. We instead use the `workspace-location` which is derived from the LA workspace" + } + }, + "workspace-location": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "[concat('Region to deploy solution resources -- separate from location selection',parameters('location'))]" + } + }, + "workspace": { + "defaultValue": "", + "type": "string", + "metadata": { + "description": "Workspace name for Log Analytics where Microsoft Sentinel is setup" + } + }, + "workbook1-name": { + "type": "string", + "defaultValue": "Cisco Email Threat Defense", + "minLength": 1, + "metadata": { + "description": "Name for the workbook" + } + } +} diff --git a/Solutions/Cisco ETD/ReleaseNotes.md b/Solutions/Cisco ETD/ReleaseNotes.md new file mode 100644 index 00000000000..9ea3ff5d7fb --- /dev/null +++ b/Solutions/Cisco ETD/ReleaseNotes.md @@ -0,0 +1,3 @@ +| **Version** | **Date Modified (DD-MM-YYYY)** | **Change History** | +|-------------|--------------------------------|---------------------------------------------| +| 3.0.0 | 11-02-2024 | Initial Solution Release | \ No newline at end of file diff --git a/Solutions/Cisco ETD/SolutionMetadata.json b/Solutions/Cisco ETD/SolutionMetadata.json new file mode 100644 index 00000000000..96121078470 --- /dev/null +++ b/Solutions/Cisco ETD/SolutionMetadata.json @@ -0,0 +1,16 @@ +{ + "publisherId": "cisco", + "offerId": "cisco-etd", + "firstPublishDate": "2024-03-04", + "providers": [ + "Cisco" + ], + "categories": { + "domains" : ["Security - Threat Protection"] + }, + "support": { + "name": "Cisco Systems", + "tier": "Partner", + "email": "etd-sentinel@cisco.com" + } +} diff --git a/Solutions/Cisco ETD/Workbooks/CiscoETD.json b/Solutions/Cisco ETD/Workbooks/CiscoETD.json new file mode 100644 index 00000000000..a5d4a996028 --- /dev/null +++ b/Solutions/Cisco ETD/Workbooks/CiscoETD.json @@ -0,0 +1,146 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CiscoETD_CL | summarize TotalMessages = count() by verdict_category_s | extend Categories = coalesce(verdict_category_s, 'No Verdict') | project Verdicts = Categories, TotalMessages | render piechart title = 'Email Threat Defense Messages by Verdict'", + "size": 0, + "title": "Total Messages by Threat Type", + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "50", + "name": "query - 0", + "styleSettings": { + "margin": "10px" + } + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "title": "Top 10 Malicious Senders Domains", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CiscoETD_CL\n| extend Domain = tostring(split(fromAddress_s, '@')[1])\n| where isnotnull(Domain) and trim(' ', Domain) != ''\n| summarize Count = count() by Domain\n| top 10 by Count desc\n", + "size": 0, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "visualization": "categoricalbar", + "graphSettings": { + "type": 0, + "topContent": { + "columnMatch": "Domain", + "formatter": 1 + }, + "centerContent": { + "columnMatch": "Count", + "formatter": 1, + "numberFormat": { + "unit": 17, + "options": { + "maximumSignificantDigits": 3, + "maximumFractionDigits": 2 + } + } + } + } + }, + "name": "query - 0" + } + ] + }, + "customWidth": "50", + "name": "group - 9", + "styleSettings": { + "margin": "10px" + } + } + ] + }, + "customWidth": "100", + "name": "group - 6", + "styleSettings": { + "margin": "10px", + "showBorder": true + } + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CiscoETD_CL\n| extend Email = fromAddress_s\n| where isnotnull(Email) and trim(' ', Email) != ''\n| summarize Count = count() by Email\n| top 10 by Count desc", + "size": 0, + "title": "Top 10 Malicious Senders", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces", + "gridSettings": { + "sortBy": [ + { + "itemKey": "Count", + "sortOrder": 2 + } + ] + }, + "sortBy": [ + { + "itemKey": "Count", + "sortOrder": 2 + } + ] + }, + "customWidth": "50", + "name": "query - 2", + "styleSettings": { + "margin": "10px" + } + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "CiscoETD_CL\n| summarize Count = count() by mailboxes_s\n| top 10 by Count desc\n| extend Email = tostring(replace(\"[\\\"\\\"\\\\[\\\\]]\", \"\", mailboxes_s))\n| project Email, Count", + "size": 0, + "title": "Top 10 Targetd users", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "customWidth": "50", + "name": "query - 3", + "styleSettings": { + "margin": "10px" + } + } + ] + }, + "name": "Group_Top 10" + } + ], + "fallbackResourceIds": [], + "fromTemplateId": "sentinel-CiscoETD", + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" + } diff --git a/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDBlack01.PNG b/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDBlack01.PNG new file mode 100644 index 00000000000..83811e66f77 Binary files /dev/null and b/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDBlack01.PNG differ diff --git a/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDBlack02.PNG b/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDBlack02.PNG new file mode 100644 index 00000000000..4078a55494f Binary files /dev/null and b/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDBlack02.PNG differ diff --git a/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDWhite01.PNG b/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDWhite01.PNG new file mode 100644 index 00000000000..7efa5e1cf90 Binary files /dev/null and b/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDWhite01.PNG differ diff --git a/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDWhite02.PNG b/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDWhite02.PNG new file mode 100644 index 00000000000..669724c965e Binary files /dev/null and b/Solutions/Cisco ETD/Workbooks/Images/Preview/CiscoETDWhite02.PNG differ diff --git a/Workbooks/Images/Preview/CiscoETDBlack01.PNG b/Workbooks/Images/Preview/CiscoETDBlack01.PNG new file mode 100644 index 00000000000..83811e66f77 Binary files /dev/null and b/Workbooks/Images/Preview/CiscoETDBlack01.PNG differ diff --git a/Workbooks/Images/Preview/CiscoETDBlack02.PNG b/Workbooks/Images/Preview/CiscoETDBlack02.PNG new file mode 100644 index 00000000000..4078a55494f Binary files /dev/null and b/Workbooks/Images/Preview/CiscoETDBlack02.PNG differ diff --git a/Workbooks/Images/Preview/CiscoETDWhite01.PNG b/Workbooks/Images/Preview/CiscoETDWhite01.PNG new file mode 100644 index 00000000000..7efa5e1cf90 Binary files /dev/null and b/Workbooks/Images/Preview/CiscoETDWhite01.PNG differ diff --git a/Workbooks/Images/Preview/CiscoETDWhite02.PNG b/Workbooks/Images/Preview/CiscoETDWhite02.PNG new file mode 100644 index 00000000000..669724c965e Binary files /dev/null and b/Workbooks/Images/Preview/CiscoETDWhite02.PNG differ diff --git a/Workbooks/WorkbooksMetadata.json b/Workbooks/WorkbooksMetadata.json index 0a75334b41f..36e730de143 100644 --- a/Workbooks/WorkbooksMetadata.json +++ b/Workbooks/WorkbooksMetadata.json @@ -172,6 +172,7 @@ "subtitle": "", "provider": "Microsoft" }, + { "workbookKey": "ExchangeOnlineWorkbook", "logoFileName": "office365_logo.svg", @@ -3450,6 +3451,28 @@ "subtitle": "", "provider": "Armorblox" }, +{ + "workbookKey": "CiscoETDWorkbook", + "logoFileName": "cisco-logo-72px.svg", + "description": "Analyze email threat data seamlessly with the workbook, correlating information from the Secure Email Threat Defense API to identify and mitigate suspicious activities, providing insights into trends and allowing for precise filtering and analysis", + "dataTypesDependencies": [ + "CiscoETD_CL" + ], + "dataConnectorsDependencies": [ + "CiscoETD" + ], + "previewImagesFileNames": [ + "CiscoETDBlack01.PNG", + "CiscoETDBlack02.PNG", + "CiscoETDWhite01.PNG", + "CiscoETDWhite02.PNG" + ], + "version": "1.0", + "title": "Cisco Email Threat Defense", + "templateRelativePath": "CiscoETD.json", + "subtitle": "", + "provider": "Cisco" +}, { "workbookKey": "PaloAltoCDL", "logoFileName": "paloalto_logo.svg",