Merge branch 'master' into box_rules_and_queries

This commit is contained in:
Vitalii Uslystyi 2021-03-24 11:37:41 +02:00
Родитель 36c885747c 87ec71476a
Коммит 93ee4622f1
365 изменённых файлов: 59505 добавлений и 1388 удалений

Просмотреть файл

@ -1,45 +0,0 @@
{
"Name": "AppServiceAntivirusScanAuditLogs",
"Properties": [
{
"Name": "TimeGenerated",
"Type": "DateTime"
},
{
"Name": "TenantId",
"Type": "String"
},
{
"Name": "ScanStatus",
"Type": "String"
},
{
"Name": "TotalFilesScanned",
"Type": "Long"
},
{
"Name": "NumberOfInfectedFiles",
"Type": "Long"
},
{
"Name": "ListOfInfectedFiles",
"Type": "String"
},
{
"Name": "ErrorMessage",
"Type": "String"
},
{
"Name": "SourceSystem",
"Type": "String"
},
{
"Name": "Type",
"Type": "String"
},
{
"Name": "_ResourceId",
"Type": "String"
}
]
}

Просмотреть файл

@ -1,97 +0,0 @@
{
"Name": "AppServiceHTTPLogs",
"Properties": [
{
"Name": "TenantId",
"Type": "string"
},
{
"Name": "TimeGenerated",
"Type": "datetime"
},
{
"Name": "Category",
"Type": "string"
},
{
"Name": "CsMethod",
"Type": "string"
},
{
"Name": "CsUriStem",
"Type": "string"
},
{
"Name": "SPort",
"Type": "string"
},
{
"Name": "CIp",
"Type": "string"
},
{
"Name": "UserAgent",
"Type": "string"
},
{
"Name": "CsHost",
"Type": "string"
},
{
"Name": "ScStatus",
"Type": "long"
},
{
"Name": "ScSubStatus",
"Type": "string"
},
{
"Name": "ScWin32Status",
"Type": "string"
},
{
"Name": "ScBytes",
"Type": "long"
},
{
"Name": "CsBytes",
"Type": "long"
},
{
"Name": "TimeTaken",
"Type": "long"
},
{
"Name": "Result",
"Type": "string"
},
{
"Name": "Cookie",
"Type": "string"
},
{
"Name": "CsUriQuery",
"Type": "string"
},
{
"Name": "CsUsername",
"Type": "string"
},
{
"Name": "Referer",
"Type": "string"
},
{
"Name": "SourceSystem",
"Type": "string"
},
{
"Name": "Type",
"Type": "string"
},
{
"Name": "_ResourceId",
"Type": "string"
}
]
}

Просмотреть файл

@ -0,0 +1,417 @@
{
"Name": "Cloudflare_CL",
"Properties": [
{
"Name": "BotScore_d",
"Type": "Double"
},
{
"Name": "BotScoreSrc_s",
"Type": "String"
},
{
"Name": "CacheCacheStatus_s",
"Type": "String"
},
{
"Name": "CacheResponseBytes_d",
"Type": "Double"
},
{
"Name": "CacheResponseStatus_d",
"Type": "Double"
},
{
"Name": "CacheTieredFill_b",
"Type": "Bool"
},
{
"Name": "ClientASN_d",
"Type": "Double"
},
{
"Name": "ClientCountry_s",
"Type": "String"
},
{
"Name": "ClientDeviceType_s",
"Type": "String"
},
{
"Name": "ClientIP_s",
"Type": "String"
},
{
"Name": "ClientIPClass_s",
"Type": "String"
},
{
"Name": "ClientRequestBytes_d",
"Type": "Double"
},
{
"Name": "ClientRequestHost_s",
"Type": "String"
},
{
"Name": "ClientRequestMethod_s",
"Type": "String"
},
{
"Name": "ClientRequestPath_s",
"Type": "String"
},
{
"Name": "ClientRequestProtocol_s",
"Type": "String"
},
{
"Name": "ClientRequestReferer_s",
"Type": "String"
},
{
"Name": "ClientRequestURI_s",
"Type": "String"
},
{
"Name": "ClientRequestUserAgent_s",
"Type": "String"
},
{
"Name": "ClientSSLCipher_s",
"Type": "String"
},
{
"Name": "ClientSSLProtocol_s",
"Type": "String"
},
{
"Name": "ClientSrcPort_d",
"Type": "Double"
},
{
"Name": "ClientXRequestedWith_s",
"Type": "String"
},
{
"Name": "EdgeColoCode_s",
"Type": "String"
},
{
"Name": "EdgeColoID_d",
"Type": "Double"
},
{
"Name": "EdgeEndTimestamp_t",
"Type": "DateTime"
},
{
"Name": "EdgePathingOp_s",
"Type": "String"
},
{
"Name": "EdgePathingSrc_s",
"Type": "String"
},
{
"Name": "EdgePathingStatus_s",
"Type": "String"
},
{
"Name": "EdgeRateLimitAction_s",
"Type": "String"
},
{
"Name": "EdgeRateLimitID_d",
"Type": "Double"
},
{
"Name": "EdgeRequestHost_s",
"Type": "String"
},
{
"Name": "EdgeResponseBytes_d",
"Type": "Double"
},
{
"Name": "EdgeResponseCompressionRatio_d",
"Type": "Double"
},
{
"Name": "EdgeResponseContentType_s",
"Type": "String"
},
{
"Name": "EdgeResponseStatus_d",
"Type": "Double"
},
{
"Name": "EdgeServerIP_s",
"Type": "String"
},
{
"Name": "EdgeStartTimestamp_t",
"Type": "DateTime"
},
{
"Name": "FirewallMatchesActions_s",
"Type": "String"
},
{
"Name": "FirewallMatchesRuleIDs_s",
"Type": "String"
},
{
"Name": "FirewallMatchesSources_s",
"Type": "String"
},
{
"Name": "OriginIP_s",
"Type": "String"
},
{
"Name": "OriginResponseBytes_d",
"Type": "Double"
},
{
"Name": "OriginResponseHTTPExpires_s",
"Type": "String"
},
{
"Name": "OriginResponseHTTPLastModified_s",
"Type": "String"
},
{
"Name": "OriginResponseStatus_d",
"Type": "Double"
},
{
"Name": "OriginResponseTime_d",
"Type": "Double"
},
{
"Name": "OriginSSLProtocol_s",
"Type": "String"
},
{
"Name": "ParentRayID_s",
"Type": "String"
},
{
"Name": "RayID_s",
"Type": "String"
},
{
"Name": "SecurityLevel_s",
"Type": "String"
},
{
"Name": "WAFAction_s",
"Type": "String"
},
{
"Name": "WAFFlags_s",
"Type": "String"
},
{
"Name": "WAFMatchedVar_s",
"Type": "String"
},
{
"Name": "WAFProfile_s",
"Type": "String"
},
{
"Name": "WAFRuleID_s",
"Type": "String"
},
{
"Name": "WAFRuleMessage_s",
"Type": "String"
},
{
"Name": "WorkerCPUTime_d",
"Type": "Double"
},
{
"Name": "WorkerStatus_s",
"Type": "String"
},
{
"Name": "WorkerSubrequest_b",
"Type": "Bool"
},
{
"Name": "WorkerSubrequestCount_d",
"Type": "Double"
},
{
"Name": "ZoneID_d",
"Type": "Double"
},
{
"Name": "Application_s",
"Type": "String"
},
{
"Name": "ClientBytes_d",
"Type": "Double"
},
{
"Name": "ClientMatchedIpFirewall_s",
"Type": "String"
},
{
"Name": "ClientPort_d",
"Type": "Double"
},
{
"Name": "ClientProto_s",
"Type": "String"
},
{
"Name": "ClientTcpRtt_d",
"Type": "Double"
},
{
"Name": "ClientTlsCipher_s",
"Type": "String"
},
{
"Name": "ClientTlsClientHelloServerName_s",
"Type": "String"
},
{
"Name": "ClientTlsProtocol_s",
"Type": "String"
},
{
"Name": "ClientTlsStatus_s",
"Type": "String"
},
{
"Name": "ColoCode_s",
"Type": "String"
},
{
"Name": "ConnectTimestamp_t",
"Type": "DateTime"
},
{
"Name": "DisconnectTimestamp_t",
"Type": "DateTime"
},
{
"Name": "Event_s",
"Type": "String"
},
{
"Name": "IpFirewall_b",
"Type": "Bool"
},
{
"Name": "OriginBytes_d",
"Type": "Double"
},
{
"Name": "OriginPort_d",
"Type": "Double"
},
{
"Name": "OriginProto_s",
"Type": "String"
},
{
"Name": "OriginTcpRtt_d",
"Type": "Double"
},
{
"Name": "OriginTlsCipher_s",
"Type": "String"
},
{
"Name": "OriginTlsFingerprint_s",
"Type": "String"
},
{
"Name": "OriginTlsMode_s",
"Type": "String"
},
{
"Name": "OriginTlsProtocol_s",
"Type": "String"
},
{
"Name": "OriginTlsStatus_s",
"Type": "String"
},
{
"Name": "ProxyProtocol_s",
"Type": "String"
},
{
"Name": "Status_d",
"Type": "Double"
},
{
"Name": "Timestamp_t",
"Type": "DateTime"
},
{
"Name": "Action_s",
"Type": "String"
},
{
"Name": "ClientASNDescription_s",
"Type": "String"
},
{
"Name": "ClientRefererHost_s",
"Type": "String"
},
{
"Name": "ClientRefererPath_s",
"Type": "String"
},
{
"Name": "ClientRefererQuery_s",
"Type": "String"
},
{
"Name": "ClientRefererScheme_s",
"Type": "String"
},
{
"Name": "ClientRequestQuery_s",
"Type": "String"
},
{
"Name": "ClientRequestScheme_s",
"Type": "String"
},
{
"Name": "Datetime_t",
"Type": "DateTime"
},
{
"Name": "Kind_s",
"Type": "String"
},
{
"Name": "MatchIndex_d",
"Type": "Double"
},
{
"Name": "OriginatorRayID_s",
"Type": "String"
},
{
"Name": "RuleID_s",
"Type": "String"
},
{
"Name": "Source_s",
"Type": "String"
}
]
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,189 @@
{
"Name": "ExabeamEvent",
"Properties": [
{
"Name": "EventVendor",
"Type": "String"
},
{
"Name": "Service",
"Type": "String"
},
{
"Name": "Status",
"Type": "String"
},
{
"Name": "Id",
"Type": "String"
},
{
"Name": "UrlOriginal",
"Type": "String"
},
{
"Name": "EntityValue",
"Type": "String"
},
{
"Name": "Score",
"Type": "String"
},
{
"Name": "SequenceType",
"Type": "String"
},
{
"Name": "EventStartTime",
"Type": "DateTime"
},
{
"Name": "EventEndTime",
"Type": "DateTime"
},
{
"Name": "SrcUserName",
"Type": "String"
},
{
"Name": "SrcDvcHostname",
"Type": "String"
},
{
"Name": "SrcIpAddr",
"Type": "String"
},
{
"Name": "Labels",
"Type": "String"
},
{
"Name": "Accounts",
"Type": "String"
},
{
"Name": "AssetsCount",
"Type": "String"
},
{
"Name": "Assets",
"Type": "String"
},
{
"Name": "Zones",
"Type": "String"
},
{
"Name": "TopReasons",
"Type": "String"
},
{
"Name": "ReasonsCount",
"Type": "String"
},
{
"Name": "EventsCount",
"Type": "String"
},
{
"Name": "AlertsCount",
"Type": "String"
},
{
"Name": "AssetLabels",
"Type": "String"
},
{
"Name": "AssetLocations",
"Type": "String"
},
{
"Name": "TopUsers",
"Type": "String"
},
{
"Name": "AssetHostname",
"Type": "String"
},
{
"Name": "AssetIpAddress",
"Type": "String"
},
{
"Name": "DstDvcHostname",
"Type": "String"
},
{
"Name": "DstIpAddr",
"Type": "String"
},
{
"Name": "EventTime",
"Type": "DateTime"
},
{
"Name": "EventType",
"Type": "String"
},
{
"Name": "DvcHostname",
"Type": "String"
},
{
"Name": "Domain",
"Type": "String"
},
{
"Name": "Raw",
"Type": "String"
},
{
"Name": "RuleId",
"Type": "String"
},
{
"Name": "RuleName",
"Type": "String"
},
{
"Name": "RuleDescription",
"Type": "String"
},
{
"Name": "App",
"Type": "String"
},
{
"Name": "EventSubType",
"Type": "String"
},
{
"Name": "Activity",
"Type": "String"
},
{
"Name": "AdditionalInfo",
"Type": "String"
},
{
"Name": "JobStatus",
"Type": "String"
},
{
"Name": "JobDetails",
"Type": "String"
},
{
"Name": "JobId",
"Type": "String"
},
{
"Name": "CreatedBy",
"Type": "String"
},
{
"Name": "Timestamp",
"Type": "DateTime"
}
]
}

Просмотреть файл

@ -20,6 +20,10 @@
{
"Name": "Client_IP",
"Type": "String"
},
{
"Name": "ServerIP",
"Type": "String"
}
]
}
}

Просмотреть файл

@ -0,0 +1,313 @@
{
"Name": "McAfeeEPOEvent",
"Properties": [
{
"Name": "TimeGenerated",
"Type": "DateTime"
},
{
"Name": "GmtTime",
"Type": "DateTime"
},
{
"Name": "EventVendor",
"Type": "String"
},
{
"Name": "EventProduct",
"Type": "String"
},
{
"Name": "EventId",
"Type": "String"
},
{
"Name": "EventSeverity",
"Type": "String"
},
{
"Name": "AgentGuid",
"Type": "String"
},
{
"Name": "DvcHostname",
"Type": "String"
},
{
"Name": "DvcIpAddr",
"Type": "String"
},
{
"Name": "DvcMacAddr",
"Type": "String"
},
{
"Name": "AgentVersion",
"Type": "String"
},
{
"Name": "SrcDvcOs",
"Type": "String"
},
{
"Name": "SrcUserName",
"Type": "String"
},
{
"Name": "TimeZoneBias",
"Type": "String"
},
{
"Name": "ProductName",
"Type": "String"
},
{
"Name": "ProductFamily",
"Type": "String"
},
{
"Name": "ProductVersion",
"Type": "String"
},
{
"Name": "Analyzer",
"Type": "String"
},
{
"Name": "AnalyzerName",
"Type": "String"
},
{
"Name": "AnalyzerVersion",
"Type": "String"
},
{
"Name": "AnalyzerHostName",
"Type": "String"
},
{
"Name": "AnalyzerDatVersion",
"Type": "String"
},
{
"Name": "AnalyzerEngineVersion",
"Type": "String"
},
{
"Name": "AnalyzerDetectionMethod",
"Type": "String"
},
{
"Name": "ThreatName",
"Type": "String"
},
{
"Name": "ThreatType",
"Type": "String"
},
{
"Name": "ThreatCategory",
"Type": "String"
},
{
"Name": "ThreatId",
"Type": "String"
},
{
"Name": "ThreatHandled",
"Type": "String"
},
{
"Name": "ThreatActionTaken",
"Type": "String"
},
{
"Name": "ThreatSeverity",
"Type": "String"
},
{
"Name": "SrcUserUpn",
"Type": "String"
},
{
"Name": "SrcProcessName",
"Type": "String"
},
{
"Name": "DstDvcHostname",
"Type": "String"
},
{
"Name": "DstUserName",
"Type": "String"
},
{
"Name": "TargetProcessName",
"Type": "String"
},
{
"Name": "DstFileName",
"Type": "String"
},
{
"Name": "Target",
"Type": "String"
},
{
"Name": "BladeName",
"Type": "String"
},
{
"Name": "AnalyzerContentVersion",
"Type": "String"
},
{
"Name": "AnalyzerContentCreationDate",
"Type": "String"
},
{
"Name": "AnalyzerRuleName",
"Type": "String"
},
{
"Name": "AnalyzerRuleId",
"Type": "String"
},
{
"Name": "AnalyzerGtiQuery",
"Type": "String"
},
{
"Name": "ThreatDetectedOnCreation",
"Type": "String"
},
{
"Name": "DstFileSize",
"Type": "String"
},
{
"Name": "DstFileModifiedTime",
"Type": "DateTime"
},
{
"Name": "DstFileAccessedTime",
"Type": "DateTime"
},
{
"Name": "DstFileCreationTime",
"Type": "DateTime"
},
{
"Name": "Cleanable",
"Type": "String"
},
{
"Name": "TaskName",
"Type": "String"
},
{
"Name": "FirstAttemptedAction",
"Type": "String"
},
{
"Name": "FirstActionStatus",
"Type": "String"
},
{
"Name": "SecondAttemptedAction",
"Type": "String"
},
{
"Name": "SecondActionStatus",
"Type": "String"
},
{
"Name": "ApiName",
"Type": "String"
},
{
"Name": "SourceDescription",
"Type": "String"
},
{
"Name": "SrcProcessId",
"Type": "String"
},
{
"Name": "SrcProcessHashMd5",
"Type": "String"
},
{
"Name": "AttackVectorType",
"Type": "String"
},
{
"Name": "DurationBeforeDetection",
"Type": "String"
},
{
"Name": "AccessRequested",
"Type": "String"
},
{
"Name": "DetectionMessage",
"Type": "String"
},
{
"Name": "AmCoreContentVersion",
"Type": "String"
},
{
"Name": "SrcIpAddr",
"Type": "String"
},
{
"Name": "SrcMacAddr",
"Type": "String"
},
{
"Name": "DstIpAddr",
"Type": "String"
},
{
"Name": "DstMacAddr",
"Type": "String"
},
{
"Name": "ProductId",
"Type": "String"
},
{
"Name": "Locale",
"Type": "String"
},
{
"Name": "Error",
"Type": "String"
},
{
"Name": "Type",
"Type": "String"
},
{
"Name": "Version",
"Type": "String"
},
{
"Name": "InitiatorId",
"Type": "String"
},
{
"Name": "InitiatorType",
"Type": "String"
},
{
"Name": "SiteName",
"Type": "String"
},
{
"Name": "Description",
"Type": "String"
}
]
}

Просмотреть файл

@ -0,0 +1,97 @@
{
"Name": "OracleDatabaseAuditEvent",
"Properties": [
{
"Name": "TimeGenerated",
"Type": "DateTime"
},
{
"Name": "EventVendor",
"Type": "String"
},
{
"Name": "SeverityLevel",
"Type": "String"
},
{
"Name": "MessageLength",
"Type": "String"
},
{
"Name": "Action",
"Type": "String"
},
{
"Name": "ActionLength",
"Type": "String"
},
{
"Name": "DbAction",
"Type": "String"
},
{
"Name": "DstUserName",
"Type": "String"
},
{
"Name": "Privilege",
"Type": "String"
},
{
"Name": "SrcUserName",
"Type": "String"
},
{
"Name": "ClientTerminal",
"Type": "String"
},
{
"Name": "Status",
"Type": "String"
},
{
"Name": "DbId",
"Type": "String"
},
{
"Name": "SessionId",
"Type": "String"
},
{
"Name": "EntryId",
"Type": "String"
},
{
"Name": "Statement",
"Type": "String"
},
{
"Name": "SrcDvcHostname",
"Type": "String"
},
{
"Name": "SrcIpAddr",
"Type": "String"
},
{
"Name": "SrcPortNumber",
"Type": "String"
},
{
"Name": "ReturnCode",
"Type": "String"
},
{
"Name": "ObjCreator",
"Type": "String"
},
{
"Name": "ObjName",
"Type": "String"
},
{
"Name": "OsUserId",
"Type": "String"
}
]
}

Просмотреть файл

@ -16,6 +16,10 @@
{
"Name": "Computer",
"Type": "String"
},
{
"Name": "Source_IP",
"Type": "String"
}
]
}
}

Просмотреть файл

@ -0,0 +1,285 @@
{
"Name":"SlackAudit",
"Properties": [
{
"Name": "TimeGenerated",
"Type": "Datetime"
},
{
"Name": "Action",
"Type": "String"
},
{
"Name": "EventVendor",
"Type": "String"
},
{
"Name": "EventProduct",
"Type": "String"
},
{
"Name": "DetailsMobileOnly",
"Type": "Bool"
},
{
"Name": "DetailsWebOnly",
"Type": "Bool"
},
{
"Name": "DetailsKickerId",
"Type": "String"
},
{
"Name": "DetailsKickerName",
"Type": "String"
},
{
"Name": "DetailsKickerEmail",
"Type": "String"
},
{
"Name": "DetailsKickerTeam",
"Type": "String"
},
{
"Name": "DetailsAppOwnerId",
"Type": "String"
},
{
"Name": "DetailsGranularBotToken",
"Type": "Bool"
},
{
"Name": "DetailsNewScopes",
"Type": "String"
},
{
"Name": "DetailsPreviousScopes",
"Type": "String"
},
{
"Name": "EntityUsergroupId",
"Type": "String"
},
{
"Name": "EntityUsergroupName",
"Type": "String"
},
{
"Name": "DetailsKickerType",
"Type": "String"
},
{
"Name": "DetailsKickerUserId",
"Type": "String"
},
{
"Name": "DetailsKickerUserName",
"Type": "String"
},
{
"Name": "DetailsKickerUserEmail",
"Type": "String"
},
{
"Name": "DetailsKickerUserTeam",
"Type": "String"
},
{
"Name": "DetailsInviterId",
"Type": "String"
},
{
"Name": "DetailsInviterName",
"Type": "String"
},
{
"Name": "DetailsInviterEmail",
"Type": "String"
},
{
"Name": "DetailsInviterTeam",
"Type": "String"
},
{
"Name": "DetailsInviterType",
"Type": "String"
},
{
"Name": "DetailsInviterUserId",
"Type": "String"
},
{
"Name": "DetailsInviterUserName",
"Type": "String"
},
{
"Name": "DetailsInviterUserEmail",
"Type": "String"
},
{
"Name": "DetailsInviterUserTeam",
"Type": "String"
},
{
"Name": "DetailsIsWorkflow",
"Type": "Bool"
},
{
"Name": "EntityAppId",
"Type": "String"
},
{
"Name": "EntityAppName",
"Type": "String"
},
{
"Name": "EntityAppIsDistributed",
"Type": "Bool"
},
{
"Name": "EntityAppIsDirectoryApproved",
"Type": "Bool"
},
{
"Name": "EntityAppIsWorkflowApp",
"Type": "Bool"
},
{
"Name": "EntityAppScopes",
"Type": "String"
},
{
"Name": "DetailsIsInternalIntegration",
"Type": "Bool"
},
{
"Name": "DetailsBotScopes",
"Type": "String"
},
{
"Name": "EntityChannelId",
"Type": "String"
},
{
"Name": "EntityChannelPrivacy",
"Type": "String"
},
{
"Name": "EntityChannelName",
"Type": "String"
},
{
"Name": "EntityChannelIsShared",
"Type": "Bool"
},
{
"Name": "EntityChannelIsOrgShared",
"Type": "Bool"
},
{
"Name": "DetailsType",
"Type": "String"
},
{
"Name": "EntityUserId",
"Type": "String"
},
{
"Name": "EntityUserName",
"Type": "String"
},
{
"Name": "EntityUserEmail",
"Type": "String"
},
{
"Name": "EntityUserTeam",
"Type": "String"
},
{
"Name": "EventId",
"Type": "String"
},
{
"Name": "EventEndTime",
"Type": "Double"
},
{
"Name": "DvcAction",
"Type": "String"
},
{
"Name": "ActorType",
"Type": "String"
},
{
"Name": "SrcUserIdentity",
"Type": "String"
},
{
"Name": "SrcUserName",
"Type": "String"
},
{
"Name": "SrcUserEmail",
"Type": "String"
},
{
"Name": "ActorUserTeam",
"Type": "String"
},
{
"Name": "EntityType",
"Type": "String"
},
{
"Name": "EntityFileId",
"Type": "String"
},
{
"Name": "EntityFileName",
"Type": "String"
},
{
"Name": "EntityFileFiletype",
"Type": "String"
},
{
"Name": "EntityFileTitle",
"Type": "String"
},
{
"Name": "context_location_type_s",
"Type": "String"
},
{
"Name": "ContextLocationId",
"Type": "String"
},
{
"Name": "ContextLocationName",
"Type": "String"
},
{
"Name": "ContextLocationDomain",
"Type": "String"
},
{
"Name": "UserAgentOriginal",
"Type": "String"
},
{
"Name": "SrcIpAddr",
"Type": "String"
},
{
"Name": "ContextSessionId",
"Type": "Double"
},
{
"Name": "DvcActionDesc",
"Type": "String"
}
]
}

Просмотреть файл

@ -39,8 +39,6 @@ namespace Kqlvalidations.Tests
return;
}
var lines = Regex.Split(queryStr, @"\n\r?");
var validationRes = _queryValidator.ValidateSyntax(queryStr);
var firstErrorLocation = (Line: 0, Col: 0);
if (!validationRes.IsValid)
@ -49,6 +47,36 @@ namespace Kqlvalidations.Tests
}
Assert.True(validationRes.IsValid, validationRes.IsValid ? string.Empty : $"Template Id:{id} is not valid in Line:{firstErrorLocation.Line} col:{firstErrorLocation.Col} Errors:{validationRes.Diagnostics.Select(d => d.ToString()).ToList().Aggregate((s1, s2) => s1 + "," + s2)}");
}
[Theory]
[ClassData(typeof(DetectionsYamlFilesTestData))]
public void Validate_DetectionQueries_SkippedTemplatesDoNotHaveValidKql(string detectionsYamlFileName)
{
var detectionsYamlFile = Directory.GetFiles(DetectionPath, detectionsYamlFileName, SearchOption.AllDirectories).Single();
var yaml = File.ReadAllText(detectionsYamlFile);
var deserializer = new DeserializerBuilder().Build();
var res = deserializer.Deserialize<dynamic>(yaml);
string queryStr = res["query"];
string id = res["id"];
//Templates that are in the skipped templates should not pass the validateion (if they pass, why skip?)
if (TemplatesToSkipValidationReader.WhiteListTemplateIds.Contains(id))
{
var validationRes = _queryValidator.ValidateSyntax(queryStr);
var firstErrorLocation = (Line: 0, Col: 0);
if (!validationRes.IsValid)
{
firstErrorLocation = GetLocationInQuery(queryStr, validationRes.Diagnostics.First(d => d.Severity == "Error").Start);
}
Assert.False(validationRes.IsValid, $"Template Id:{id} is valid but it is in the skipped validation templates. Please remove it from the templates that are skipped since it is valid.");
}
else
{
return;
}
}
private (int Line, int Col) GetLocationInQuery(string queryStr, int pos)
{

Просмотреть файл

@ -12,7 +12,7 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="YamlDotNet" Version="6.0.0" />
<PackageReference Include="Microsoft.Azure.Sentinel.KustoServices" Version="1.0.11" />
<PackageReference Include="Microsoft.Azure.Sentinel.KustoServices" Version="1.0.12" />
</ItemGroup>
</Project>

Двоичный файл не отображается.

Просмотреть файл

@ -1,20 +1,11 @@
[
"34663177-8abf-4db1-b0a4-5683ab273f44",
"24f8c234-d1ff-40ec-8b73-96b17a3a9c1c",
"7249500f-3038-4b83-8549-9cd8dfa2d498",
"06a9b845-6a95-4432-a78b-83919b28c375",
"04384937-e927-4595-8f3c-89ff58ed231f",
"0914adab-90b5-47a3-a79f-7cdcac843aa7",
"155f40c6-610d-497d-85fc-3cf06ec13256",
"f7f4a77e-f68f-4b56-9aaf-a0c9d87d7a8e",
"d6491be0-ab2d-439d-95d6-ad8ea39277c5",
"57e56fc9-417a-4f41-a579-5475aea7b8ce",
"a9956d3a-07a9-44a6-a279-081a85020cae",
"aac495a9-feb1-446d-b08e-a1164a539452",
"f2dd4a3a-ebac-4994-9499-1a859938c947",
"97ad74c4-fdd9-4a3f-b6bf-5e28f4f71e06",
"f041e01d-840d-43da-95c8-4188f6cef546",
"a4025a76-6490-4e6b-bb69-d02be4b03f07",
"e70fa6e0-796a-4e85-9420-98b17b0bb749",
"6d7214d9-4a28-44df-aafb-0910b9e6ae3e"
]
"e70fa6e0-796a-4e85-9420-98b17b0bb749"
]

Двоичный файл не отображается.

Просмотреть файл

@ -67,6 +67,33 @@ namespace Kqlvalidations.Tests
var isValid = connectorIds.Count() == 0;
Assert.True(isValid, isValid ? string.Empty : $"Template Id:'{id}' doesn't have valid connectorIds:'{string.Join(",", connectorIds)}'. If a new connector is used and already configured in the Portal, please add it's Id to the list in 'ValidConnectorIds.json' file.");
}
[Fact]
public void Validate_DetectionTemplates_AllFilesAreYamls()
{
string detectionPath = DetectionsYamlFilesTestData.GetDetectionPath();
var yamlFiles = Directory.GetFiles(detectionPath, "*.yaml", SearchOption.AllDirectories).ToList();
var AllFiles = Directory.GetFiles(detectionPath,"*", SearchOption.AllDirectories).ToList();
var numberOfNotYamlFiles = 1; //This is the readme.md file in the directory
Assert.True(AllFiles.Count == yamlFiles.Count + numberOfNotYamlFiles, "All the files in detections folder are supposed to end with .yaml");
}
[Fact]
public void Validate_DetectionTemplates_NoSameTemplateIdTwice()
{
string detectionPath = DetectionsYamlFilesTestData.GetDetectionPath();
var yamlFiles = Directory.GetFiles(detectionPath, "*.yaml", SearchOption.AllDirectories);
var templatesAsStrings = yamlFiles.Select(yaml => GetYamlFileAsString(Path.GetFileName(yaml)));
var templatesAsObjects = templatesAsStrings.Select(yaml => JObject.Parse(ConvertYamlToJson(yaml)));
var duplicationsById = templatesAsObjects.GroupBy(a => a["id"]).Where(group => group.Count() > 1); //Finds duplications -> ids that there are more than 1 template from
var duplicatedId = "";
if (duplicationsById.Count() > 0){
duplicatedId = duplicationsById.Last().Select(x => x["id"]).First().ToString();
}
Assert.True(duplicationsById.Count() == 0, $"There should not be 2 templates with the same ID, but the id {duplicatedId} is duplicated.");
}
private string GetYamlFileAsString(string detectionsYamlFileName)
{

Просмотреть файл

@ -2,8 +2,6 @@
{
public enum AttackTactic
{
Reconnaissance,
ResourceDevelopment,
InitialAccess,
Execution,
Persistence,
@ -15,6 +13,7 @@
Collection,
Exfiltration,
CommandAndControl,
Impact
Impact,
PreAttack
}
}

Просмотреть файл

@ -58,6 +58,7 @@
"InfobloxNIOS",
"IoT",
"JuniperSRX",
"McAfeeePO",
"MicrosoftCloudAppSecurity",
"MicrosoftDefenderAdvancedThreatProtection",
"MicrosoftThreatIntelligence",
@ -80,6 +81,7 @@
"QualysVulnerabilityManagement",
"SalesforceServiceCloud",
"SecurityEvents",
"SlackAuditAPI",
"SonicWallFirewall",
"SophosCloudOptix",
"SophosXGFirewall",

Просмотреть файл

@ -3,7 +3,7 @@
# the last matching pattern has the most precendence.
# Core team members
* @liemilyg @mgladi @orco365 @shalinoid @KobyKoren @shainw @ianhelle @timbMSFT @juliango2100 @dicolanl @Amitbergman @sagamzu @YaronFruchtmann @preetikr @Yaniv-Shasha @sarah-yo @nazang @ehudk-msft @oshvartz @Liatlishams @NoamLandress @laithhisham @petebryan
* @liemilyg @mgladi @orco365 @shalinoid @KobyKoren @shainw @ianhelle @timbMSFT @juliango2100 @dicolanl @Amitbergman @sagamzu @YaronFruchtmann @preetikr @Yaniv-Shasha @sarah-yo @nazang @ehudk-msft @oshvartz @Liatlishams @NoamLandress @laithhisham @petebryan @lior-tamir
# This is copied from here: https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "DarktraceDarktrace",
"id": "Darktrace",
"title": "AI Analyst Darktrace",
"publisher": "Darktrace",
"descriptionMarkdown": "The Darktrace connector lets users connect Darktrace Model Breaches in real-time with Azure Sentinel, allowing creation of custom Dashboards, Workbooks, Notebooks and Custom Alerts to improve investigation. Azure Sentinel's enhanced visibility into Darktrace logs enables monitoring and mitigation of security threats.",
@ -111,4 +111,4 @@
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
}
}

Просмотреть файл

@ -122,5 +122,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "2de7b355-5f0b-4eb1-a264-629314ef86e5",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Vectra AI"
},
"support": {
"name": "Vectra AI",
"link": "https://www.vectra.ai/support",
"tier": "developer"
}
}
}

Просмотреть файл

@ -168,5 +168,21 @@
"title": "",
"description": "**5. Complete Setup.**\n\n1. Once all application settings have been entered, click **Save**. Note that it will take some time to have the required dependencies download, so you may see some inital failure messages."
}
]
],
"metadata" : {
"id": "152fa8d4-b84b-4370-8317-b63ed52f9fe3",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Agari"
},
"support": {
"name": "Agari",
"link": "https://support.agari.com/hc/en-us/articles/360000645632-How-to-access-Agari-Support",
"tier": "developer"
}
}
}

Просмотреть файл

@ -1,156 +1,172 @@
{
"id": "AlsidForAD",
"title": "Alsid for Active Directory",
"publisher": "Alsid",
"descriptionMarkdown": "Alsid for Active Directory connector allows to export Alsid Indicators of Exposures, trailflow and Indicators of Attacks logs to Azure Sentinel in real time.\nIt provides a data parser to manipulate the logs more easily. The different workbooks ease your Active Directory monitoring and provide different ways to visualize the data. The analytic templates allow to automate responses regarding different events, exposures, or attacks.",
"additionalRequirementBanner": "This data connector depends on a parser based on Kusto Function to work as expected. Follow the steps to use this Kusto Function alias **afad_parser** in queries and workbooks. [Follow steps to get this Kusto Function>](https://github.com/Azure/Azure-Sentinel/blob/master/Parsers/Alsid/afad_parser.kql) ",
"graphQueries": [
{
"metricName": "Total data received",
"legend": "AlsidForADLog_CL",
"baseQuery": "AlsidForADLog_CL"
}
],
"sampleQueries": [
{
"description" : "Get the number of alerts triggered by each IoE",
"query": "afad_parser\n | where MessageType == 0\n | summarize AlertCount = count() by Codename"
},
{
"description" : "Get all IoE alerts with severity superior to the threshold",
"query" : "let threshold = 2;\n let SeverityTable=datatable(Severity:string,Level:int) [\n \"low\", 1,\n \"medium\", 2,\n \"high\", 3,\n \"critical\", 4\n ];\n afad_parser\n | where MessageType == 0\n | lookup kind=leftouter SeverityTable on Severity\n | where Level >= ['threshold']"
},
{
"description" : "Get all IoE alerts for the last 24 hours",
"query" : "afad_parser\r\n| where MessageType == 0 and TimeGenerated > ago(1d)"
},
{
"description" : "Get all IoE alerts for the last 7 days",
"query" : "afad_parser\r\n| where MessageType == 0 and TimeGenerated > ago(7d)"
},
{
"description" : "Get all IoE alerts for the last 30 days",
"query" : "afad_parser\r\n| where MessageType == 0 and TimeGenerated > ago(30d)"
},
{
"description" : "Get all trailflow changes for the last 24 hours",
"query" : "afad_parser\r\n| where MessageType == 1 and TimeGenerated > ago(1d)"
},
{
"description" : "Get all trailflow changes for the last 7 days",
"query" : "afad_parser\r\n| where MessageType == 1 and TimeGenerated > ago(7d)"
}
],
"dataTypes": [
{
"name": "AlsidForADLog_CL",
"lastDataReceivedQuery": "AlsidForADLog_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
}
],
"connectivityCriterias": [
{
"type": "IsConnectedQuery",
"value": [
"AlsidForADLog_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 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
}
}
]
},
"instructionSteps": [
{
"title": "",
"description": ">This data connector depends on a parser based on a Kusto Function to work as expected. [Follow these steps](https://github.com/Azure/Azure-Sentinel/blob/master/Parsers/Alsid/afad_parser.kql) to create the Kusto Functions alias, **afad_parser**",
"instructions": [
]
},
{
"title": "1. Configure the Syslog server",
"description": "You will first need a **linux Syslog** server that Alsid for AD will send logs to. Typically you can run **rsyslog** on **Ubuntu**.\n You can then configure this server as you wish but it is recommended to be able to output AFAD logs in a separate file."
},
{
"title": "2. Configure Alsid to send logs to your Syslog server",
"description": "On your **Alsid for AD** portal, go to *System*, *Configuration* and then *Syslog*.\nFrom there you can create a new Syslog alert toward your Syslog server.\n\nOnce this is done, check that the logs are correctly gathered on your server in a separate file (to do this, you can use the *Test the configuration* button in the Syslog alert configuration in AFAD)."
},
{
"title": "3. Install and onboard the Microsoft agent for Linux",
"description": "",
"instructions": [
{
"parameters": {
"title": "Choose where to install the agent:",
"instructionSteps": [
{
"title": "Install agent on Azure Linux Virtual Machine",
"description": "Select the machine to install the agent on and then click **Connect**.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnLinuxVirtualMachine"
},
"type": "InstallAgent"
}
]
},
{
"title": "Install agent on a non-Azure Linux Machine",
"description": "Download the agent on the relevant machine and follow the instructions.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnLinuxNonAzure"
},
"type": "InstallAgent"
}
]
}
]
},
"type": "InstructionStepsGroup"
}
]
},
{
"title": "4. Configure the logs to be collected by the agents",
"description": "Configure the agent to collect the logs.\n\n1. Under workspace advanced settings **Configuration**, select **Data** and then **Custom Logs**.\n2. Select **Apply below configuration to my machines** and click **Add**.\n4. Upload a sample AFAD Syslog file from the **Linux** machine running the **Syslog** server and click **Next**.\n5. Set the record delimiter to **New Line** if not already the case and click **Next**.\n6. Select **Linux** and enter the file path to the **Syslog** file, click **+** then **Next**.\n7. In the Name field type *AlsidForADLog* before the _CL suffix, then click **Done**.\n\nAll of theses steps are showcased [here](https://www.youtube.com/watch?v=JwV1uZSyXM4&feature=youtu.be) as an example",
"instructions": [
{
"parameters": {
"linkType": "OpenAdvancedWorkspaceSettings"
},
"type": "InstallAgent"
}
]
},
{
"title": "",
"description": "> You should now be able to receive logs in the *AlsidForADLog_CL* table, logs data can be parse using the **afad_parser()** function, used by all query samples, workbooks and analytic templates."
}
]
}
{
"id": "AlsidForAD",
"title": "Alsid for Active Directory",
"publisher": "Alsid",
"descriptionMarkdown": "Alsid for Active Directory connector allows to export Alsid Indicators of Exposures, trailflow and Indicators of Attacks logs to Azure Sentinel in real time.\nIt provides a data parser to manipulate the logs more easily. The different workbooks ease your Active Directory monitoring and provide different ways to visualize the data. The analytic templates allow to automate responses regarding different events, exposures, or attacks.",
"additionalRequirementBanner": "This data connector depends on a parser based on Kusto Function to work as expected. Follow the steps to use this Kusto Function alias **afad_parser** in queries and workbooks. [Follow steps to get this Kusto Function>](https://github.com/Azure/Azure-Sentinel/blob/master/Parsers/Alsid/afad_parser.kql) ",
"graphQueries": [
{
"metricName": "Total data received",
"legend": "AlsidForADLog_CL",
"baseQuery": "AlsidForADLog_CL"
}
],
"sampleQueries": [
{
"description" : "Get the number of alerts triggered by each IoE",
"query": "afad_parser\n | where MessageType == 0\n | summarize AlertCount = count() by Codename"
},
{
"description" : "Get all IoE alerts with severity superior to the threshold",
"query" : "let threshold = 2;\n let SeverityTable=datatable(Severity:string,Level:int) [\n \"low\", 1,\n \"medium\", 2,\n \"high\", 3,\n \"critical\", 4\n ];\n afad_parser\n | where MessageType == 0\n | lookup kind=leftouter SeverityTable on Severity\n | where Level >= ['threshold']"
},
{
"description" : "Get all IoE alerts for the last 24 hours",
"query" : "afad_parser\r\n| where MessageType == 0 and TimeGenerated > ago(1d)"
},
{
"description" : "Get all IoE alerts for the last 7 days",
"query" : "afad_parser\r\n| where MessageType == 0 and TimeGenerated > ago(7d)"
},
{
"description" : "Get all IoE alerts for the last 30 days",
"query" : "afad_parser\r\n| where MessageType == 0 and TimeGenerated > ago(30d)"
},
{
"description" : "Get all trailflow changes for the last 24 hours",
"query" : "afad_parser\r\n| where MessageType == 1 and TimeGenerated > ago(1d)"
},
{
"description" : "Get all trailflow changes for the last 7 days",
"query" : "afad_parser\r\n| where MessageType == 1 and TimeGenerated > ago(7d)"
}
],
"dataTypes": [
{
"name": "AlsidForADLog_CL",
"lastDataReceivedQuery": "AlsidForADLog_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
}
],
"connectivityCriterias": [
{
"type": "IsConnectedQuery",
"value": [
"afad_parser\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 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
}
}
]
},
"instructionSteps": [
{
"title": "",
"description": ">This data connector depends on a parser based on a Kusto Function to work as expected. [Follow these steps](https://github.com/Azure/Azure-Sentinel/blob/master/Parsers/Alsid/afad_parser.kql) to create the Kusto Functions alias, **afad_parser**",
"instructions": [
]
},
{
"title": "1. Configure the Syslog server",
"description": "You will first need a **linux Syslog** server that Alsid for AD will send logs to. Typically you can run **rsyslog** on **Ubuntu**.\n You can then configure this server as you wish, but it is recommended to be able to output AFAD logs in a separate file.\nAlternatively you can use [this Quickstart template](https://azure.microsoft.com/resources/templates/alsid-syslog-proxy/) which will deploy the Syslog server and the Microsoft agent for you. If you do use this template, you can skip step 3."
},
{
"title": "2. Configure Alsid to send logs to your Syslog server",
"description": "On your **Alsid for AD** portal, go to *System*, *Configuration* and then *Syslog*.\nFrom there you can create a new Syslog alert toward your Syslog server.\n\nOnce this is done, check that the logs are correctly gathered on your server in a seperate file (to do this, you can use the *Test the configuration* button in the Syslog alert configuration in AFAD).\nIf you used the Quickstart template, the Syslog server will by default listen on port 514 in UDP and 1514 in TCP, without TLS."
},
{
"title": "3. Install and onboard the Microsoft agent for Linux",
"description": "You can skip this step if you used the Quickstart template in step 1",
"instructions": [
{
"parameters": {
"title": "Choose where to install the agent:",
"instructionSteps": [
{
"title": "Install agent on Azure Linux Virtual Machine",
"description": "Select the machine to install the agent on and then click **Connect**.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnLinuxVirtualMachine"
},
"type": "InstallAgent"
}
]
},
{
"title": "Install agent on a non-Azure Linux Machine",
"description": "Download the agent on the relevant machine and follow the instructions.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnLinuxNonAzure"
},
"type": "InstallAgent"
}
]
}
]
},
"type": "InstructionStepsGroup"
}
]
},
{
"title": "4. Configure the logs to be collected by the agents",
"description": "Configure the agent to collect the logs.\n\n1. Under workspace advanced settings **Configuration**, select **Data** and then **Custom Logs**.\n2. Select **Apply below configuration to my machines** and click **Add**.\n3. Upload a sample AFAD Syslog file from the **Linux** machine running the **Syslog** server and click **Next**, for your convenience, you can find such a file [here](https://github.com/Azure/azure-quickstart-templates/blob/master/alsid-syslog-proxy/logs/AlsidForAD.log).\n4. Set the record delimiter to **New Line** if not already the case and click **Next**.\n5. Select **Linux** and enter the file path to the **Syslog** file, click **+** then **Next**. If you used the Quickstart template in step 1, the default location of the file is `/var/log/AlsidForAD.log`.\n6. Set the **Name** to *AlsidForADLog_CL* then click **Done** (Azure automatically adds *_CL* at the end of the name, there must be only one, make sure the name is not *AlsidForADLog_CL_CL*).\n\nAll of these steps are showcased [here](https://www.youtube.com/watch?v=JwV1uZSyXM4&feature=youtu.be) as an example",
"instructions": [
{
"parameters": {
"linkType": "OpenAdvancedWorkspaceSettings"
},
"type": "InstallAgent"
}
]
},
{
"title": "",
"description": "> You should now be able to receive logs in the *AlsidForADLog_CL* table, logs data can be parse using the **afad_parser()** function, used by all query samples, workbooks and analytic templates."
}
],
"metadata": {
"id": "12ff1831-b733-4861-a3e7-6115d20106f4",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Alsid"
},
"support": {
"name": "Alsid",
"link": "https://www.alsid.com/contact-us/",
"tier": "developer"
}
}
}

Двоичный файл не отображается.

Просмотреть файл

@ -9,6 +9,7 @@ import hashlib
import os
import tempfile
import logging
import re
from .state_manager import StateManager
customer_id = os.environ['WorkspaceID']
@ -17,9 +18,18 @@ jira_token = os.environ['JiraAccessToken']
jira_username = os.environ['JiraUsername']
jira_homesite_name = os.environ['JiraHomeSiteName']
connection_string = os.environ['AzureWebJobsStorage']
logAnalyticsUri = os.environ.get('logAnalyticsUri')
log_type = 'Jira_Audit'
jira_uri_audit = "https://" + jira_homesite_name + ".atlassian.net/rest/api/3/auditing/record"
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customer_id + '.ods.opinsights.azure.com'
pattern = r"https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$"
match = re.match(pattern,str(logAnalyticsUri))
if(not match):
raise Exception("Invalid Log Analytics Uri.")
def generate_date():
current_time = datetime.datetime.utcnow().replace(second=0, microsecond=0) - datetime.timedelta(minutes=10)
state = StateManager(connection_string=connection_string)
@ -95,7 +105,7 @@ def post_data(body):
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
content_length = len(body)
signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource)
uri = 'https://' + customer_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01'
uri = logAnalyticsUri + resource + '?api-version=2016-04-01'
headers = {
'content-type': content_type,

Просмотреть файл

@ -111,11 +111,11 @@
},
{
"title": "",
"description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://github.com/averbn/azure_sentinel_data_connectors/blob/main/jira-audit-azure-sentinel-data-connector/JiraAuditAPISentinelConn.zip?raw=true) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. JiraAuditXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Azure Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
"description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-jiraauditapi-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. JiraAuditXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Azure Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
},
{
"title": "",
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select ** New application setting**.\n3. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tJiraUsername\n\t\tJiraAccessToken\n\t\tJiraHomeSiteName\n\t\tWorkspaceID\n\t\tWorkspaceKey\n3. Once all application settings have been entered, click **Save**."
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select ** New application setting**.\n3. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tJiraUsername\n\t\tJiraAccessToken\n\t\tJiraHomeSiteName\n\t\tWorkspaceID\n\t\tWorkspaceKey\n\t\tlogAnalyticsUri (optional)\n> - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://<CustomerId>.ods.opinsights.azure.us`.\n3. Once all application settings have been entered, click **Save**."
}
]
}

Просмотреть файл

@ -4,6 +4,8 @@
"parameters": {
"FunctionName": {
"defaultValue": "JiraAudit",
"minLength": 1,
"maxLength": 11,
"type": "string"
},
"WorkspaceID": {
@ -28,7 +30,9 @@
}
},
"variables": {
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]"
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
"StorageSuffix": "[environment().suffixes.storage]",
"LogAnaltyicsUri": "[replace(environment().portal, 'https://portal', concat('https://', toLower(parameters('WorkspaceID')), '.ods.opinsights'))]"
},
"resources": [
{
@ -148,30 +152,18 @@
"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=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=core.windows.net')]",
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
"WorkspaceID": "[parameters('WorkspaceID')]",
"WorkspaceKey": "[parameters('WorkspaceKey')]",
"JiraAccessToken": "[parameters('JiraAccessToken')]",
"JiraUsername": "[parameters('JiraUsername')]",
"JiraHomeSiteName": "[parameters('JiraHomeSiteName')]",
"WEBSITE_RUN_FROM_PACKAGE": "https://github.com/averbn/azure_sentinel_data_connectors/blob/main/jira-audit-azure-sentinel-data-connector/JiraAuditAPISentinelConn.zip?raw=true"
"logAnalyticsUri": "[variables('LogAnaltyicsUri')]",
"WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-jiraauditapi-functionapp"
}
}
]
},
{
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2018-11-01",
"name": "[concat(variables('FunctionName'), '/', variables('FunctionName'), '.azurewebsites.net')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('FunctionName'))]"
],
"properties": {
"siteName": "[variables('FunctionName')]",
"hostNameType": "Verified"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",

Просмотреть файл

@ -91,7 +91,7 @@
},
{
"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)",
"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": {
@ -125,5 +125,21 @@
}
]
}
]
],
"metadata": {
"id": "31f0ea52-dcd4-443b-9d04-a3e709addebc",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Better Mobile"
},
"support": {
"name": "Better Mobile",
"email": "support@better.mobi",
"tier": "developer"
}
}
}

Просмотреть файл

@ -97,7 +97,7 @@
},
{
"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)",
"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": {
@ -139,5 +139,21 @@
}
]
}
]
],
"metadata": {
"id": "3be993d4-3aa7-41de-8280-e62de7859eca",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Beyond Security"
},
"support": {
"name": "Beyond Security",
"link": "https://beyondsecurity.freshdesk.com/support/home",
"tier": "developer"
}
}
}

Просмотреть файл

@ -11,12 +11,22 @@ from .state_manager import StateManager
from dateutil.parser import parse as parse_date
import azure.functions as func
import logging
import re
WORKSPACE_ID = os.environ['AzureSentinelWorkspaceId']
SHARED_KEY = os.environ['AzureSentinelSharedKey']
logAnalyticsUri = os.environ.get('logAnalyticsUri')
LOG_TYPE = 'BoxEvents'
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + WORKSPACE_ID + '.ods.opinsights.azure.com'
pattern = r"https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$"
match = re.match(pattern,str(logAnalyticsUri))
if(not match):
raise Exception("Invalid Log Analytics Uri.")
# interval of script execution
SCRIPT_EXECUTION_INTERVAL_MINUTES = 2
# if ts of last extracted event is older than now - MAX_PERIOD_MINUTES -> script will get events from now - SCRIPT_EXECUTION_INTERVAL_MINUTES
@ -41,7 +51,7 @@ def main(mytimer: func.TimerRequest):
logging.info('Script started. Getting events from stream_position {}, created_after {}'.format(stream_position, created_after))
sentinel = AzureSentinelConnector(workspace_id=WORKSPACE_ID, shared_key=SHARED_KEY, log_type=LOG_TYPE, queue_size=10000)
sentinel = AzureSentinelConnector(workspace_id=WORKSPACE_ID, logAnalyticsUri = logAnalyticsUri, shared_key=SHARED_KEY, log_type=LOG_TYPE, queue_size=10000)
with sentinel:
for events, stream_position in get_events(config_dict, created_after, stream_position=stream_position):
for event in events:

Просмотреть файл

@ -9,8 +9,9 @@ from threading import Thread
class AzureSentinelConnector:
def __init__(self, workspace_id, shared_key, log_type, queue_size=200, bulks_number=10, queue_size_bytes=25 * (2**20)):
def __init__(self, workspace_id, logAnalyticsUri, shared_key, log_type, queue_size=200, bulks_number=10, queue_size_bytes=25 * (2**20)):
self.workspace_id = workspace_id
self.logAnalyticsUri = logAnalyticsUri
self.shared_key = shared_key
self.log_type = log_type
self.queue_size = queue_size
@ -79,7 +80,7 @@ class AzureSentinelConnector:
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
content_length = len(body)
signature = self._build_signature(workspace_id, shared_key, rfc1123date, content_length, method, content_type, resource)
uri = 'https://' + workspace_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01'
uri = self.logAnalyticsUri + resource + '?api-version=2016-04-01'
headers = {
'content-type': content_type,

Двоичные данные
DataConnectors/Box/BoxConn.zip

Двоичный файл не отображается.

Просмотреть файл

@ -124,7 +124,7 @@
},
{
"title": "",
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tAzureSentinelWorkspaceId\n\t\tAzureSentinelSharedKey\n\t\tBOX_CONFIG_JSON\n3. Once all application settings have been entered, click **Save**."
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tAzureSentinelWorkspaceId\n\t\tAzureSentinelSharedKey\n\t\tBOX_CONFIG_JSON\n\t\tlogAnalyticsUri (optional)\n> - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://<CustomerId>.ods.opinsights.azure.us`.\n3. Once all application settings have been entered, click **Save**."
}
]
}

Просмотреть файл

@ -4,6 +4,8 @@
"parameters": {
"FunctionName": {
"defaultValue": "Box",
"minLength": 1,
"maxLength": 11,
"type": "string"
},
"BoxConfigJSON": {
@ -20,7 +22,9 @@
}
},
"variables": {
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]"
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
"StorageSuffix": "[environment().suffixes.storage]",
"LogAnaltyicsUri": "[replace(environment().portal, 'https://portal', concat('https://', toLower(parameters('AzureSentinelWorkspaceId')), '.ods.opinsights'))]"
},
"resources": [
{
@ -141,28 +145,16 @@
"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=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=core.windows.net')]",
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
"BOX_CONFIG_JSON": "[parameters('BoxConfigJSON')]",
"AzureSentinelWorkspaceId": "[parameters('AzureSentinelWorkspaceId')]",
"AzureSentinelSharedKey": "[parameters('AzureSentinelSharedKey')]",
"logAnalyticsUri": "[variables('LogAnaltyicsUri')]",
"WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-BoxDataConnector-functionapp"
}
}
]
},
{
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2018-11-01",
"name": "[concat(variables('FunctionName'), '/', variables('FunctionName'), '.azurewebsites.net')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('FunctionName'))]"
],
"properties": {
"siteName": "[variables('FunctionName')]",
"hostNameType": "Verified"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",

Просмотреть файл

@ -122,5 +122,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "7504f78d-1928-4399-a1ae-ba826c47c42d",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Citrix Systems"
},
"support": {
"name": "Citrix Systems",
"link": "https://www.citrix.com/support/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -114,5 +114,21 @@
}
]
}
]
],
"metadata": {
"id": "47835227-715b-4000-892e-e1fff81023c0",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "WatchGuard"
},
"support": {
"name": "WatchGuard",
"link": "https://www.watchguard.com/wgrd-support/overview",
"tier": "developer"
}
}
}

Просмотреть файл

@ -96,5 +96,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machines security according to your organizations security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "1c45e738-21dd-4fcd-9449-e2c9478e9552",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Cyberark"
},
"support": {
"name": "Cyberark",
"link": "https://www.cyberark.com/customer-support/",
"tier": "developer"
}
}
}

Двоичный файл не отображается.

Просмотреть файл

@ -38,8 +38,18 @@ def main(eeimsg: func.QueueMessage) -> None:
verify = bool(strtobool(os.environ['verifySsl']))
workspace_id = os.environ['workspaceId']
workspace_key = os.environ['workspaceKey']
logAnalyticsUri = os.environ.get('logAnalyticsUri')
log_type = 'ESETEnterpriseInspector'
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customer_id + '.ods.opinsights.azure.com'
pattern = r'https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$'
match = re.match(pattern,str(logAnalyticsUri))
if(not match):
raise Exception("ESET Enterprise Inspector: Invalid Log Analytics Uri.")
# Connect to ESET Enterprise Inspector server
ei = EnterpriseInspector(
base_url=base_url,
@ -58,5 +68,6 @@ def main(eeimsg: func.QueueMessage) -> None:
customer_id=workspace_id,
shared_key=workspace_key,
body=body,
log_type=log_type
log_type=log_type,
logAnalyticsUri = logAnalyticsUri
)

Просмотреть файл

@ -24,15 +24,16 @@ def build_signature(customer_id, shared_key, date, content_length, method, conte
return authorization
# Build and send a request to the POST API
def post_data(customer_id, shared_key, body, log_type):
def post_data(customer_id, shared_key, body, log_type, logAnalyticsUri):
method = 'POST'
content_type = 'application/json'
resource = '/api/logs'
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
content_length = len(body)
signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource)
uri = 'https://' + customer_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01'
uri = logAnalyticsUri + resource + '?api-version=2016-04-01'
headers = {
'content-type': content_type,
'Authorization': signature,
@ -40,9 +41,9 @@ def post_data(customer_id, shared_key, body, log_type):
'x-ms-date': rfc1123date
}
response = requests.post(uri,data=body, headers=headers)
response = requests.post(uri, data=body, headers=headers)
if (response.status_code >= 200 and response.status_code <= 299):
print('Accepted')
else:
exit_error(f'Response code "{response.status_code}" while sending data through data-collector API.')
exit_error(f'Response code "{response.status_code}" while sending data through data-collector API.')

Просмотреть файл

@ -0,0 +1,156 @@
{
"id": "Exabeam",
"title": "Exabeam Advanced Analytics",
"publisher": "Exabeam",
"descriptionMarkdown": "The [Exabeam Advanced Analytics](https://www.exabeam.com/ueba/advanced-analytics-and-mitre-detect-and-stop-threats/) data connector provides the capability to ingest Exabeam Advanced Analytics events into Azure Sentinel. Refer to [Exabeam Advanced Analytics documentation](https://docs.exabeam.com/) for more information.",
"additionalRequirementBanner": "This data connector depends on a parser based on Kusto Function to work as expected. Follow the steps to use this Kusto Function alias **ExabeamEvent** in queries and workbooks. [Follow steps to get this Kusto Function>](https://aka.ms/sentinel-Exabeam-parser)",
"graphQueries": [
{
"metricName": "Total data received",
"legend": "Exabeam",
"baseQuery": "ExabeamEvent"
}
],
"sampleQueries": [
{
"description" : "Top 10 Clients (Source IP)",
"query": "ExabeamEvent\n | summarize count() by SrcIpAddr\n | top 10 by count_"
}
],
"dataTypes": [
{
"name": "Syslog (Exabeam)",
"lastDataReceivedQuery": "ExabeamEvent\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
}
],
"connectivityCriterias": [
{
"type": "IsConnectedQuery",
"value": [
"ExabeamEvent\n | summarize LastLogReceived = max(TimeGenerated)\n | project IsConnected = LastLogReceived > ago(30d)"
]
}
],
"availability": {
"status": 2,
"isPreview": true
},
"permissions": {
"resourceProvider": [
{
"provider": "Microsoft.OperationalInsights/workspaces",
"permissionsDisplayText": "write permission is required.",
"providerDisplayName": "Workspace",
"scope": "Workspace",
"requiredPermissions": {
"write": true,
"delete": true
}
}
]
},
"instructionSteps": [
{
"title": "",
"description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. [Follow these steps](https://aka.ms/sentinel-Exabeam-parser) to create the Kusto Functions alias, **ExabeamEvent**",
"instructions": [
]
},
{
"title": "",
"description": ">**NOTE:** This data connector has been developed using Exabeam Advanced Analytics i54 (Syslog)",
"instructions": [
]
},
{
"title": "1. Install and onboard the agent for Linux or Windows",
"description": "Install the agent on the server where the Exabeam Advanced Analytic logs are generated or forwarded.\n\n> Logs from Exabeam Advanced Analytic deployed on Linux or Windows servers are collected by **Linux** or **Windows** agents.",
"instructions": [
{
"parameters": {
"title": "Choose where to install the Linux agent:",
"instructionSteps": [
{
"title": "Install agent on Azure Linux Virtual Machine",
"description": "Select the machine to install the agent on and then click **Connect**.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnLinuxVirtualMachine"
},
"type": "InstallAgent"
}
]
},
{
"title": "Install agent on a non-Azure Linux Machine",
"description": "Download the agent on the relevant machine and follow the instructions.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnLinuxNonAzure"
},
"type": "InstallAgent"
}
]
}
]
},
"type": "InstructionStepsGroup"
}
]
},
{
"instructions": [
{
"parameters": {
"title": "Choose where to install the Windows agent:",
"instructionSteps": [
{
"title": "Install agent on Azure Windows Virtual Machine",
"description": "Select the machine to install the agent on and then click **Connect**.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnVirtualMachine"
},
"type": "InstallAgent"
}
]
},
{
"title": "Install agent on a non-Azure Windows Machine",
"description": "Download the agent on the relevant machine and follow the instructions.",
"instructions": [
{
"parameters": {
"linkType": "InstallAgentOnNonAzure"
},
"type": "InstallAgent"
}
]
}
]
},
"type": "InstructionStepsGroup"
}
]
},
{
"title": "2. Configure the logs to be collected",
"description": "Configure the custom log directory to be collected" ,
"instructions": [
{
"parameters": {
"linkType": "OpenAdvancedWorkspaceSettings"
},
"type": "InstallAgent"
}
]
},
{
"title": "3. Configure Exabeam event forwarding to Syslog",
"description": "[Follow these instructions](https://docs.exabeam.com/en/advanced-analytics/i54/advanced-analytics-administration-guide/113254-configure-advanced-analytics.html#UUID-7ce5ff9d-56aa-93f0-65de-c5255b682a08) to send Exabeam Advanced Analytics activity log data via syslog."
}
]
}

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "FORCEPOINT_NGFW",
"id": "ForcepointNgfw",
"title": "Forcepoint NGFW (Preview)",
"publisher": "Forcepoint",
"descriptionMarkdown": "The Forcepoint NGFW (Next Generation Firewall) connector allows you to automatically export user-defined Forcepoint NGFW logs into Azure Sentinel in real-time. This enriches visibility into user activities recorded by NGFW, enables further correlation with data from Azure workloads and other feeds, and improves monitoring capability with Workbooks inside Azure Sentinel.",
@ -122,5 +122,21 @@
"title": "5. Forcepoint integration installation guide ",
"description": "To complete the installation of this Forcepoint product integration, follow the guide linked below.\n\n[Installation Guide >](https://frcpnt.com/ngfw-sentinel)"
}
]
],
"metadata":{
"id": "e002d400-e0b0-4673-959a-eec31378d17c",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Forcepoint"
},
"support": {
"name": "Forcepoint",
"link": "https://support.forcepoint.com/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -116,6 +116,22 @@
},
{ "title": "5. Forcepoint integration installation guide ",
"description": "To complete the installation of this Forcepoint product integration, follow the guide linked below.\n\n[Installation Guide >](https://frcpnt.com/casb-sentinel)"
}
],
"metadata": {
"id": "04f93db2-8f2a-4edc-bb78-9e1e7587faff",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Forcepoint"
},
"support": {
"name": "Forcepoint",
"link": "https://support.forcepoint.com",
"tier": "developer"
}
}
]
}

Просмотреть файл

@ -57,7 +57,7 @@
},
{
"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)",
"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": {
@ -91,5 +91,21 @@
}
]
}
]
],
"metadata": {
"id": "c4961e1e-45b1-4565-a096-6e14561c90b6",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Forcepoint"
},
"support": {
"name": "Forcepoint",
"link": "https://support.forcepoint.com/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -118,5 +118,21 @@
"title" : "4. Secure your machine ",
"description" : "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "cb5b9a69-5ab1-445c-8491-6b96a2ea3100",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "ForgeRock"
},
"support": {
"name": "ForgeRock",
"link": "https://www.forgerock.com/support",
"tier": "developer"
}
}
}

Двоичный файл не отображается.

Просмотреть файл

@ -3,7 +3,7 @@
Language: PowerShell
Version: 1.2
Author: Nicholas Dicola, Sreedhar Ande
Last Modified: 02/08/2021
Last Modified: 03/12/2021
DESCRIPTION
This Function App calls the GitHub REST API (https://api.github.com/) to pull the GitHub
@ -36,25 +36,21 @@ $AzureWebJobsStorage = $env:AzureWebJobsStorage
$personalAccessToken = $env:PersonalAccessToken
$workspaceId = $env:WorkspaceId
$workspaceKey = $env:WorkspaceKey
$LAURI = $env:LAURI
$storageAccountContainer = "github-repo-logs"
$AuditLogTable = $env:GitHubAuditLogsTableName
if ([string]::IsNullOrEmpty($AuditLogTable))
{
$AuditLogTable = "GitHub_CL"
}
$RepoLogTable = $env:GitHubRepoLogsTableName
if ([string]::IsNullOrEmpty($RepoLogTable))
{
$RepoLogTable = "GitHubRepoLogs_CL"
}
#The AzureTenant variable is used to specify other cloud environments like Azure Gov(.us) etc.,
$AzureTenant = $env:AZURE_TENANT
$AuditLogTable = "GitHub_CL"
$RepoLogTable = "GitHubRepoLogs_CL"
$currentStartTime = (get-date).ToUniversalTime() | get-date -Format yyyy-MM-ddTHH:mm:ss:ffffffZ
if (-Not [string]::IsNullOrEmpty($LAURI)){
if($LAURI.Trim() -notmatch 'https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$')
{
Write-Error -Message "DocuSign-SecurityEvents: Invalid Log Analytics Uri." -ErrorAction Stop
Exit
}
}
function Write-OMSLogfile {
<#
.SYNOPSIS
@ -129,12 +125,13 @@ function Write-OMSLogfile {
-contentType $ContentType `
-resource $resource
# Compatible with Commercial and Gov Tenants
if ([string]::IsNullOrEmpty($AzureTenant)){
$uri = "https://" + $CustomerId + ".ods.opinsights.azure.com" + $resource + "?api-version=2016-04-01"
# Compatible with previous version
if ([string]::IsNullOrEmpty($LAURI)){
$LAURI = "https://" + $CustomerId + ".ods.opinsights.azure.com" + $resource + "?api-version=2016-04-01"
}
else{
$uri = "https://" + $CustomerId + ".ods.opinsights.azure" +$AzureTenant + $resource + "?api-version=2016-04-01"
else
{
$LAURI = $LAURI + $resource + "?api-version=2016-04-01"
}
$headers = @{
@ -143,7 +140,7 @@ function Write-OMSLogfile {
"x-ms-date" = $rfc1123date
"time-generated-field" = $dateTime
}
$response = Invoke-WebRequest -Uri $uri -Method $method -ContentType $ContentType -Headers $headers -Body $Body -UseBasicParsing
$response = Invoke-WebRequest -Uri $LAURI -Method $method -ContentType $ContentType -Headers $headers -Body $Body -UseBasicParsing
Write-Verbose -message ('Post Function Return Code ' + $response.statuscode)
return $response.statuscode
}
@ -398,14 +395,23 @@ foreach($org in $githubOrgs){
$forkLogs | Add-Member -NotePropertyName LogType -NotePropertyValue Forks
#Send to log A
SendToLogA -gitHubData $forkLogs -customLogName $RepoLogTable
}
}
$uri = "https://api.github.com/repos/$orgName/$repoName/secret-scanning/alerts"
$secretscanningalerts = $null
$secretscanningalerts = Invoke-RestMethod -Method Get -Uri $uri -Headers $headers
if ($secretscanningalerts.Length -gt 0){
$secretscanningalerts | Add-Member -NotePropertyName OrgName -NotePropertyValue $orgName
$secretscanningalerts | Add-Member -NotePropertyName Repository -NotePropertyValue $repoName
$secretscanningalerts | Add-Member -NotePropertyName LogType -NotePropertyValue SecretScanningAlerts
#Send to log A
SendToLogA -gitHubData $secretscanningalerts -customLogName $RepoLogTable
}
}
else {
Write-Host "$repoName is empty"
Write-Verbose "$repoName is empty"
}
}
}
# get blobs for last run

Просмотреть файл

@ -1,3 +1,11 @@
## 1.3
- Added secret-scanning/alerts logs
- Updated ARM template to support both Commercial and Azure Gov
- Removed previously added logic
- Environment variables to provide additional support for users to supply their own values for Table names
## 1.2
- Fixed issues raised on Sentinel GitHub Repo on AuditLogs
- Updated logic to ingest each AuditLog as an individual record

Просмотреть файл

@ -118,7 +118,7 @@
},
{
"title": "Option 1 - Azure Resource Manager (ARM) Template",
"description": "This method provides an automated deployment of the GitHub Data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FDataConnectors%2FGithubFunction%2Fazurecomdeploy_dotcomtenants.json)\t[![Deploy To Azure Gov](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazuregov.png)](https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FDataConnectors%2FGithubFunction%2Fazuregovdeploy_dotustenants.json)\t(**.us Tenant**)\n\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID**, **Workspace Key**, **Personal Access Token** \n> - The default **Time Interval** is set to pull the last five (5) minutes of data. If the time interval needs to be modified, it is recommended to change the Function App Timer Trigger accordingly (in the function.json file, post deployment) to prevent overlapping data ingestion. \n> - Note: If using Azure Key Vault secrets for any of the values above, use the`@Microsoft.KeyVault(SecretUri={Security Identifier})`schema in place of the string values. Refer to [Key Vault references documentation](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) for further details. \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
"description": "This method provides an automated deployment of the GitHub Data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FDataConnectors%2FGithubFunction%2Fazuredeploy.json)\n\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter the **Workspace ID**, **Workspace Key**, **Personal Access Token** \n> - The default **Time Interval** is set to pull the last five (5) minutes of data. If the time interval needs to be modified, it is recommended to change the Function App Timer Trigger accordingly (in the function.json file, post deployment) to prevent overlapping data ingestion. \n> - Note: If using Azure Key Vault secrets for any of the values above, use the`@Microsoft.KeyVault(SecretUri={Security Identifier})`schema in place of the string values. Refer to [Key Vault references documentation](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) for further details. \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
},
{
"title": "Option 2 - Manual Deployment of Azure Functions",
@ -130,7 +130,7 @@
},
{
"title": "",
"description": "**2. Import Function App Code**\n\n1. In the newly created Function App, select **Functions** on the left pane and click **+ Add**.\n2. Select **Timer Trigger**.\n3. Enter a unique Function **Name** and leave the default cron schedule of every 5 minutes, then click **Create**.\n4. Click on **Code + Test** on the left pane. \n5. Copy the [Function App Code](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fandedevsecops%2FAzure-Sentinel%2Faz-func-github-dataconnector%2FDataConnectors%2FGithubFunction%2Fazuredeploy_GitHubData.json) and paste into the Function App `run.ps1` editor.\n5. Click **Save**."
"description": "**2. Import Function App Code**\n\n1. In the newly created Function App, select **Functions** on the left pane and click **+ Add**.\n2. Select **Timer Trigger**.\n3. Enter a unique Function **Name** and leave the default cron schedule of every 5 minutes, then click **Create**.\n4. Click on **Code + Test** on the left pane. \n5. Copy the [Function App Code](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fandedevsecops%2FAzure-Sentinel%2Faz-func-github-dataconnector%2FDataConnectors%2FGithubFunction%2Fazuredeploy.json) and paste into the Function App `run.ps1` editor.\n5. Click **Save**."
},
{
"title": "",

Просмотреть файл

@ -1,4 +1,5 @@
{
"org":"",
"lastContext": "",
"lastRun": ""
}

Просмотреть файл

@ -9,27 +9,24 @@
"description": "Specifies the name of the Function App."
}
},
"PersonalAccessToken": {
"defaultValue": "Enter the GitHub Personal Access Token (PAT)",
"type": "string",
"PersonalAccessToken": {
"type": "securestring",
"metadata": {
"description": "Specifies GitHub Enterprise Personal Access Token."
}
},
"WorkspaceId": {
"type": "string",
"defaultValue": "<WorkspaceId>",
"type": "string",
"metadata": {
"description": "Specifies the Log Analytics Workspace Id."
}
},
"WorkspaceKey": {
"type": "string",
"defaultValue": "<WorkspaceKey>",
"type": "securestring",
"metadata": {
"description": "Specifies the Log Analytics Workspace Key."
}
},
},
"FunctionSchedule": {
"type": "string",
"defaultValue": "0 */10 * * * *",
@ -40,10 +37,13 @@
},
"variables": {
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
"KeyVaultName": "[tolower(concat('githubkv', uniqueString(resourceGroup().id, subscription().id)))]",
"StorageAccountName":"[concat(substring(variables('FunctionName'), 0, 20), 'sa')]",
"KeyVaultName": "[concat(substring(variables('FunctionName'), 0, 20), 'kv')]",
"GitAPIToken": "GitAPIToken",
"LogAnalyticsWorkspaceKey": "LogAnalyticsWorkspaceKey",
"StorageContainerName": "github-repo-logs"
"StorageContainerName": "github-repo-logs",
"StorageSuffix":"[environment().suffixes.storage]",
"LogAnaltyicsUri":"[replace(environment().portal, 'https://portal', concat('https://', toLower(parameters('WorkspaceId')), '.ods.opinsights'))]"
},
"resources": [
{
@ -60,7 +60,7 @@
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[tolower(variables('FunctionName'))]",
"name": "[variables('StorageAccountName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS",
@ -112,9 +112,9 @@
{
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default')]",
"name": "[concat(variables('StorageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"sku": {
"name": "Standard_LRS",
@ -133,9 +133,9 @@
{
"type": "Microsoft.Storage/storageAccounts/fileServices",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default')]",
"name": "[concat(variables('StorageAccountName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"sku": {
"name": "Standard_LRS",
@ -154,7 +154,7 @@
"name": "[variables('FunctionName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]",
"[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
"[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
],
@ -167,7 +167,10 @@
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
"httpsOnly": true,
"clientAffinityEnabled": true,
"alwaysOn": true
"alwaysOn": true,
"siteConfig": {
"powerShellVersion": "~7"
}
},
"resources": [
{
@ -185,16 +188,15 @@
"FUNCTIONS_WORKER_RUNTIME": "powershell",
"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=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=core.windows.net')]",
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=core.windows.net')]",
"AzureWebJobsStorage": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('StorageAccountName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName')), '2019-06-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('StorageAccountName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName')), '2019-06-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
"WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
"PersonalAccessToken": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('GitAPIToken')).secretUriWithVersion, ')')]",
"TMPDIR": "D:\\local\\Temp",
"TMPDIR": "C:\\local\\Temp",
"WorkspaceId": "[parameters('WorkspaceId')]",
"WorkspaceKey": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('LogAnalyticsWorkspaceKey')).secretUriWithVersion, ')')]",
"Schedule": "[parameters('FunctionSchedule')]",
"GitHubAuditLogsTableName": "GitHubAuditLogs",
"GitHubRepoLogsTableName": "GitHubRepoLogs",
"LAURI": "[variables('LogAnaltyicsUri')]",
"WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/githubazurefunctionzip"
}
}
@ -263,26 +265,13 @@
}
]
},
{
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2018-11-01",
"name": "[concat(variables('FunctionName'), '/', variables('FunctionName'), '.azurewebsites.net')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('FunctionName'))]"
],
"properties": {
"siteName": "[variables('FunctionName')]",
"hostNameType": "Verified"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
"name": "[concat(variables('StorageAccountName'), '/default/azure-webjobs-hosts')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('StorageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"properties": {
"publicAccess": "None"
@ -291,10 +280,10 @@
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
"name": "[concat(variables('StorageAccountName'), '/default/azure-webjobs-secrets')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('StorageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"properties": {
"publicAccess": "None"
@ -303,10 +292,10 @@
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), concat('/default/', variables('StorageContainerName')))]",
"name": "[concat(variables('StorageAccountName'), concat('/default/', variables('StorageContainerName')))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('StorageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"properties": {
"publicAccess": "None"
@ -315,10 +304,10 @@
{
"type": "Microsoft.Storage/storageAccounts/fileServices/shares",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
"name": "[concat(variables('StorageAccountName'), '/default/', tolower(variables('StorageAccountName')))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
"[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('StorageAccountName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('StorageAccountName'))]"
],
"properties": {
"shareQuota": 5120

Просмотреть файл

@ -1,329 +0,0 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"FunctionName": {
"defaultValue": "GitHubLogs",
"type": "string",
"metadata": {
"description": "Specifies the name of the Function App."
}
},
"PersonalAccessToken": {
"defaultValue": "Enter the GitHub Personal Access Token (PAT)",
"type": "string",
"metadata": {
"description": "Specifies GitHub Enterprise Personal Access Token."
}
},
"WorkspaceId": {
"type": "string",
"defaultValue": "<WorkspaceId>",
"metadata": {
"description": "Specifies the Log Analytics Workspace Id."
}
},
"WorkspaceKey": {
"type": "string",
"defaultValue": "<WorkspaceKey>",
"metadata": {
"description": "Specifies the Log Analytics Workspace Key."
}
},
"FunctionSchedule": {
"type": "string",
"defaultValue": "0 */10 * * * *",
"metadata": {
"description": "For a `TimerTrigger` to work, you provide a schedule in the form of a [cron expression](https://en.wikipedia.org/wiki/Cron#CRON_expression)(See the link for full details). A cron expression is a string with 6 separate expressions which represent a given schedule via patterns. The pattern we use to represent every 1 hour is `0 0 * * * *`. This, in plain text, means: When seconds is equal to 0, minutes is divisible by 5, for any hour, day of the month, month, day of the week, or year"
}
}
},
"variables": {
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
"KeyVaultName": "[tolower(concat('githubkv', uniqueString(resourceGroup().id, subscription().id)))]",
"GitAPIToken": "GitAPIToken",
"LogAnalyticsWorkspaceKey": "LogAnalyticsWorkspaceKey",
"StorageContainerName": "github-repo-logs"
},
"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": "[tolower(variables('FunctionName'))]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"kind": "StorageV2",
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [
],
"ipRules": [
],
"defaultAction": "Allow"
},
"supportsHttpsTrafficOnly": true,
"encryption": {
"services": {
"file": {
"keyType": "Account",
"enabled": true
},
"blob": {
"keyType": "Account",
"enabled": true
}
},
"keySource": "Microsoft.Storage"
}
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[variables('FunctionName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Y1",
"tier": "Dynamic"
},
"kind": "functionapp",
"properties": {
"name": "[variables('FunctionName')]",
"workerSize": "0",
"workerSizeId": "0",
"numberOfWorkers": "1"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
],
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"properties": {
"cors": {
"corsRules": [
]
},
"deleteRetentionPolicy": {
"enabled": false
}
}
},
{
"type": "Microsoft.Storage/storageAccounts/fileServices",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
],
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"properties": {
"cors": {
"corsRules": [
]
}
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[variables('FunctionName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
"[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
"[resourceId('Microsoft.Insights/components', variables('FunctionName'))]"
],
"kind": "functionapp",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"name": "[variables('FunctionName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('FunctionName'))]",
"httpsOnly": true,
"clientAffinityEnabled": true,
"alwaysOn": true
},
"resources": [
{
"apiVersion": "2018-11-01",
"type": "config",
"name": "appsettings",
"dependsOn": [
"[concat('Microsoft.Web/sites/', variables('FunctionName'))]",
"[resourceId('Microsoft.KeyVault/vaults/', variables('KeyVaultName'))]",
"[resourceId('Microsoft.KeyVault/vaults/secrets', variables('KeyVaultName'), variables('GitAPIToken'))]",
"[resourceId('Microsoft.KeyVault/vaults/secrets', variables('KeyVaultName'), variables('LogAnalyticsWorkspaceKey'))]"
],
"properties": {
"FUNCTIONS_EXTENSION_VERSION": "~3",
"FUNCTIONS_WORKER_RUNTIME": "powershell",
"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=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=core.usgovcloudapi.net')]",
"WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('DefaultEndpointsProtocol=https;AccountName=', toLower(variables('FunctionName')),';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=core.usgovcloudapi.net')]",
"WEBSITE_CONTENTSHARE": "[toLower(variables('FunctionName'))]",
"PersonalAccessToken": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('GitAPIToken')).secretUriWithVersion, ')')]",
"TMPDIR": "D:\\local\\Temp",
"WorkspaceId": "[parameters('WorkspaceId')]",
"WorkspaceKey": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('LogAnalyticsWorkspaceKey')).secretUriWithVersion, ')')]",
"Schedule": "[parameters('FunctionSchedule')]",
"AZURE_TENANT": ".us",
"GitHubAuditLogsTableName": "GitHubAuditLogs",
"GitHubRepoLogsTableName": "GitHubRepoLogs",
"WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/githubazurefunctionzip"
}
}
]
},
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2016-10-01",
"name": "[variables('KeyVaultName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('FunctionName'))]"
],
"properties": {
"sku": {
"family": "A",
"name": "Standard"
},
"tenantId": "[subscription().tenantId]",
"accessPolicies": [
{
"tenantId": "[subscription().tenantId]",
"objectId": "[reference(resourceId('Microsoft.Web/sites', variables('FunctionName')),'2019-08-01', 'full').identity.principalId]",
"permissions": {
"secrets": [ "get",
"list"
]
}
}
],
"enabledForDeployment": false,
"enabledForDiskEncryption": false,
"enabledForTemplateDeployment": true,
"enableSoftDelete": true
},
"resources": [
{
"type": "secrets",
"apiVersion": "2016-10-01",
"name": "[variables('GitAPIToken')]",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults/', variables('KeyVaultName'))]"
],
"properties": {
"value": "[parameters('PersonalAccessToken')]",
"contentType": "string",
"attributes": {
"enabled": true
}
}
},
{
"type": "secrets",
"apiVersion": "2016-10-01",
"name": "[variables('LogAnalyticsWorkspaceKey')]",
"dependsOn": [
"[resourceId('Microsoft.KeyVault/vaults/', variables('KeyVaultName'))]"
],
"properties": {
"value": "[parameters('WorkspaceKey')]",
"contentType": "string",
"attributes": {
"enabled": true
}
}
}
]
},
{
"type": "Microsoft.Web/sites/hostNameBindings",
"apiVersion": "2018-11-01",
"name": "[concat(variables('FunctionName'), '/', variables('FunctionName'), '.azurewebsites.us')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Web/sites', variables('FunctionName'))]"
],
"properties": {
"siteName": "[variables('FunctionName')]",
"hostNameType": "Verified"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
],
"properties": {
"publicAccess": "None"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
],
"properties": {
"publicAccess": "None"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), concat('/default/', variables('StorageContainerName')))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
],
"properties": {
"publicAccess": "None"
}
},
{
"type": "Microsoft.Storage/storageAccounts/fileServices/shares",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
],
"properties": {
"shareQuota": 5120
}
}
]
}

Просмотреть файл

@ -12,16 +12,30 @@ Following are the configuration steps to deploy Function App.
A GitHub API Token is required. See the documentation to learn more about the [GitHub Personal Access Token](https://github.com/settings/tokens/).
## Configuration Steps
1. Deploy the ARM template and fill in the parameters.
## Configuration Steps to Deploy Function App
1. Click on Deploy to Azure (For both Commercial & Azure GOV)
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FDataConnectors%2FGithubFunction%2Fazuredeploy.json" target="_blank">
<img src="https://aka.ms/deploytoazurebutton"/>
</a>
2. Select the preferred **Subscription**, **Resource Group** and **Location**
**Note**
Best practice : Create new Resource Group while deploying - all the resources of your custom Data connector will reside in the newly created Resource
Group
3. Enter the following value in the ARM template deployment
```
"PersonalAccessToken": This is the GITHUB PAT
"Workspace Id": The Sentinel Log Analytics Workspace Id
"Workspace Key": The Sentinel Log Analytics Workspace Key
"Function Schedule": The `TimerTrigger` makes it incredibly easy to have your functions executed on a schedule
"PersonalAccessToken": This is the GITHUB PAT
"Workspace Id": The Sentinel Log Analytics Workspace Id
"Workspace Key": The Sentinel Log Analytics Workspace Key
"Function Schedule": The `TimerTrigger` makes it incredibly easy to have your functions executed on a schedule
```
2. There are two json files (ORGS.json and lastrun-Audit.json) in Function Dependencies folder
3. Edit the ORGS.json file and update "org": "sampleorg" and replace sample org with your org name.
## Post Deployment Steps
1. There are two json files (ORGS.json and lastrun-Audit.json) in Function Dependencies folder
2. Edit the ORGS.json file and update "org": "sampleorg" and replace sample org with your org name.
```
If you have single org
[
@ -44,7 +58,7 @@ A GitHub API Token is required. See the documentation to learn more about the [G
]
```
4. Edit lastrun-Audit.json and update "org": "sampleorg" and replace sample org with your org name
3. Edit lastrun-Audit.json and update "org": "sampleorg" and replace sample org with your org name
```
If you have single org
@ -73,16 +87,16 @@ A GitHub API Token is required. See the documentation to learn more about the [G
]
```
5. Upload the following files to the storage account "github-repo-logs" container from
4. Upload the following files to the storage account "github-repo-logs" container from
```
ORGS.json
lastrun-Audit.json
```
6. PersonalAccessToken and Workspace Key will be placed as "Secrets" in the Azure KeyVault `githubkv<<uniqueid>>` with only Azure Function access policy. If you want to see/update these secrets,
5. PersonalAccessToken and Workspace Key will be placed as "Secrets" in the Azure KeyVault `<<Function App Name>><<uniqueid>>` with only Azure Function access policy. If you want to see/update these secrets,
```
a. Go to Azure KeyVault "githubkv<<uniqueid>>"
a. Go to Azure KeyVault `<<Function App Name>><<uniqueid>>`
b. Click on "Access Policies" under Settings
c. Click on "Add Access Policy"
i. Configure from template : Secret Management
@ -93,7 +107,7 @@ A GitHub API Token is required. See the documentation to learn more about the [G
```
7. The `TimerTrigger` makes it incredibly easy to have your functions executed on a schedule. This sample demonstrates a simple use case of calling your function based on your schedule provided while deploying. If you want to change
6. The `TimerTrigger` makes it incredibly easy to have your functions executed on a schedule. This sample demonstrates a simple use case of calling your function based on your schedule provided while deploying. If you want to change
the schedule
```
a. Click on Function App "Configuration" under Settings
@ -102,32 +116,21 @@ A GitHub API Token is required. See the documentation to learn more about the [G
```
**Note: For a `TimerTrigger` to work, you provide a schedule in the form of a [cron expression](https://en.wikipedia.org/wiki/Cron#CRON_expression)(See the link for full details). A cron expression is a string with 6 separate expressions which represent a given schedule via patterns. The pattern we use to represent every 5 minutes is `0 */5 * * * *`. This, in plain text, means: "When seconds is equal to 0, minutes is divisible by 5, for any hour, day of the month, month, day of the week, or year".**
8. Once Azure Function App is deployed
7. Once Azure Function App is deployed
```
a. Go to `githublogs<<uniqueid>>`
a. Go to `<<Function App Name>><<uniqueid>>`
b. Click on "Advanced Tools" under Development Tools
c. Click on Go --> You will be redirected to Web App --> Check Temp folder path.
d. It can be either C:\local\Temp\ or D:\local\Temp\.
```
9. After finding Temp folder path
8. After finding Temp folder path
```
a. Go to `githublogs<<uniqueid>>`
a. Go to `<<Function App Name>><<uniqueid>>`
b. Click on "Configuration" under Settings
c. Click on "TMPDIR" under "Application Settings"
d. Update Drive (C//D) based on your findings from Step 9.
```
**Note: Make sure the value in "TMPDIR" doesnt have "\\" at the end.**
10. **For Azure Gov customers only**, You will see additional environment variable "Azure Tenant" under "Configuration" --> "Application Settings" and its default value is ".us"
Currently this Function App supports "Azure Gov(.US)" tenants
Ex: https://portal.azure.us
Note: there are two parsers (here)[https://github.com/Azure/Azure-Sentinel/blob/master/Parsers/GitHub] to make the logs useful
## Deploy the Function App template
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FDataConnectors%2FGithubFunction%2Fazurecomdeploy_dotcomtenants.json" target="_blank">
<img src="https://aka.ms/deploytoazurebutton"/>
</a>
<a href="https://portal.azure.us/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2FAzure-Sentinel%2Fmaster%2FDataConnectors%2FGithubFunction%2Fazuregovdeploy_dotustenants.json" target="_blank">
<img src="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazuregov.png"/>
</a>

Двоичный файл не отображается.

Просмотреть файл

@ -13,6 +13,7 @@ import azure.functions as func
import logging
import os
import time
import re
customer_id = os.environ['WorkspaceID']
shared_key = os.environ['WorkspaceKey']
@ -20,6 +21,15 @@ pickle_str = os.environ['GooglePickleString']
pickle_string = base64.b64decode(pickle_str)
SCOPES = ['https://www.googleapis.com/auth/admin.reports.audit.readonly']
activities = ["login", "calendar", "drive", "admin", "mobile", "token", "user_accounts"]
logAnalyticsUri = os.environ.get('logAnalyticsUri')
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customer_id + '.ods.opinsights.azure.com'
pattern = r'https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$'
match = re.match(pattern,str(logAnalyticsUri))
if(not match):
raise Exception("Google Workspace Reports: Invalid Log Analytics Uri.")
def get_credentials():
creds = None
@ -75,15 +85,14 @@ def post_data(customer_id, shared_key, body, log_type):
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
content_length = len(body)
signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource)
uri = 'https://' + customer_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01'
uri = logAnalyticsUri + resource + '?api-version=2016-04-01'
headers = {
'content-type': content_type,
'Authorization': signature,
'Log-Type': log_type,
'x-ms-date': rfc1123date
}
response = requests.post(uri,data=body, headers=headers)
response = requests.post(uri, data=body, headers=headers)
if (response.status_code >= 200 and response.status_code <= 299):
logging.info("Logs with {} activity was processed into Azure".format(log_type))
else:

Просмотреть файл

@ -129,5 +129,21 @@
"title": "5. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "f8699c9c-536c-4d28-9049-d0c555dd8c8c",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Imperva"
},
"support": {
"name": "Imperva",
"link": "https://www.imperva.com/support/technical-support/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -53,7 +53,7 @@
},
{
"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)",
"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": {
@ -87,5 +87,21 @@
}
]
}
]
],
"metadata": {
"id": "4eb027bc-5a8e-4e7e-8dac-3aaba3e487b1",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "NXLog"
},
"support": {
"name": "NXLog",
"link": "https://nxlog.co/community-forum",
"tier": "developer"
}
}
}

Просмотреть файл

@ -57,7 +57,7 @@
},
{
"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)",
"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": {
@ -91,5 +91,21 @@
}
]
}
]
],
"metadata": {
"id": "3969d734-ab64-44fe-ac9b-73d758e0e814",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "NXLog"
},
"support": {
"name": "NXLog",
"link": "https://nxlog.co/community-forum",
"tier": "developer"
}
}
}

Просмотреть файл

@ -131,7 +131,7 @@
},
{
"title": "",
"description": "**3. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following five (5) application settings individually, with their respective string values (case-sensitive): \n\t\tapiToken\n\t\tworkspaceID\n\t\tworkspaceKey\n\t\turi\n\t\tlogAnalyticsUri (optional)\n - Use the following schema for the `uri` value: `https://<OktaDomain>/api/v1/logs?since=` Replace `<OktaDomain>` with your domain. [Click here](https://developer.okta.com/docs/reference/api-overview/#url-namespace) for further details on how to identify your Okta domain namespace. There is no need to add a time value to the URI, the Function App will dynamically append the inital start time of logs to UTC 0:00 for the current UTC date as time value to the URI in the proper format.\n - Note: If using Azure Key Vault secrets for any of the values above, use the`@Microsoft.KeyVault(SecretUri={Security Identifier})`schema in place of the string values. Refer to [Key Vault references documentation](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) for further details.\n - Use logAnalyticsUri to override the log analytics API endpoint for delegated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: https://<CustomerId>.ods.opinsights.azure.us. \n4. Once all application settings have been entered, click **Save**."
"description": "**3. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following five (5) application settings individually, with their respective string values (case-sensitive): \n\t\tapiToken\n\t\tworkspaceID\n\t\tworkspaceKey\n\t\turi\n\t\tlogAnalyticsUri (optional)\n - Use the following schema for the `uri` value: `https://<OktaDomain>/api/v1/logs?since=` Replace `<OktaDomain>` with your domain. [Click here](https://developer.okta.com/docs/reference/api-overview/#url-namespace) for further details on how to identify your Okta domain namespace. There is no need to add a time value to the URI, the Function App will dynamically append the inital start time of logs to UTC 0:00 for the current UTC date as time value to the URI in the proper format.\n - Note: If using Azure Key Vault secrets for any of the values above, use the`@Microsoft.KeyVault(SecretUri={Security Identifier})`schema in place of the string values. Refer to [Key Vault references documentation](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) for further details.\n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: https://<CustomerId>.ods.opinsights.azure.us. \n4. Once all application settings have been entered, click **Save**."
}
]
}

Просмотреть файл

@ -236,6 +236,21 @@
}
]
],
"metadata": {
"id": "81ae314e-2c7c-40d0-87fe-812ffda0b60c",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Onapsis"
},
"support": {
"name": "Onapsis",
"link": "https://onapsis.force.com/s/login/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -53,7 +53,7 @@
},
{
"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)",
"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": {
@ -87,5 +87,21 @@
}
]
}
]
],
"metadata": {
"id": "f664e101-f4af-4d74-809c-8fad6ee3c381",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Orca Security"
},
"support": {
"name": "Orca Security",
"link": "http://support.orca.security/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -35,7 +35,8 @@
}
],
"availability": {
"status": 1
"status": 1,
"isPreview": true
},
"permissions": {
"resourceProvider": [
@ -113,5 +114,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "ef80260c-3aec-43bc-a1e5-c2f2372c9adc",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Palo Alto Networks"
},
"support": {
"name": "Palo Alto Networks",
"link": "https://www.paloaltonetworks.com/company/contact-support",
"tier": "developer"
}
}
}

Просмотреть файл

@ -99,5 +99,21 @@
}
]
}
]
],
"metadata": {
"id": "1d855d54-0f17-43b3-ad33-93a0ab7b6ce8",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Perimeter 81"
},
"support": {
"name": "Perimeter 81",
"link": "https://support.perimeter81.com/",
"tier": "developer"
}
}
}

Двоичный файл не отображается.

Просмотреть файл

@ -12,6 +12,7 @@ import requests
import azure.functions as func
import logging
import certifi
import re
customer_id = os.environ['WorkspaceID']
@ -20,6 +21,15 @@ cluster_id = os.environ['ProofpointClusterID']
_token = os.environ['ProofpointToken']
time_delay_minutes = 60
event_types = ["maillog","message"]
logAnalyticsUri = os.environ.get('logAnalyticsUri')
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customer_id + '.ods.opinsights.azure.com'
pattern = r'https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$'
match = re.match(pattern,str(logAnalyticsUri))
if(not match):
raise Exception("ProofpointPOD: Invalid Log Analytics Uri.")
def main(mytimer: func.TimerRequest) -> None:
if mytimer.past_due:
@ -35,6 +45,7 @@ def main(mytimer: func.TimerRequest) -> None:
class Proofpoint_api:
def __init__(self):
self.cluster_id = cluster_id
self.logAnalyticsUri = logAnalyticsUri
self._token = _token
self.time_delay_minutes = int(time_delay_minutes)
self.gen_timeframe(time_delay_minutes=self.time_delay_minutes)
@ -113,7 +124,9 @@ class Proofpoint_api:
content_length = len(body)
signature = self.build_signature(rfc1123date, content_length, method, content_type,
resource)
uri = 'https://' + customer_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01'
uri = self.logAnalyticsUri + resource + '?api-version=2016-04-01'
headers = {
'content-type': content_type,
'Authorization': signature,

Двоичный файл не отображается.

Просмотреть файл

@ -9,6 +9,7 @@ import csv
import os
import sys
import tempfile
import re
import azure.functions as func
@ -25,7 +26,15 @@ interval = "hourly"
hours_interval = 1
days_interval = 1
url = "https://login.salesforce.com/services/oauth2/token"
logAnalyticsUri = os.environ.get('logAnalyticsUri')
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customer_id + '.ods.opinsights.azure.com'
pattern = r'https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$'
match = re.match(pattern,str(logAnalyticsUri))
if(not match):
raise Exception("Salesforce Service Cloud: Invalid Log Analytics Uri.")
def _get_token():
params = {
@ -175,14 +184,15 @@ def post_data(customer_id, shared_key, body, log_type, chunk_count):
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
content_length = len(body)
signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource)
uri = 'https://' + customer_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01'
uri = logAnalyticsUri + resource + '?api-version=2016-04-01'
headers = {
'content-type': content_type,
'Authorization': signature,
'Log-Type': log_type,
'x-ms-date': rfc1123date
}
response = requests.post(uri,data=body, headers=headers)
response = requests.post(uri, data=body, headers=headers)
if (response.status_code >= 200 and response.status_code <= 299):
print('Accepted')
logging.info("Chunk was processed({} events)".format(chunk_count))

Двоичные данные
DataConnectors/SlackAudit/SlackAuditAPISentinelConn.zip Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,295 @@
import requests
import json
import datetime
import azure.functions as func
import base64
import hmac
import hashlib
import os
import logging
import re
from .state_manager import StateManager
customer_id = os.environ['WorkspaceID']
shared_key = os.environ['WorkspaceKey']
slack_api_bearer_token = os.environ['SlackAPIBearerToken']
logAnalyticsUri = os.environ.get('logAnalyticsUri')
log_type = 'SlackAudit'
slack_uri_audit = "https://api.slack.com/audit/v1/logs"
offset_limit = 1000
connection_string = os.environ['AzureWebJobsStorage']
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customer_id + '.ods.opinsights.azure.com'
pattern = r"https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$"
match = re.match(pattern,str(logAnalyticsUri))
if(not match):
raise Exception("Invalid Log Analytics Uri.")
def action_mapping(event):
action_id = event["action"]
action_dict = {
"workspace_created": "A workspace in an organization was created.",
"workspace_deleted": "A workspace in an organization was deleted.",
"workspace_accepted_migration": "An administrator on a workspace has accepted an invitation to migrate to a Grid organization.",
"workspace_declined_migration": "An administrator on a workspace has declined an invitation to migrate to a Grid organization.",
"migration_scheduled": "A migration was scheduled.",
"organization_verified": "Slack has confirmed the identity of your organization. The organization will now be denoted with a verified badge.",
"organization_unverified": "Slack has flagged a change in your organizations identity and has unverified it. The organization will no longer be denoted with a verified badge.",
"organization_public_url_updated": "Your organizations public URL has been changed.",
"organization_created": "An Enterprise Grid organization was created.",
"organization_deleted": "An Enterprise Grid organization was deleted.",
"organization_accepted_migration": "The Org Owner accepted a workspace invitation to join their organization.",
"organization_declined_migration": "The Org Owner declined a workspace invitation to join their organization.",
"billing_address_added": "A billing address was added. Includes a details parameter noting the timestamp the TOS was accepted.",
"emoji_added": "An emoji was added. Includes a details parameter with the name of the emoji.",
"emoji_removed": "An emoji was removed. Includes a details parameter with the name of the emoji.",
"emoji_aliased": "An emoji was given an alias. Includes a details parameter with the name of the alias.",
"emoji_renamed": "An emoji was renamed. Includes a details parameter with the previous and new names of the emoji.",
"message_tombstoned": "A message was tombstoned.",
"message_restored": "A message was restored.",
"manual_export_started": "A workspace admin or owner has started a standard export on a workspace.",
"manual_export_completed": "A standard export on a workspace has finished.",
"corporate_exports_approved": "The corporate export feature has been approved for use on a workspace.",
"corporate_exports_enabled": "The corporate export feature has been enabled for a workspace.",
"scheduled_export_started": "A scheduled corporate export has started.",
"scheduled_export_completed": "A scheduled corporate export has finished.",
"channels_export_started": "A channel export has begun.",
"channels_export_completed": "A channel export is complete.",
"pref.allow_calls": "A preference indicating whether Slack Calls can be used in this workspace has changed.",
"pref.allow_message_deletion": "Someone altered this workspace's settings around whether messages can be deleted or not.",
"pref.app_dir_only": "Whether only Slack App Directory apps can be installed or not in this workspace has changed.",
"pref.app_whitelist_enabled": "Someone's carefully carved or culled the list of apps this workspace has whitelisted.",
"pref.can_receive_shared_channels_invites": "Whether this workspace can receive invites to share channels with other workspaces has changed.",
"pref.commands_only_regular": "The setting determining whether restricted users are restricted from using slash commands was changed.",
"pref.custom_tos": "This workspace's settings on having a custom terms of service have changed.",
"pref.disallow_public_file_urls": "This workspace has modified their public file URL settings for files uploaded within it.",
"pref.dm_retention_changed": "The direct message (DM) retention setting changed. Includes a details parameter noting the previous and new values.",
"pref.dnd_enabled": "Do not disturb settings have been enabled for a workspace.",
"pref.dnd_end_hour": "The exact ending hour for workspace do not disturb settings has been set. Work hard and go home.",
"pref.dnd_start_hour": "The exact starting hour for workspace do not disturb settings has been set. Hopefully everyone is awake and ready to work by then.",
"pref.emoji_only_admins": "Someone modified the list of emoji-administrating admins, so you know who stole the cookies from the cookie jar.",
"pref.enterprise_default_channels": "Someone modified the list of default channels across the enterprise grid.",
"pref.enterprise_team_creation_request": "Someone has requested that your organization allow a new workspace to be created.",
"pref.file_retention_changed": "The file retention setting changed. Includes a details parameter noting the previous and new values.",
"pref.msg_edit_window_mins": "Someone edited the edit messaging window for a workspace!",
"pref.private_channel_retention_changed": "The group (private channel) retention setting changed. Includes a details parameter noting the previous and new values.",
"pref.public_channel_retention_changed": "The channel retention setting type changed. Includes a details parameter noting the previous and new values.",
"pref.retention_override_changed": "The retention override setting, allowing workspace members to set their own retention period for private channels and DMs, changed. Includes a details parameter noting the previous and new values.",
"pref.sign_in_with_slack_disabled": "This workspace changed their preference around allowing Sign in with Slack.",
"pref.slackbot_responses_disabled": "The settings around whether Slackbot's witty responses are enabled or disabled changed.",
"pref.slackbot_responses_only_admins": "There's a secret cabal of admins for those witty Slackbot responses and that list was changed.",
"pref.sso_setting_changed": "The Single Sign On (SSO) restriction changed. Includes a details parameter noting the previous and new values.",
"pref.stats_only_admins": "The list of admins that can work with workspace statistics only has changed.",
"pref.two_factor_auth_changed": "The two-factor authentication requiremented changed. Includes a details parameter noting the previous and new values.",
"pref.username_policy": "A workspace's username policy preference changed.",
"pref.who_can_archive_channels": "Who can archive channels indeed?",
"pref.who_can_create_delete_user_groups": "The list of who can create or delete user groups changed.",
"pref.who_can_create_private_channels": "It's like a who's who of who can create private channels, and it changed.",
"pref.who_can_create_public_channels": "The same as above, but for public channels.",
"pref.who_can_edit_user_groups": "The list of those who can edit user groups changed.",
"pref.who_can_manage_channel_posting_prefs": "Someone's been changing who can manage channel posting preferences",
"pref.who_can_manage_ext_shared_channels": "The list of who can manage externally shared channels has changed for this workspace.",
"pref.who_can_manage_guests": "The list of who can manage guests now has changed for this workspace.",
"pref.who_can_manage_shared_channels": "Settings around who can remove users from shared channels has changed for a workspace.",
"pref.who_can_remove_from_private_channels": "Settings around who can remove users from private channels has changed for a workspace.",
"pref.who_can_remove_from_public_channels": "Settings around who can remove users from public channels has changed for a workspace.",
"ekm_enrolled": "The workspace is now enrolled/managed by EKM.",
"ekm_unenrolled": "The workspace is no longer enrolled or managed by EKM.",
"ekm_key_added": "An EKM key was added for the workspace.",
"ekm_key_removed": "An EKM key was removed for the workspace.",
"ekm_clear_cache_set": "A revocation event has triggered a new TTL for cached date in this workspace.",
"ekm_logging_config_set": "Logging settings for this workspace's EKM configuration have changed.",
"ekm_slackbot_enroll_notification_sent": "Slack sent notifications about this workspace being enrolled in EKM.",
"ekm_slackbot_unenroll_notification_sent": "Slack sent notifications about this workspace no longer being enrolled in EKM.",
"ekm_slackbot_rekey_notification_sent": "Slack sent notifications about this workspace's EKM configuration being rekeyed.",
"ekm_slackbot_logging_notification_sent": "Slack sent notifications about logging changes to EKM in this workspace.",
"user_channel_join": "A user has joined a channel. The user field in this action contains a team identifier so that you can see which team the joining user comes from (useful for externally shared channels).",
"user_channel_leave": "A user has left a channel. This action contains a team identifier so that you can see which team the departing user comes from (useful for externally shared channels).",
"guest_channel_join": "A guest user has joined a channel. This action contains a team identifier so that you can see which team the joining guest comes from (useful for externally shared channels).",
"guest_channel_leave": "A guest user has left a channel. This action contains a team identifier so that you can see which team the departing guest comes from (useful for externally shared channels).",
"guest_created": "A guest was invited to a channel. This action contains a team identifier so that you can see which team the inviting user comes from.",
"channel_moved": "A channel has been moved to a different workspace.",
"public_channel_created": "A public channel was created.",
"private_channel_created": "A private channel was created.",
"public_channel_archive": "A public channel was archived.",
"private_channel_archive": "A private channel was archived.",
"public_channel_unarchive": "A public channel was unarchived.",
"private_channel_unarchive": "A private channel was unarchived.",
"public_channel_deleted": "A public channel was deleted.",
"private_channel_deleted": "A private channel was deleted.",
"mpim_converted_to_private": "A multi-party direct message was converted to a private channel.",
"public_channel_converted_to_private": "A channel which was once public is now private.",
"channel_email_address_created": "An email forwarding address was created for a channel.",
"channel_email_address_deleted": "An email forwarding address was deleted from channel.",
"external_shared_channel_connected": "A shared channel with another workspace has been connected with this one.",
"external_shared_channel_disconnected": "A shared channel with another workspace is no longer connected with this one.",
"external_shared_channel_reconnected": "A previously connected and then disconnected shared channel with another workspace is once again shared with this one.",
"external_shared_channel_invite_sent": "An invitation to join a shared channel was sent.",
"external_shared_channel_invite_accepted": "An invitation to join a shared channel was accepted! Nice.",
"external_shared_channel_invite_approved": "An invitation to join a shared channel was approved by an admin.",
"external_shared_channel_invite_created": "An invitation url to join a shared channel was created.",
"external_shared_channel_invite_declined": "An invitation to join a shared channel was declined.",
"external_shared_channel_invite_expired": "An invitation to join a shared channel expired.",
"external_shared_channel_invite_revoked": "An invitation to join a shared channel was revoked.",
"role_change_to_owner": "A team member was made an owner.",
"role_change_to_admin": "A team member was made an admin.",
"role_change_to_user": "A team member was a user.",
"role_change_to_guest": "A team member was made a guest.",
"owner_transferred": "An owner was transferred.",
"user_created": "A team member was created.",
"user_deactivated": "A team member was deactivated.",
"user_reactivated": "A team member was reactivated after having been deactivated.",
"user_login_failed": "A team member login failed",
"guest_created": "A guest was created.",
"guest_deactivated": "A guest was deactivated.",
"guest_reactivated": "A guest was reactivated after having been deactivated.",
"guest_expiration_set": "A guest had an account expiration time set.",
"guest_expired": "A guest was deactivated when the expiration time was reached.",
"guest_expiration_cleared": "A guest had an expiration time cleared (before this time arrived).",
"user_login": "A team member logged in.",
"user_logout": "A team member logged out.",
"custom_tos_accepted": "A team member accepted a custom terms of service agreement.",
"app_approved": "On workspaces that have admin approved apps enabled, an app has been approved but not yet installed.",
"app_restricted": "On workspaces that have admin approved apps enabled, an app has been restricted and cannot be installed.",
"app_installed": "An app has been installed. If a custom integration had been disabled, this event will also be triggered if it is re-enabled.",
"app_scopes_expanded": "An app has been granted additional access to resources on a workspace, via OAuth scopes. For most apps, this requires a re-install. For workspace apps, this may also happen via the permissions API.",
"app_resources_added": "Workspace apps have the ability to request access to a specific resource on a workspace, such as a channel or a DM, including wildcard resources (such as all public channels). This event is triggered when access has been granted.",
"app_uninstalled": "A Slack app was uninstalled.",
"app_token_preserved": "An app's token was preserved instead of revoked, usually due to an app owner or installer being removed from an organization.",
"file_downloaded": "A file was downloaded.",
"file_downloaded_blocked": "A file was blocked from being downloaded.",
"file_uploaded": "A file was uploaded. This action contains a team identifier so that you can see which team the uploading user comes from (useful for externally shared channels).",
"file_public_link_created": "A public link was created for a file. This action contains a team identifier so that you can see which team the creating user comes from (useful for externally shared channels).",
"file_public_link_revoked": "A public link was revoked from a file. This action contains a team identifier so that you can see which team the revoking user comes from (useful for externally shared channels).",
"file_shared": "A file was shared in another channel.",
"workflow_created": "A workflow has been created.",
"workflow_deleted": "A workflow has been deleted.",
"workflow_published": "A workflow has been published.",
"workflow_unpublished": "A workflow has been unpublished.",
"workflow_responses_csv_download": "A user downloaded a workflows responses as a CSV file."
}
if action_id in action_dict.keys():
action_desc = action_dict[action_id]
event["action_description"] = action_desc
return event
def process_events(events_obj):
map_result = map(action_mapping, events_obj)
to_list = list(map_result)
element_count = len(to_list)
global global_element_count, oldest, latest
if element_count > 0:
post_status_code = post_data(json.dumps(to_list))
if post_status_code is not None:
global_element_count = global_element_count + element_count
def build_signature(customer_id, shared_key, date, content_length, method, content_type, resource):
x_headers = 'x-ms-date:' + date
string_to_hash = method + "\n" + str(content_length) + "\n" + content_type + "\n" + x_headers + "\n" + resource
bytes_to_hash = bytes(string_to_hash, encoding="utf-8")
decoded_key = base64.b64decode(shared_key)
encoded_hash = base64.b64encode(hmac.new(decoded_key, bytes_to_hash, digestmod=hashlib.sha256).digest()).decode()
authorization = "SharedKey {}:{}".format(customer_id,encoded_hash)
return authorization
def post_data(body):
method = 'POST'
content_type = 'application/json'
resource = '/api/logs'
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
content_length = len(body)
signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource)
uri = logAnalyticsUri + resource + '?api-version=2016-04-01'
headers = {
'content-type': content_type,
'Authorization': signature,
'Log-Type': log_type,
'x-ms-date': rfc1123date
}
response = requests.post(uri,data=body, headers=headers)
if (response.status_code >= 200 and response.status_code <= 299):
return response.status_code
else:
logging.warn("Events are not processed into Azure. Response code: {}".format(response.status_code))
return None
def get_result_request(params):
try:
r = requests.get(url=slack_uri_audit,
headers={'Accept': 'application/json',
"Authorization": "Bearer "+ slack_api_bearer_token
},
params=params)
if r.status_code == 200:
if "entries" in r.json():
result = r.json()["entries"]
if len(result) > 0:
logging.info("Processing {} events".format(len(result)))
process_events(result)
else:
logging.info("There are no entries from the output.")
#check next_page cursor
if "response_metadata" in r.json():
if "next_cursor" in r.json()["response_metadata"]:
if r.json()["response_metadata"]["next_cursor"] == "":
return None
else:
return r.json()["response_metadata"]["next_cursor"]
else:
return None
else:
return None
elif r.status_code == 401:
logging.error("The authentication credentials are incorrect or missing. Error code: {}".format(r.status_code))
elif r.status_code == 403:
logging.error("The user does not have the required permissions. Error code: {}".format(r.status_code))
else:
logging.error("Something wrong. Error code: {}".format(r.status_code))
except Exception as err:
logging.error("Something wrong. Exception error text: {}".format(err))
def generate_date():
current_time = datetime.datetime.utcnow().replace(second=0, microsecond=0) - datetime.timedelta(minutes=10)
state = StateManager(connection_string=connection_string)
past_time = state.get()
if past_time is not None:
logging.info("The last time point is: {}".format(past_time))
else:
logging.info("There is no last time point, trying to get events for last hour.")
past_time = (current_time - datetime.timedelta(minutes=60)).strftime("%s")
state.post(current_time.strftime("%s"))
return (past_time, current_time.strftime("%s"))
def main(mytimer: func.TimerRequest) -> None:
if mytimer.past_due:
logging.info('The timer is past due!')
logging.info('Starting program')
global global_element_count
global_element_count = 0
oldest, latest = generate_date()
logging.info("Start processing events to Azure Sentinel. Time period: from {} to {}.".format(datetime.datetime.fromtimestamp(int(oldest)).strftime("%Y-%m-%dT%H:%M:%SZ"),
datetime.datetime.fromtimestamp(int(latest)).strftime("%Y-%m-%dT%H:%M:%SZ")))
params = {
"limit": offset_limit,
"oldest": oldest,
"latest": latest
}
next_cursor = get_result_request(params)
while next_cursor is not None:
params = {
"limit": offset_limit,
"oldest": oldest,
"latest": latest,
"cursor": next_cursor
}
next_cursor = get_result_request(params)
logging.info("Processed {} events to Azure Sentinel. Time period: from {} to {}.".format(global_element_count, datetime.datetime.fromtimestamp(int(oldest)).strftime("%Y-%m-%dT%H:%M:%SZ"),
datetime.datetime.fromtimestamp(int(latest)).strftime("%Y-%m-%dT%H:%M:%SZ")))

Просмотреть файл

@ -0,0 +1,11 @@
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "mytimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */10 * * * *"
}
]
}

Просмотреть файл

@ -0,0 +1,22 @@
from azure.storage.fileshare import ShareClient
from azure.storage.fileshare import ShareFileClient
from azure.core.exceptions import ResourceNotFoundError
class StateManager:
def __init__(self, connection_string, share_name='funcstatemarkershare', file_path='funcstatemarkerfile'):
self.share_cli = ShareClient.from_connection_string(conn_str=connection_string, share_name=share_name)
self.file_cli = ShareFileClient.from_connection_string(conn_str=connection_string, share_name=share_name, file_path=file_path)
def post(self, marker_text: str):
try:
self.file_cli.upload_file(marker_text)
except ResourceNotFoundError:
self.share_cli.create_share()
self.file_cli.upload_file(marker_text)
def get(self):
try:
return self.file_cli.download_file().readall().decode()
except ResourceNotFoundError:
return None

Просмотреть файл

@ -0,0 +1,121 @@
{
"id": "SlackAuditAPI",
"title": "Slack Audit",
"publisher": "Slack",
"descriptionMarkdown": "The [Slack](https://slack.com) Audit data connector provides the capability to ingest [Slack Audit Records](https://api.slack.com/admins/audit-logs) events into Azure Sentinel through the REST API. Refer to [API documentation](https://api.slack.com/admins/audit-logs#the_audit_event) for more information. The connector provides ability to get events which helps to examine potential security risks, analyze your team's use of collaboration, diagnose configuration problems and more.",
"additionalRequirementBanner": "These queries and workbooks are dependent on a parser based on Kusto to work as expected. Follow the steps to use this Kusto functions alias **SlackAudit** in queries and workbooks [Follow steps to get this Kusto functions>](https://aka.ms/sentinel-SlackAuditAPI-parser).",
"graphQueries": [{
"metricName": "Total data received",
"legend": "SlackAudit_CL",
"baseQuery": "SlackAudit_CL"
}
],
"sampleQueries": [{
"description": "Slack Audit Events - All Activities.",
"query": "SlackAudit\n | sort by TimeGenerated desc"
}
],
"dataTypes": [{
"name": "SlackAudit_CL",
"lastDataReceivedQuery": "SlackAudit_CL\n | summarize Time = max(TimeGenerated)\n | where isnotempty(Time)"
}
],
"connectivityCriterias": [{
"type": "IsConnectedQuery",
"value": [
"SlackAudit_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": "REST API Credentials/permissions",
"description": "**SlackAPIBearerToken** is required for REST API. [See the documentation to learn more about API](https://api.slack.com/web#authentication). Check all [requirements and follow the instructions](https://api.slack.com/web#authentication) for obtaining credentials."
}
]
},
"instructionSteps": [{
"title": "",
"description": ">**NOTE:** This connector uses Azure Functions to connect to the Slack REST API to pull its logs into Azure Sentinel. This might result in additional data ingestion costs. Check the [Azure Functions pricing page](https://azure.microsoft.com/pricing/details/functions/) for details."
},
{
"title": "",
"description": ">**(Optional Step)** Securely store workspace and API authorization key(s) or token(s) in Azure Key Vault. Azure Key Vault provides a secure mechanism to store and retrieve key values. [Follow these instructions](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) to use Azure Key Vault with an Azure Function App."
},
{
"description": ">**NOTE:** This data connector depends on a parser based on a Kusto Function to work as expected. [Follow these steps](https://aka.ms/sentinel-SlackAuditAPI-parser) to create the Kusto functions alias, **SlackAudit**"
},
{
"title": "",
"description": "**STEP 1 - Configuration steps for the Slack API**\n\n [Follow the instructions](https://api.slack.com/web#authentication) to obtain the credentials. \n"
},
{
"title": "",
"description": "**STEP 2 - Choose ONE from the following two deployment options to deploy the connector and the associated Azure Function**\n\n>**IMPORTANT:** Before deploying the Slack Audit data connector, have the Workspace ID and Workspace Primary Key (can be copied from the following).",
"instructions": [{
"parameters": {
"fillWith": [
"WorkspaceId"
],
"label": "Workspace ID"
},
"type": "CopyableLabel"
},
{
"parameters": {
"fillWith": [
"PrimaryKey"
],
"label": "Primary Key"
},
"type": "CopyableLabel"
}
]
},
{
"title": "Option 1 - Azure Resource Manager (ARM) Template",
"description": "Use this method for automated deployment of the Slack Audit data connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-SlackAuditAPI-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n> **NOTE:** Within the same resource group, you can't mix Windows and Linux apps in the same region. Select existing resource group without Windows apps in it or create new resource group.\n3. Enter the **SlackAPIBearerToken** and deploy. \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
},
{
"title": "Option 2 - Manual Deployment of Azure Functions",
"description": "Use the following step-by-step instructions to deploy the Slack Audit data connector manually with Azure Functions (Deployment via Visual Studio Code)."
},
{
"title": "",
"description": "**1. Deploy a Function App**\n\n> **NOTE:** You will need to [prepare VS code](https://docs.microsoft.com/azure/azure-functions/functions-create-first-function-python#prerequisites) for Azure function development.\n\n1. Download the [Azure Function App](https://aka.ms/sentinel-SlackAuditAPI-functionapp) file. Extract archive to your local development computer.\n2. Start VS Code. Choose File in the main menu and select Open Folder.\n3. Select the top level folder from extracted files.\n4. Choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose the **Deploy to function app** button.\nIf you aren't already signed in, choose the Azure icon in the Activity bar, then in the **Azure: Functions** area, choose **Sign in to Azure**\nIf you're already signed in, go to the next step.\n5. Provide the following information at the prompts:\n\n\ta. **Select folder:** Choose a folder from your workspace or browse to one that contains your function app.\n\n\tb. **Select Subscription:** Choose the subscription to use.\n\n\tc. Select **Create new Function App in Azure** (Don't choose the Advanced option)\n\n\td. **Enter a globally unique name for the function app:** Type a name that is valid in a URL path. The name you type is validated to make sure that it's unique in Azure Functions. (e.g. SlackAuditXXXXX).\n\n\te. **Select a runtime:** Choose Python 3.8.\n\n\tf. Select a location for new resources. For better performance and lower costs choose the same [region](https://azure.microsoft.com/regions/) where Azure Sentinel is located.\n\n6. Deployment will begin. A notification is displayed after your function app is created and the deployment package is applied.\n7. Go to Azure Portal for the Function App configuration."
},
{
"title": "",
"description": "**2. Configure the Function App**\n\n1. In the Function App, select the Function App Name and select **Configuration**.\n2. In the **Application settings** tab, select ** New application setting**.\n3. Add each of the following application settings individually, with their respective string values (case-sensitive): \n\t\tSlackAPIBearerToken\n\t\tWorkspaceID\n\t\tWorkspaceKey\n\t\tlogAnalyticsUri (optional)\n> - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: `https://<CustomerId>.ods.opinsights.azure.us`.\n3. Once all application settings have been entered, click **Save**."
}
]
}

Просмотреть файл

@ -0,0 +1,194 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"FunctionName": {
"defaultValue": "SlackAudit",
"minLength": 1,
"maxLength": 11,
"type": "string"
},
"WorkspaceID": {
"type": "string",
"defaultValue": "<workspaceID>"
},
"WorkspaceKey": {
"type": "securestring",
"defaultValue": "<workspaceKey>"
},
"SlackAPIBearerToken": {
"type": "securestring",
"defaultValue": "<SlackAPIBearerToken>"
}
},
"variables": {
"FunctionName": "[concat(toLower(parameters('FunctionName')), uniqueString(resourceGroup().id))]",
"StorageSuffix": "[environment().suffixes.storage]",
"LogAnaltyicsUri": "[replace(environment().portal, 'https://portal', concat('https://', toLower(parameters('WorkspaceID')), '.ods.opinsights'))]"
},
"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": "[tolower(variables('FunctionName'))]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"kind": "StorageV2",
"properties": {
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [],
"ipRules": [],
"defaultAction": "Allow"
},
"supportsHttpsTrafficOnly": true,
"encryption": {
"services": {
"file": {
"keyType": "Account",
"enabled": true
},
"blob": {
"keyType": "Account",
"enabled": true
}
},
"keySource": "Microsoft.Storage"
}
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
],
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"properties": {
"cors": {
"corsRules": []
},
"deleteRetentionPolicy": {
"enabled": false
}
}
},
{
"type": "Microsoft.Storage/storageAccounts/fileServices",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]"
],
"sku": {
"name": "Standard_LRS",
"tier": "Standard"
},
"properties": {
"cors": {
"corsRules": []
}
}
},
{
"type": "Microsoft.Web/sites",
"apiVersion": "2018-11-01",
"name": "[variables('FunctionName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('FunctionName')))]",
"[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": "~3",
"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=', toLower(variables('FunctionName')),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', toLower(variables('FunctionName'))), '2019-06-01').keys[0].value, ';EndpointSuffix=',toLower(variables('StorageSuffix')))]",
"WorkspaceID": "[parameters('WorkspaceID')]",
"WorkspaceKey": "[parameters('WorkspaceKey')]",
"SlackAPIBearerToken": "[parameters('SlackAPIBearerToken')]",
"logAnalyticsUri": "[variables('LogAnaltyicsUri')]",
"WEBSITE_RUN_FROM_PACKAGE": "https://aka.ms/sentinel-SlackAuditAPI-functionapp"
}
}
]
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/azure-webjobs-hosts')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
],
"properties": {
"publicAccess": "None"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/azure-webjobs-secrets')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
],
"properties": {
"publicAccess": "None"
}
},
{
"type": "Microsoft.Storage/storageAccounts/fileServices/shares",
"apiVersion": "2019-06-01",
"name": "[concat(variables('FunctionName'), '/default/', tolower(variables('FunctionName')))]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/fileServices', variables('FunctionName'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('FunctionName'))]"
],
"properties": {
"shareQuota": 5120
}
}
]
}

Просмотреть файл

@ -0,0 +1,15 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}

Просмотреть файл

@ -0,0 +1,4 @@
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {}
}

Просмотреть файл

@ -0,0 +1,7 @@
# 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
azure-storage-file-share==12.3.0

Просмотреть файл

@ -118,5 +118,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "bbe6d9ef-2581-41b8-95b0-9d50c919d377",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "SonicWall"
},
"support": {
"name": "SonicWall",
"link": "https://www.sonicwall.com/support/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -53,7 +53,7 @@
},
{
"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)",
"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": {
@ -99,5 +99,21 @@
"title": "4. Turn on the integration",
"description": "To turn on the integration, select Enable, and then click Save.\n"
}
]
],
"metadata": {
"id": "a3646b81-9e6a-4f4b-beb1-9d2eba8ab669",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Sophos"
},
"support": {
"name": "Sophos",
"link": "https://secure2.sophos.com/en-us/support.aspx",
"tier": "developer"
}
}
}

Просмотреть файл

@ -125,5 +125,21 @@
}
]
}
]
],
"metadata": {
"id": "5040166e-9344-4b4a-b260-8f2e3539ae45",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Squadra Technologies"
},
"support": {
"name": "Squadra Technologies",
"link": "https://www.squadratechnologies.com/Contact.aspx",
"tier": "developer"
}
}
}

Просмотреть файл

@ -110,5 +110,23 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "Unique Identifier (GUID) used to identify dependencies and content from solutions or community.",
"version": "This is an optional field. Default and recommended format for kind value as **community or solutions** is string eg. \"1.0.0\" aligning with solutions which makes it easier to manage the content. Whereas, for kind value as **sourceRepository** the recommended format is numeric (eg. 1, 1.0,1.0.0, etc) aligning to ARM template best practices.",
"kind": "dataConnector",
"source": {
"kind": "source type of the content. Value must be one of these : localWorkspace | community | solution | sourceRepository",
"name": "Name of the content source. The repo name, solution name, LA workspace name etc."
},
"author": {
"name": "Name of the author. For localWorkspace it is automatically the workspace user"
},
"support": {
"tier": "Type of support for content item: microsoft | developer | community",
"name": "Name of support contact or company",
"email": "Optional: Email of support contact",
"link":"Optional: Link for support help, like to support page to open a ticket etc"
}
}
}

Просмотреть файл

@ -125,5 +125,23 @@
"title": "3. Configure the Function App",
"description": "1. In the Function App screen, click the Function App name and select **Configuration**.\n2. In the **Application settings** tab, select **+ New application setting**.\n3. Add each of the following 'x (number of)' application settings individually, under Name, with their respective string values (case-sensitive) under Value: \n\t\tapiUsername\n\t\tapipassword\n\t\tapiToken\n\t\tworkspaceID\n\t\tworkspaceKey\n\t\turi\n\t\tlogAnalyticsUri (optional)\n(add any other settings required by the Function App)\nSet the `uri` value to: `<add uri value>` \n>Note: If using Azure Key Vault secrets for any of the values above, use the`@Microsoft.KeyVault(SecretUri={Security Identifier})`schema in place of the string values. Refer to [Azure Key Vault references documentation](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) for further details.\n - Use logAnalyticsUri to override the log analytics API endpoint for dedicated cloud. For example, for public cloud, leave the value empty; for Azure GovUS cloud environment, specify the value in the following format: https://<CustomerId>.ods.opinsights.azure.us. \n4. Once all application settings have been entered, click **Save**."
}
]
],
"metadata": {
"id": "Unique Identifier (GUID) used to identify dependencies and content from solutions or community.",
"version": "This is an optional field. Default and recommended format for kind value as **community or solutions** is string eg. \"1.0.0\" aligning with solutions which makes it easier to manage the content. Whereas, for kind value as **sourceRepository** the recommended format is numeric (eg. 1, 1.0,1.0.0, etc) aligning to ARM template best practices.",
"kind": "dataConnector",
"source": {
"kind": "source type of the content. Value must be one of these : localWorkspace | community | solution | sourceRepository",
"name": "Name of the content source. The repo name, solution name, LA workspace name etc."
},
"author": {
"name": "Name of the author. For localWorkspace it is automatically the workspace user"
},
"support": {
"tier": "Type of support for content item: microsoft | developer | community",
"name": "Name of support contact or company",
"email": "Optional: Email of support contact",
"link":"Optional: Link for support help, like to support page to open a ticket etc"
}
}
}

Просмотреть файл

@ -18,7 +18,6 @@ $currentUTCtime = (Get-Date).ToUniversalTime()
# The 'IsPastDue' property is 'true' when the current function invocation is later than scheduled.
if ($Timer.IsPastDue) {
Write-Host "PowerShell timer is running late! $($Timer.ScheduledStatus.Last)"
}
# Define the application settings (environmental variables) for the Workspace ID, Workspace Key, <PROVIDER NAME APPLIANCE NAME> API Key(s) or Token, URI, and/or Other variables. Reference (https://docs.microsoft.com/azure/azure-functions/functions-reference-powershell#environment-variables)for more information
@ -116,9 +115,22 @@ Function Post-LogAnalyticsData($customerId, $sharedKey, $body, $logType)
"time-generated-field" = $TimeStampField;
}
$response = Invoke-WebRequest -Uri $logAnalyticsUri -Method $method -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing
return $response.StatusCode
try {
$response = Invoke-WebRequest -Uri $logAnalyticsUri -Method $method -ContentType $contentType -Headers $headers -Body $body -UseBasicParsing
}
catch {
Write-Error "Error during sending logs to Azure Sentinel: $_.Exception.Message"
# Exit out of context
Exit
}
if ($response.StatusCode -eq 200) {
Write-Host "Logs have been successfully sent to Azure Sentinel."
}
else {
Write-Host "Error during sending logs to Azure Sentinel. Response code : $response.StatusCode"
}
return $response.StatusCode
}
<# Use this block to post the JSON formated data into Azure Log Analytics via the Azure Log Analytics Data Collector API

Просмотреть файл

@ -37,7 +37,7 @@ def main(mytimer: func.TimerRequest) -> None:
customer_id = os.environ['workspaceId']
shared_key = os.envviron['workspaceKey']
log_type = os.envviron['tableName']
logAnalyticsUri = os.environ['logAnalyticsUri']
logAnalyticsUri = os.environ.get('logAnalyticsUri')
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customerId + '.ods.opinsights.azure.com'
@ -97,7 +97,7 @@ def post_data(customer_id, shared_key, body, log_type):
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
content_length = len(body)
signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource)
logAnalyticsUri = logAnalyticsUri + resource + "?api-version=2016-04-01"
uri = logAnalyticsUri + resource + "?api-version=2016-04-01"
headers = {
'content-type': content_type,
@ -105,12 +105,15 @@ def post_data(customer_id, shared_key, body, log_type):
'Log-Type': log_type,
'x-ms-date': rfc1123date
}
response = requests.post(logAnalyticsUri,data=body, headers=headers)
if (response.status_code >= 200 and response.status_code <= 299):
print 'Accepted'
try:
response = requests.post(uri, data=body, headers=headers)
except Exception as err:
print("Error during sending logs to Azure Sentinel: {}".format(err))
else:
print "Response code: {}".format(response.status_code)
if (response.status_code >= 200 and response.status_code <= 299):
print("logs have been successfully sent to Azure Sentinel.")
else:
print("Error during sending logs to Azure Sentinel. Response code: {}".format(response.status_code))
/* Use this block to post the JSON formated data into Azure Log Analytics via the Azure Log Analytics Data Collector API

Просмотреть файл

@ -89,5 +89,23 @@
}
]
}
]
],
"metadata": {
"id": "Unique Identifier (GUID) used to identify dependencies and content from solutions or community.",
"version": "This is an optional field. Default and recommended format for kind value as **community or solutions** is string eg. \"1.0.0\" aligning with solutions which makes it easier to manage the content. Whereas, for kind value as **sourceRepository** the recommended format is numeric (eg. 1, 1.0,1.0.0, etc) aligning to ARM template best practices.",
"kind": "dataConnector",
"source": {
"kind": "source type of the content. Value must be one of these : localWorkspace | community | solution | sourceRepository",
"name": "Name of the content source. The repo name, solution name, LA workspace name etc."
},
"author": {
"name": "Name of the author. For localWorkspace it is automatically the workspace user"
},
"support": {
"tier": "Type of support for content item: microsoft | developer | community",
"name": "Name of support contact or company",
"email": "Optional: Email of support contact",
"link":"Optional: Link for support help, like to support page to open a ticket etc"
}
}
}

Просмотреть файл

@ -106,5 +106,23 @@
}
]
}
]
],
"metadata": {
"id": "Unique Identifier (GUID) used to identify dependencies and content from solutions or community.",
"version": "This is an optional field. Default and recommended format for kind value as **community or solutions** is string eg. \"1.0.0\" aligning with solutions which makes it easier to manage the content. Whereas, for kind value as **sourceRepository** the recommended format is numeric (eg. 1, 1.0,1.0.0, etc) aligning to ARM template best practices.",
"kind": "dataConnector",
"source": {
"kind": "source type of the content. Value must be one of these : localWorkspace | community | solution | sourceRepository",
"name": "Name of the content source. The repo name, solution name, LA workspace name etc."
},
"author": {
"name": "Name of the author. For localWorkspace it is automatically the workspace user"
},
"support": {
"tier": "Type of support for content item: microsoft | developer | community",
"name": "Name of support contact or company",
"email": "Optional: Email of support contact",
"link":"Optional: Link for support help, like to support page to open a ticket etc"
}
}
}

Просмотреть файл

@ -120,5 +120,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "c4c9c58b-d659-49af-a11e-2d5d7bd8ccc8",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Thycotic"
},
"support": {
"name": "Thycotic",
"link": "https://thycotic.com/support/",
"tier": "developer"
}
}
}

Двоичный файл не отображается.

Просмотреть файл

@ -14,6 +14,7 @@ import hmac
import hashlib
import sys
import os
import re
import azure.functions as func
def main(mytimer: func.TimerRequest) -> None:
@ -39,6 +40,15 @@ api_id = os.environ ['api_key']
regioncode = os.environ ['regioncode']
url_base = region[regioncode]
log_type = 'TrendMicro_XDR'
logAnalyticsUri = os.environ.get('logAnalyticsUri')
if ((logAnalyticsUri in (None, '') or str(logAnalyticsUri).isspace())):
logAnalyticsUri = 'https://' + customer_id + '.ods.opinsights.azure.com'
pattern = r'https:\/\/([\w\-]+)\.ods\.opinsights\.azure.([a-zA-Z\.]+)$'
match = re.match(pattern,str(logAnalyticsUri))
if(not match):
raise Exception("Trend Micro: Invalid Log Analytics Uri.")
#Get List of Events
def getWorkbenchList():
@ -107,7 +117,7 @@ def post_data(customer_id, shared_key, body, log_type, workbencheIds):
rfc1123date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
content_length = len(body)
signature = build_signature(customer_id, shared_key, rfc1123date, content_length, method, content_type, resource)
uri = 'https://' + customer_id + '.ods.opinsights.azure.com' + resource + '?api-version=2016-04-01'
uri = logAnalyticsUri + resource + '?api-version=2016-04-01'
headers = {
'content-type': content_type,
@ -116,7 +126,7 @@ def post_data(customer_id, shared_key, body, log_type, workbencheIds):
'x-ms-date': rfc1123date
}
response = requests.post(uri,data=body, headers=headers)
response = requests.post(uri, data=body, headers=headers)
if (response.status_code >= 200 and response.status_code <= 299):
print ('Accepted ' + workbencheIds)
#Uncomment for easy troublshooting of log posting to Sentinel
@ -150,3 +160,4 @@ def function():
a += 1
return status

Просмотреть файл

@ -130,5 +130,21 @@
"title": "Azure Resource Manager (ARM) Template Deployment",
"description": "This method provides an automated deployment of the Trend Micro XDR connector using an ARM Tempate.\n\n1. Click the **Deploy to Azure** button below. \n\n\t[![Deploy To Azure](https://aka.ms/deploytoazurebutton)](https://aka.ms/sentinel-trendmicroxdr-azuredeploy)\n2. Select the preferred **Subscription**, **Resource Group** and **Location**. \n3. Enter a unique **Function Name**, **Workspace ID**, **Workspace Key**, **API Token** and **Region Code**. \n - Note: Provide the appropriate region code based on where your Trend Micro XDR instance is deployed: us, eu, au, in, sg, jp \n - Note: If using Azure Key Vault secrets for any of the values above, use the`@Microsoft.KeyVault(SecretUri={Security Identifier})`schema in place of the string values. Refer to [Key Vault references documentation](https://docs.microsoft.com/azure/app-service/app-service-key-vault-references) for further details. \n4. Mark the checkbox labeled **I agree to the terms and conditions stated above**. \n5. Click **Purchase** to deploy."
}
]
],
"metadata": {
"id": "61d3a450-20c0-4f0e-9209-b8cf41d9a774",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Trend Micro"
},
"support": {
"name": "Trend Micro",
"link": "https://success.trendmicro.com/technical-support",
"tier": "developer"
}
}
}

Просмотреть файл

@ -52,7 +52,8 @@
}
],
"availability": {
"status": 1
"status": 1,
"isPreview": true
},
"permissions": {
"resourceProvider": [
@ -130,5 +131,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "abf0937a-e5be-4587-a805-fd5dbcffd6cd",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Trend Micro"
},
"support": {
"name": "Trend Micro",
"link": "https://success.trendmicro.com/technical-support",
"tier": "developer"
}
}
}

Просмотреть файл

@ -126,5 +126,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "78cd5319-f6b0-4428-be45-5dea94c8ec83",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Trend Micro"
},
"support": {
"name": "Trend Micro",
"link": "https://success.trendmicro.com/technical-support",
"tier": "developer"
}
}
}

Просмотреть файл

@ -126,5 +126,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "4c0776c2-a5dc-419d-8cf7-81c2484448d2",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "WireX Systems"
},
"support": {
"name": "WireX Systems",
"email": "support@wirexsystems.com",
"tier": "developer"
}
}
}

Просмотреть файл

@ -1,5 +1,5 @@
{
"id": "Zimperium_MTD_Alerts",
"id": "ZimperiumMtdAlerts",
"title": "Zimperium Mobile Threat Defense",
"publisher": "Zimperium",
"descriptionMarkdown": "Zimperium Mobile Threat Defense connector gives you the ability to connect the Zimperium threat log with Azure Sentinel to view dashboards, create custom alerts, and improve investigation. This gives you more insight into your organization's mobile threat landscape and enhances your security operation capabilities.",
@ -61,15 +61,14 @@
},
{
"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)",
"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":""
]
},
"instructionSteps": [
{
@ -96,5 +95,21 @@
}
]
}
]
],
"metadata": {
"id": "26bcf619-26b2-44aa-a7ad-212da52deeb8",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Zimperium"
},
"support": {
"name": "Zimperium",
"link": "https://www.zimperium.com/support",
"tier": "developer"
}
}
}

Просмотреть файл

@ -103,5 +103,21 @@
}
]
}
]
],
"metadata" : {
"id": "ffaeb3c2-6c9a-4d55-8852-e13da1162ec6",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Alcide"
},
"support": {
"name": "Alcide",
"link": "https://www.alcide.io/company/contact-us/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -114,5 +114,21 @@
"title": "4. Secure your machine ",
"description": "Make sure to configure the machine's security according to your organization's security policy\n\n\n[Learn more >](https://aka.ms/SecureCEF)"
}
]
],
"metadata": {
"id": "aa770f1e-4d05-477a-8dc1-b893772f3a46",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Illusive Networks"
},
"support": {
"name": "Illusive Networks",
"link": "https://www.illusivenetworks.com/technical-support/",
"tier": "developer"
}
}
}

Просмотреть файл

@ -125,5 +125,21 @@
}
]
}
]
],
"metadata": {
"id": "afbf6c4a-7190-442a-a649-5c18a907ceb3",
"version": "1.0.0",
"kind": "dataConnector",
"source": {
"kind": "community"
},
"author": {
"name": "Barracuda Networks"
},
"support": {
"name": "Barracuda Networks",
"link": "https://www.barracuda.com/support",
"tier": "developer"
}
}
}

Просмотреть файл

@ -0,0 +1,20 @@
id: 25e0b2dd-3ad3-4d5b-80dd-720f4ef0f12c
name: Alsid DCShadow
description: |
'Searches for DCShadow attacks'
severity: High
requiredDataConnectors:
- connectorId: AlsidForAD
dataTypes:
- AlsidForADLog_CL
queryFrequency: 2h
queryPeriod: 2h
triggerOperator: gt
triggerThreshold: 0
tactics:
- DefenseEvasion
relevantTechniques:
- T1207
query: |
afad_parser
| where MessageType == 2 and Codename == "DCShadow"

Просмотреть файл

@ -0,0 +1,20 @@
id: d3c658bd-8da9-4372-82e4-aaffa922f428
name: Alsid DCSync
description: |
'Searches for DCSync attacks'
severity: High
requiredDataConnectors:
- connectorId: AlsidForAD
dataTypes:
- AlsidForADLog_CL
queryFrequency: 2h
queryPeriod: 2h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1003.006
query: |
afad_parser
| where MessageType == 2 and Codename == "DCSync"

Просмотреть файл

@ -0,0 +1,20 @@
id: 21ab3f52-6d79-47e3-97f8-ad65f2cb29fb
name: Alsid Golden Ticket
description: |
'Searches for Golden Ticket attacks'
severity: High
requiredDataConnectors:
- connectorId: AlsidForAD
dataTypes:
- AlsidForADLog_CL
queryFrequency: 2h
queryPeriod: 2h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1558.001
query: |
afad_parser
| where MessageType == 2 and Codename == "Golden Ticket"

Просмотреть файл

@ -0,0 +1,28 @@
id: 3caa67ef-8ed3-4ab5-baf2-3850d3667f3d
name: Alsid Indicators of Attack
description: |
'Searches for triggered Indicators of Attack'
severity: Low
requiredDataConnectors:
- connectorId: AlsidForAD
dataTypes:
- AlsidForADLog_CL
queryFrequency: 2h
queryPeriod: 2h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
relevantTechniques:
- T1110
query: |
let SeverityTable=datatable(Severity:string,Level:int) [
"low", 1,
"medium", 2,
"high", 3,
"critical", 4
];
afad_parser
| where MessageType == 2
| lookup kind=leftouter SeverityTable on Severity
| order by Level

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше