diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..b242572e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/MDEOnboardedDevices-OpenAPISpec.yaml b/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/MDEOnboardedDevices-OpenAPISpec.yaml new file mode 100644 index 00000000..ed43098f --- /dev/null +++ b/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/MDEOnboardedDevices-OpenAPISpec.yaml @@ -0,0 +1,101 @@ +openapi: 3.0.0 + +# This section provides metadata about the plugin, including its title, description, and version. +info: + title: Retrieve devices onboarded into Microsoft Defender for Endpoint (MDE) + description: Plugin to retrieve a list of devices onboarded into Microsoft Defender for Endpoint (MDE) using Microsoft Graph API. + version: 1.0.0 + +# Defines the base URL for the Microsoft Graph API, which is used to make requests. +servers: + - url: https://graph.microsoft.com/v1.0 + description: Microsoft Graph API url + +# Specifies the available API endpoints and their operations, in this case, retrieving a list of devices. +paths: + /devices: + get: + summary: Get devices + description: Retrieve a list of devices onboarded into Microsoft Defender for Endpoint + responses: + '200': + description: List of devices + content: + application/json: + schema: + type: object + properties: + value: + type: array + items: + type: object + properties: + id: + type: string + description: Device ID. + deviceName: + type: string + description: Name of the device. + osPlatform: + type: string + description: Operating system of the device. + complianceState: + type: string + description: Compliance state of the device. + lastSeenDateTime: + type: string + format: date-time + description: Last seen date and time. + onboardedDate: + type: string + format: date + description: Date the device was onboarded. + manufacturer: + type: string + description: Manufacturer of the device. + model: + type: string + description: Model of the device. + serialNumber: + type: string + description: Serial number of the device. + macAddress: + type: string + description: MAC address of the device. + ipAddress: + type: string + description: IP address of the device. + isAzureAdJoined: + type: boolean + description: Indicates if the device is Azure AD joined. + isCompliant: + type: boolean + description: Indicates if the device is compliant. + riskLevel: + type: string + description: Risk level assigned to the device. + '401': + description: Unauthorized error. + '403': + description: Forbidden access. + '500': + description: Internal server error. + +# Defines security mechanisms, such as authentication methods, that the API uses. +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + +security: + - bearerAuth: [] + +# Provides example natural language queries that users can use to interact with the API via Security Copilot and retrieve specific device information. +x-example-prompts: + - Retrieve devices onboarded to MDE that have a compliance state of 'Non-compliant' + - Get the list of non-compliant devices from devices onboarded to MDE + - retrieve a list of devices onboarded onto MDE that have a Risk Level of "High" + - Retrieve devices from MDE that registered less than 14 days ago from today + - Retrieve a list of MDE endpoints that were last seen less than 1 day ago + - Get devices from MDE that have the IoS operating system diff --git a/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/MDEOnboardedDevicesPlugin.yaml b/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/MDEOnboardedDevicesPlugin.yaml new file mode 100644 index 00000000..36e2dc79 --- /dev/null +++ b/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/MDEOnboardedDevicesPlugin.yaml @@ -0,0 +1,13 @@ +Descriptor: + Name: RetrieveMDEOnboardedDevices + DisplayName: Retrieve details for devices onboarded onto Microsoft Defender for Endpoint (MDE) + Description: Retrieve details for devices onboarded onto Microsoft Defender for Endpoint (MDE) + DescriptionForModel: Retrieves detailed information about devices onboarded into Microsoft Defender for Endpoint (MDE),including device name, operating system, compliance state, risk level, last seen timestamp,onboarded date, manufacturer, model, serial number, IP address, MAC address, and Azure AD join status.This API enables security analysts to assess device security posture, identify non-compliant or high-risk devices,and correlate endpoint data with ongoing security incidents. Results provide actionable insights for threat detection, response, and asset visibility within enterprise environments, supporting Security Copilot in enhancing situational awareness and proactive threat mitigation. + + Authorization: + Type: AADDelegated + EntraScopes: https://graph.microsoft.com/.default +SkillGroups: + - Format: API + Settings: + OpenApiSpecUrl: https://gist.githubusercontent.com/inwafula/88a0e5b5f3a2bdc1840771b97937d8f0/raw/ff2211080321d6e74881ab960d9c2e0f060f3e28/MDEOnboardedDevices-OpenAPISpec.yaml \ No newline at end of file diff --git a/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/Readme.md b/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/Readme.md new file mode 100644 index 00000000..b0fc1399 --- /dev/null +++ b/Plugins/Community Based Plugins/Microsoft Graph API plugins/Devices Onboarded into MDE/Readme.md @@ -0,0 +1,36 @@ +# Plugin to retrieve Devices Onboarded into Microsoft Defender for Endpoint (MDE) Plugin + +## Overview +This plugin enables users to retrieve a list of devices onboarded into **Microsoft Defender for Endpoint (MDE)** using the **Microsoft Graph API**. It provides valuable insights into device details, compliance status, risk levels, and more, facilitating security monitoring and incident response. + +## Features +- Retrieves device details including **device name, OS, manufacturer, model, serial number, and MAC address**. +- Identifies **compliance state** and **risk level** of onboarded devices. +- Fetches devices based on **last seen date** +- Supports filtering for devices based on **Azure AD join status, compliance status, and OS platform**. + +## API Endpoint +**Base URL:** `https://graph.microsoft.com/v1.0` + + +### Setup instructions +#### Upload the Plugin manifest + +1. Obtain the manifest [MDEOnboardedDevicesPlugin.yaml](https://github.com/Azure/Copilot-For-Security/blob/main/Plugins/Community%20Based%20Plugins/Microsoft%20Graph%20API%20/Devices%20Onboarded%20into%20MDE/MDEOnboardedDevicesPlugin.yaml) and the OpenAPI Specification [MDEOnboardedDevices-OpenAPISpec.yaml](https://github.com/Azure/Copilot-For-Security/blob/main/Plugins/Community%20Based%20Plugins/Microsoft%20Graph%20API%20/Devices%20Onboarded%20into%20MDE/MDEOnboardedDevices-OpenAPISpec.yaml) files from this directory. +2. Download the Spec file and move it to your preferred location, ensuring it is reachable by Security Copilot + + +3. [Upload the custom plugin](https://learn.microsoft.com/en-us/security-copilot/manage-plugins?tabs=securitycopilotplugin#add-custom-plugins) + +## Example Natural Language Queries +Use these sample prompts to retrieve relevant data via **Security Copilot**: +- "Retrieve devices onboarded to MDE that have a compliance state of 'Non-compliant'" +- "Get the list of non-compliant devices from devices onboarded to MDE" +- "Retrieve a list of devices onboarded onto MDE that have a Risk Level of 'High'" +- "Retrieve devices from MDE that registered less than 14 days ago from today" +- "Retrieve a list of MDE endpoints that were last seen less than 1 day ago" +- "Get devices from MDE that have the iOS operating system" + + +--- +For more details, visit the **[Microsoft Graph API documentation](https://learn.microsoft.com/en-us/graph/)**. diff --git a/Plugins/Community Based Plugins/Microsoft Security Experts/Microsoft Defender Experts Plugin/Dexplugin.yaml b/Plugins/Community Based Plugins/Microsoft Security Experts/Microsoft Defender Experts Plugin/Dexplugin.yaml index 05b597a0..de1d5613 100644 --- a/Plugins/Community Based Plugins/Microsoft Security Experts/Microsoft Defender Experts Plugin/Dexplugin.yaml +++ b/Plugins/Community Based Plugins/Microsoft Security Experts/Microsoft Defender Experts Plugin/Dexplugin.yaml @@ -1,3 +1,4 @@ +--- Descriptor: Name: MicrosoftDefenderExpertsPlugin DisplayName: Microsoft Defender Experts Security Copilot Plugin @@ -7,6 +8,7 @@ Descriptor: SkillGroups: - Format: KQL Skills: + - Name: DEX-SuspiciousUseOfAzureHound DisplayName: Suspicious Use of AzureHound Description: Detects potential suspicious usage of AzureHound on devices. @@ -21,7 +23,6 @@ SkillGroups: | where TimeGenerated > ago({{days}}d) | where FileName has "azurehound.exe" | where ProcessCommandLine has "azurehound" and ProcessCommandLine has_any ("az-rm", "az-ad", "list", "Invoke-azurehound") - - Name: DEX-ReconnaissanceActivityUsingNetworkLogs DisplayName: Reconnaissance Activity Using Network Logs Description: Detects reconnaissance activity leveraging network logs and specific URLs. @@ -42,7 +43,7 @@ SkillGroups: - Name: DEX-RoadreconAndRoadtxActivity DisplayName: ROADrecon and ROADtx Activity - Description: Detects known filenames and command line activity associated with ROADrecon and ROADtx tools. + Description: Detects known filenames and command line activity associated with ROADrecon and roadtx tools. Inputs: - Name: days Description: Look back x amount of days, for example 10, 20, 30. @@ -269,8 +270,8 @@ SkillGroups: Template: |- DeviceFileEvents | where TimeGenerated > ago({{days}}d) - | where InitiatingProcessFileName =~ 'ping.exe' and InitiatingProcessCommandLine == 'ping.exe -t 127.0.0.1' - and InitiatingProcessParentFileName in~('msra.exe', 'mobsync.exe') and FolderPath endswith ".eml" + | where InitiatingProcessFileName =~ "ping.exe" and InitiatingProcessCommandLine == "ping.exe -t 127.0.0.1" + and InitiatingProcessParentFileName in~ ("msra.exe", "mobsync.exe") and FolderPath endswith ".eml" - Name: DEX-QakbotReconnaissanceActivities DisplayName: Qakbot Reconnaissance Activities Detection @@ -286,8 +287,8 @@ SkillGroups: | where TimeGenerated > ago({{days}}d) | where InitiatingProcessFileName == InitiatingProcessCommandLine | where ProcessCommandLine has_any ( - "whoami /all","cmd /c set","arp -a","ipconfig /all","net view /all","nslookup -querytype=ALL -timeout=10", - "net share","route print","netstat -nao","net localgroup") + "whoami /all", "cmd /c set", "arp -a", "ipconfig /all", "net view /all", "nslookup -querytype=ALL -timeout=10", + "net share", "route print", "netstat -nao", "net localgroup") | summarize dcount(FileName), make_set(ProcessCommandLine) by DeviceId, bin(Timestamp, 1d), InitiatingProcessFileName, InitiatingProcessCommandLine | where dcount_FileName >= 8 @@ -333,13 +334,13 @@ SkillGroups: Template: |- DeviceProcessEvents | where TimeGenerated > ago({{days}}d) - | where InitiatingProcessFileName =~ 'wmiprvse.exe' - | where FileName =~ 'powershell.exe' - and (ProcessCommandLine hasprefix '-e' or ProcessCommandLine contains 'frombase64') - | where ProcessCommandLine matches regex '[A-Za-z0-9+/]{50,}[=]{0,2}' - | where ProcessCommandLine !has 'Windows\\CCM\\' + | where InitiatingProcessFileName =~ "wmiprvse.exe" + | where FileName =~ "powershell.exe" + and (ProcessCommandLine hasprefix "-e" or ProcessCommandLine contains "frombase64") + | where ProcessCommandLine matches regex "[A-Za-z0-9+/]{50,}[=]{0,2}" + | where ProcessCommandLine !has "Windows\\CCM\\" | project DeviceId, Timestamp, InitiatingProcessId, InitiatingProcessFileName, ProcessId, FileName, ProcessCommandLine - + - Name: DEX-AutomatedEmailNotificationsAndSuspiciousSignInActivity DisplayName: Automated Email Notifications and Suspicious Sign-In Activity Detection Description: Correlates automated email notifications with suspicious sign-in activity to identify potential compromises. @@ -439,6 +440,202 @@ SkillGroups: | summarize dcount(UserSharedWith) by FileShared, AccountObjectId | where dcount_UserSharedWith >= 20 + - Name: DEX-TeamsActivityAfterSuspiciousRMM + DisplayName: Teams Activity After Suspicious RMM + Description: Detects Teams activity followed by suspicious Remote Monitoring and Management + Inputs: + - Name: days + Description: Look back x amount of days, for example 10, 20, 30. + Required: true + Settings: + Target: Defender + Template: |- + let interestingUsers = DeviceProcessEvents + | where Timestamp > ago(1h) + | where isnotempty(InitiatingProcessAccountObjectId) + | where FileName has_any ("quickassist.exe", "anydesk.exe", "teamviewer_service.exe") // Multiple RMM tools can be abused here + | project InitiatingProcessAccountUpn; + CloudAppEvents + | where Timestamp > ago(1d) + | where Application == "Microsoft Teams" + | where ActionType == "ChatCreated" + | where isempty(AccountObjectId) + | where RawEventData.ParticipantInfo.HasForeignTenantUsers == true + | where RawEventData.CommunicationType == "OneOnOne" + | where RawEventData.ParticipantInfo.HasGuestUsers == false + | where RawEventData.ParticipantInfo.HasOtherGuestUsers == false + | where AccountId has "@" + | extend TargetUPN = tolower(tostring(RawEventData.Members[1].UPN)) + | where TargetUPN in (interestingUsers) + | extend VictimTenant = tostring(RawEventData.OrganizationId) + | extend AttackerTenant = RawEventData.Members[0].OrganizationId + | extend AttackerUPN = RawEventData.Members[0].UPN + | extend AttackerName = RawEventData.Members[0].DisplayName + + - Name: DEX-TeamsPhishingviaUrlClickEvents + DisplayName: Teams Phishing via Url Click Events + Description: Correlate suspicious device alerts with URL click events in MS Teams. + Inputs: + - Name: days + Description: Look back x amount of days, for example 10, 20, 30. + Required: true + Settings: + Target: Defender + Template: |- + let alertedDevices = AlertEvidence + | where Timestamp > ago(1h) + | where isnotempty(DeviceId) + | distinct DeviceId; + let interestedUsers = DeviceProcessEvents + | where Timestamp > ago(1h) + | where DeviceId in (alertedDevices) + | where isnotempty(InitiatingProcessAccountUpn) + | distinct InitiatingProcessAccountUpn; + UrlClickEvents + | where Timestamp > ago(1d) + | where ActionType == "ClickAllowed" or IsClickedThrough != "0" + | where Workload has "Teams" + | where AccountUpn in (interestedUsers) + + - Name: DEX-TeamsAdversary-in-The-Middle(AiTM) + DisplayName: TeamsAdversary-in-The-Middle(AiTM) + Description: Correlate risky sign-in attempts with Teams phishing from external tenants to identify AiTM. + Inputs: + - Name: days + Description: Look back x amount of days, for example 10, 20, 30. + Required: true + Settings: + Target: Defender + Template: |- + let usersWithRiskySignIn = AADSignInEventsBeta + | where Timestamp > ago(1h) + | where RiskLevelDuringSignIn == 100 + | project AccountUpn; + CloudAppEvents + | where Timestamp > ago(1d) + | where Application == "Microsoft Teams" + | where ActionType == "ChatCreated" + | where isempty(AccountObjectId) + | where RawEventData.ParticipantInfo.HasForeignTenantUsers == true + | where RawEventData.CommunicationType == "OneOnOne" + | where RawEventData.ParticipantInfo.HasGuestUsers == false + | where RawEventData.ParticipantInfo.HasOtherGuestUsers == false + | where AccountId has "@" + | extend TargetUPN = tolower(tostring(RawEventData.Members[1].UPN)) + | where TargetUPN in (usersWithRiskySignIn) + | extend TargetTenant = tostring(RawEventData.OrganizationId) + | extend AttackerTenant = RawEventData.Members[0].OrganizationId + | where TargetTenant != AttackerTenant + | extend AttackerUPN = RawEventData.Members[0].UPN + | extend AttackerName = RawEventData.Members[0].DisplayName + | project-reorder Timestamp, AttackerTenant, AttackerUPN, AttackerName, TargetUPN + + - Name: DEX-SuspiciousFileDownloadsviaLOLBINs + DisplayName: Suspicious File Downloads via LOLBINs + Description: Detects Living-off-the-Land Binaries (LOLBINs) commonly used by adversaries to download additional payloads. + Inputs: + - Name: days + Description: Look back x amount of days, for example 10, 20, 30. + Required: true + Settings: + Target: Defender + Template: |- + DeviceNetworkEvents + | where TimeGenerated > ago({{days}}d) + | where InitiatingProcessFileName in~ ("curl.exe", "powershell.exe", "certutil.exe", "bitsadmin.exe") + | where RemoteIPType == "Public" + | where RemoteUrl endswith ".exe" or RemoteUrl endswith ".dll" or RemoteUrl endswith ".zip" + | project Timestamp, DeviceId, InitiatingProcessFileName, RemoteIP, RemoteUrl + | extend AlertType = "Suspicious file download from unknown IP address" + + - Name: DEX-CSVDEDownloadandADEnumeration + DisplayName: CSVDE Download and AD Enumeration + Description: Detects the download and execution of Csvde, a command-line tool that can be exploited by adversaries to extract sensitive data from AD DS or introduce malicious entries. + Inputs: + - Name: days + Description: Look back x amount of days, for example 10, 20, 30. + Required: true + Settings: + Target: Defender + Template: |- + // Detect curl downloading csvde.exe + let csvde_download = DeviceProcessEvents + | where InitiatingProcessFileName =~ "cmd.exe" + | where ProcessCommandLine has_all ("curl", "-o", "csvde.exe", "http:") + | project DeviceId, Timestamp, CurlCommandLine = ProcessCommandLine, CurlProcessId = ProcessId; + // Detect execution of csvde.exe with specific parameters + let csvde_execution = DeviceProcessEvents + | where FileName =~ "csvde.exe" + | where ProcessCommandLine has_all ("-r", "objectClass=Computer") + | where ProcessCommandLine has_all ("-l", "samAccountName", "description", "info", "operatingSystem") + | where ProcessCommandLine contains "-f" + | project DeviceId, Timestamp, CsvdeCommandLine = ProcessCommandLine, CsvdeProcessId = ProcessId; + // Join the two events and look for them occurring within 5 minutes + csvde_download + | join kind=inner (csvde_execution) on DeviceId + | where Timestamp between (Timestamp1 .. Timestamp1 + 5m) + | extend AlertType = "Potential Active Directory Enumeration", Details = strcat("curl.exe was used to download csvde.exe, which was then executed to enumerate AD computers.") + + - Name: DEX-DataCompressionandExfiltration + DisplayName: Data Compression and Exfiltration + Description: Detects the use of 7-Zip for extracting files with a password and joins that process with network events to identify exfiltration of data. + Inputs: + - Name: days + Description: Look back x amount of days, for example 10, 20, 30. + Required: true + Settings: + Target: Defender + Template: |- + // Detect potential data compression and exfiltration + let compress_exfil = DeviceProcessEvents + | where FileName =~ "7z.exe" + | where ProcessCommandLine contains "x -p" + | project Timestamp, DeviceId, FileName, ProcessCommandLine, ProcessId + | join kind=inner ( + DeviceNetworkEvents + | where InitiatingProcessId != 0 + ) on $left.ProcessId == $right.InitiatingProcessId + | project Timestamp, DeviceId, FileName, ProcessCommandLine, RemoteIP, RemotePort + | extend AlertType = "Potential data compression and exfiltration"; + + - Name: DEX-PersistenceThroughStartupOperations + DisplayName: Persistence Through Startup Operations + Description: Detects adversary payloads used to create persistence via ASEP Registry Keys, Startup Folder, or Scheduled Tasks. + Inputs: + - Name: days + Description: Look back x amount of days, for example 10, 20, 30. + Required: true + Settings: + Target: Defender + Template: |- + // Persistence through Startup operations + let regKeys = pack_array(@"CurrentVersion\Run", + @"CurrentVersion\RunOnce", + @"CurrentVersion\RunOnceEx", + @"Programs\Startup", + @"CurrentVersion\RunServicesOnce", + @"CurrentVersion\RunServices", + @"CurrentVersion\Policies\Explorer\Run", + @"Windows NT\CurrentVersion\Windows", + @"System\CurrentControlSet\Control\Session Manager"); + let startUpOperations = DeviceFileEvents + | where FolderPath has @"Start Menu\Programs\Startup\" + | where ActionType in ("FileCreated", "FileModified", "FileRenamed"); + // Persistence through Registry Tampering + let regOperations = DeviceRegistryEvents + | where hasAlertDevices + | where Timestamp between (startTime .. endTime) + | where DeviceId in (alertedDevices) + | where RegistryKey has_any (regKeys) + | where ActionType in ("SetValue", "CreateKey", "RenameKey"); + // Persistence through Scheduled task creation + let scheduledOperations = DeviceProcessEvents + | where Timestamp between (startTime .. endTime) + | where DeviceId in (alertedDevices) + | where (InitiatingProcessCommandLine has "schtasks" and InitiatingProcessCommandLine has_any ("run", "create", "change")); + union startUpOperations, regOperations, scheduledOperations + | summarize arg_min(Timestamp, *) by DeviceId + - Name: DEX-PossibleAiTMPhishingAttemptAgainstEntraID DisplayName: Possible AiTM Phishing Attempt Against Entra ID Description: | @@ -566,3 +763,157 @@ SkillGroups: | extend UEBARiskScore = IPInvestigationPriority | where UEBARiskScore > {{riskScoreCutoff}} | sort by UEBARiskScore desc + - Name: DEX-BrowserRemoteDebugging + DisplayName: Browser Remote Debugging + Description: Identifies AutoIT scripts launching Chromium-based browsers (e.g., chrome.exe, msedge.exe, brave.exe) in remote debugging mode. + Inputs: + - Name: timeframe + Description: Time frame to search (e.g., "1h", "2h", "4h"). + Required: true + Settings: + Target: Defender + Template: |- + DeviceProcessEvents + | where TimeGenerated > ago({{timeframe}}) + | where InitiatingProcessVersionInfoInternalFileName == "AutoIt3.exe" + | where ProcessCommandLine has "--remote-debugging-port" + | project DeviceId, Timestamp, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessFolderPath, InitiatingProcessVersionInfoInternalFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine + + - Name: DEX-DPAPI-AutoIT + DisplayName: DPAPI Decryption via AutoIT + Description: Identifies DPAPI decryption activity originating from AutoIT scripts. + Inputs: + - Name: timeframe + Description: Time frame to search (e.g., "1h", "2h"). + Required: true + Settings: + Target: Defender + Template: |- + DeviceEvents + | where Timestamp > ago({{timeframe}}) + | where ActionType == "DpapiAccessed" + | where InitiatingProcessVersionInfoInternalFileName == "AutoIt3.exe" + | where (AdditionalFields has_any ("Google Chrome", "Microsoft Edge") and AdditionalFields has_any ("SPCryptUnprotect")) + | extend json = parse_json(AdditionalFields) + | extend dataDesp = tostring(json.DataDescription.PropertyValue) + | extend opType = tostring(json.OperationType.PropertyValue) + | where (dataDesp in~ ("Google Chrome", "Microsoft Edge") and opType =~ "SPCryptUnprotect") + | project Timestamp, ReportId, DeviceId, ActionType, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessVersionInfoInternalFileName, InitiatingProcessCommandLine, AdditionalFields, dataDesp, opType + + - Name: DEX-DPAPI-LOLBAS + DisplayName: DPAPI Decryption via LOLBAS Binaries + Description: Identifies DPAPI decryption activity originating from LOLBAS binaries such as RegAsm.exe and MSBuild.exe. + Inputs: + - Name: timeframe + Description: Time frame to search (e.g., "1h", "2h"). + Required: true + Settings: + Target: Defender + Template: |- + DeviceEvents + | where Timestamp > ago({{timeframe}}) + | where ActionType == "DpapiAccessed" + | where InitiatingProcessFileName has_any ("RegAsm.exe", "MSBuild.exe") + | where (AdditionalFields has_any ("Google Chrome", "Microsoft Edge") and AdditionalFields has_any ("SPCryptUnprotect")) + | extend json = parse_json(AdditionalFields) + | extend dataDesp = tostring(json.DataDescription.PropertyValue) + | extend opType = tostring(json.OperationType.PropertyValue) + | where (dataDesp in~ ("Google Chrome", "Microsoft Edge") and opType =~ "SPCryptUnprotect") + | project Timestamp, ReportId, DeviceId, ActionType, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessVersionInfoInternalFileName, InitiatingProcessCommandLine, AdditionalFields, dataDesp, opType + + - Name: DEX-SensitiveBrowserAccessAutoIT + DisplayName: Sensitive Browser File Access via AutoIT + Description: Identifies AutoIT scripts (renamed or otherwise) accessing sensitive browser files. + Inputs: + - Name: timeframe + Description: Time frame to search (e.g., "1h", "2h"). + Required: true + Settings: + Target: Defender + Template: |- + let browserDirs = pack_array(@"\Google\Chrome\User Data\", @"\Microsoft\Edge\User Data\", @"\Mozilla\Firefox\Profiles\"); + let browserSensitiveFiles = pack_array("Web Data", "Login Data", "key4.db", "formhistory.sqlite", "cookies.sqlite", "logins.json", "places.sqlite", "cert9.db"); + DeviceEvents + | where Timestamp > ago({{timeframe}}) + | where AdditionalFields has_any ("FileOpenSource") + | where InitiatingProcessVersionInfoInternalFileName == "AutoIt3.exe" + | where (AdditionalFields has_any (browserDirs) or AdditionalFields has_any (browserSensitiveFiles)) + | extend json = parse_json(AdditionalFields) + | extend File_Name = tostring(json.FileName.PropertyValue) + | where (File_Name has_any (browserDirs) and File_Name has_any (browserSensitiveFiles)) + | project Timestamp, ReportId, DeviceId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessVersionInfoInternalFileName, InitiatingProcessCommandLine, File_Name + + - Name: DEX-SensitiveBrowserAccessLOLBAS + DisplayName: Sensitive Browser File Access via LOLBAS + Description: Identifies LOLBAS binaries (e.g., RegAsm.exe, MSBuild.exe) accessing sensitive browser files. + Inputs: + - Name: timeframe + Description: Time frame to search (e.g., "1h", "2h"). + Required: true + Settings: + Target: Defender + Template: |- + let browserDirs = pack_array(@"\Google\Chrome\User Data\", @"\Microsoft\Edge\User Data\", @"\Mozilla\Firefox\Profiles\"); + let browserSensitiveFiles = pack_array("Web Data", "Login Data", "key4.db", "formhistory.sqlite", "cookies.sqlite", "logins.json", "places.sqlite", "cert9.db"); + DeviceEvents + | where Timestamp > ago({{timeframe}}) + | where AdditionalFields has_any ("FileOpenSource") + | where InitiatingProcessFileName has_any ("RegAsm.exe", "MSBuild.exe") + | where (AdditionalFields has_any (browserDirs) or AdditionalFields has_any (browserSensitiveFiles)) + | extend json = parse_json(AdditionalFields) + | extend File_Name = tostring(json.FileName.PropertyValue) + | where (File_Name has_any (browserDirs) and File_Name has_any (browserSensitiveFiles)) + | project Timestamp, ReportId, DeviceId, InitiatingProcessParentFileName, InitiatingProcessFileName, InitiatingProcessVersionInfoInternalFileName, InitiatingProcessCommandLine, File_Name + + - Name: DEX-Node.jsInfostealerActivity + DisplayName: Node.js-based infostealer activity + Description: Detect malicious access to sensitive credentials using Windows DPAPI. + Inputs: + - Name: timeframe + Description: Time frame to search (e.g., "1h", "2h"). + Required: true + Settings: + Target: Defender + Template: |- + DeviceEvents + | where Timestamp > ago({{timeframe}}) + | where isnotempty(DeviceId) + | where ActionType == "DpapiAccessed" + | where InitiatingProcessParentFileName endswith "powershell.exe" + | where InitiatingProcessFileName =~ "node.exe" + | where InitiatingProcessCommandLine has_all ("-r", ".js") and InitiatingProcessCommandLine endswith ".jsc" + | where AdditionalFields has "SPCryptUnprotect" + + - Name: DEX-SuspiciousInlineJavaScriptExecution + DisplayName: Suspicious inline JavaScript execution + Description: Identify suspicious inline JavaScript. + Inputs: + - Name: timeframe + Description: Time frame to search (e.g., "1h", "2h"). + Required: true + Settings: + Target: Defender + Template: |- + DeviceProcessEvents + | where Timestamp > ago({{timeframe}}) + | where isnotempty(DeviceId) + | where ProcessVersionInfoOriginalFileName == 'node.exe' + | where ProcessCommandLine has_all ('http', 'execSync', 'spawn', 'fs', 'path', 'zlib') + + - Name: DEX-SuspiciousJSCFile + DisplayName: Suspicious JSC file + Description: Identify execution of suspicious JSC file. + Inputs: + - Name: timeframe + Description: Time frame to search (e.g., "1h", "2h"). + Required: true + Settings: + Target: Defender + Template: |- + DeviceProcessEvents + | where Timestamp > ago({{timeframe}}) + | where isnotempty(DeviceId) + | where ProcessVersionInfoOriginalFileName == 'node.exe' + | where (ProcessCommandLine has_all (".jsc", ".js") and ProcessCommandLine matches regex @"\\\w*.jsc") + +... diff --git a/Plugins/Community Based Plugins/Microsoft Security Exposure Management/Microsoft Security Exposure Management.yaml b/Plugins/Community Based Plugins/Microsoft Security Exposure Management/Microsoft Security Exposure Management.yaml new file mode 100644 index 00000000..ce9764cb --- /dev/null +++ b/Plugins/Community Based Plugins/Microsoft Security Exposure Management/Microsoft Security Exposure Management.yaml @@ -0,0 +1,99 @@ +Descriptor: + Name: Microsoft Exposure Management + DisplayName: Microsoft Exposure Management + Description: > + This KQL plugin integrates capabilities of Microsoft Security Exposure Management (MSEM) with Security Copilot to show exposed devices. + MSEM provides situational awareness, while Security Copilot (SCP) offers quick and consistent retrieval capabilities. + Together, MSEM and SCP empower SOC Engineers with a natural-language front door into exposure insights and attack paths. + This combination also enables the inclusion of MSEM content and reasoning over this content in Security Copilot prompts, prompt books, and automation scenarios that leverage Security Copilot. + The two skills of the plugin correspond to the following use cases - + 1) Obtain exposure of an asset hosted on a particular cloud platform by your organization. + 2) Obtain exposure of an asset belonging to a specific user. + In each of the above use cases, you can also specify the exposure level for which you want to extract the data. + + SupportedAuthTypes: + - None + +##################################################################################### +# SkillGroups can be a single type (KQL, GPT, API) or contain a mix +##################################################################################### + +SkillGroups: + - Format: KQL + + Skills: + - Name: GetExposedDevicesByCloudPlatform + DisplayName: Get exposed Devices by Cloud Platform and exposure level. + Description: For a specific cloud platform (aka "Azure" or "GCP" or "AWS") or a list of cloud platform of the device separated by commas, semi-colons, or using the word 'or', get a list of devices + based on the exposure level specified by the user (aka "Low" or "Medium" or "High") or a list of exposures separated by commas. + DescriptionForModel: For a specific cloud platform of the device (aka "Azure" or "GCP" or "AWS") or a list of cloud platform of the device separated by commas, get a list of devices based on the exposure level specified by the user (aka "Low" or "Medium" or "High") or a list of exposures separated by commas. The results will be returned as a response to the query containing multiple entries, the user needs to be shown the below details from the response about each device DeviceName, DeviceId, ExposureLevel, CloudPlatforms, OSPlatform, OSArchitecture. + VERY IMPORTANT - Never truncate the list of devices retrieved by launching the KQL query related to this skill. Also if the user wants to search on premises then the value for CloudPlatforms should be blank in the query + + ExamplePrompts: + - Get all the devices exposed on Azure platform + - Get all the devices exposed on AWS platform + - Get all the devices exposed on GCP platform + - Get all the devices with exposure level High on Azure platform + - Get all the devices with exposure level Medium on Azure platform + - Get all the devices with exposure level Low on Azure platform + - Get all the devices with exposure level High on AWS platform + - Get all the devices with exposure level Medium on AWS platform + - Get all the devices with exposure level Low on AWS platform + - Get all the devices with exposure level High on GCP platform + - Get all the devices with exposure level Medium on GCP platform + - Get all the devices with exposure level Low on GCP platform + + Inputs: + - Name: inputExposureLevel + Description: Provide the exposure level you want to consider - e.g. High, Medium, Low (only one level) + Required: true + - Name: inputCloudPlatforms + Description: Provide the cloud platform of the device you want to consider - e.g. Azure or GCP or AWS + Required: false + + Settings: + Target: Defender + Template: |- + let userExposureLevel='{{inputExposureLevel}}'; + let userCloudPlatform='{{inputCloudPlatforms}}'; + DeviceInfo + | where ExposureLevel == userExposureLevel + | where + (CloudPlatforms != '' and (CloudPlatforms contains userCloudPlatform or isempty(userCloudPlatform))) + | project DeviceName, DeviceId, ExposureLevel, CloudPlatforms, OSPlatform, OSArchitecture, TimeGenerated + + - Name: GetExposedDevicesByUser + DisplayName: Get exposed devices by UPN and optionally exposure level + Description: For a specific user UPN (aka "user" or "UPN") or a list of users separated by commas, get a list of devices + based on the exposure level specified by the user (aka "Low" or "Medium" or "High") or a list of exposures separated by commas. + DescriptionForModel: For a specific user UPN (aka "user" or "UPN") or a list of users separated by commas, get a list of devices + based on the exposure level specified by the user (aka "Low" or "Medium" or "High") or a list of exposures separated by commas. + The results will be returned as a response to the query containing multiple entries, the user needs to be shown the below details from the response about each device UPN, DeviceName, DeviceId, ExposureLevel, CloudPlatforms, OSPlatform, OSArchitecture. + VERY IMPORTANT - Never truncate the list of devices retrieved by launching the KQL query related to this skill. Also if the user wants to search on premises then the value for CloudPlatforms should be blank in the query. + + ExamplePrompts: + - Get all the devices with exposure level High belonging to user john.doe@contoso.com + - Get all the devices with exposure level Medium belonging to user john.doe@contoso.com + - Get all the devices with exposure level Low belonging to user john.doe@contoso.com + + Inputs: + - Name: inputExposureLevel + Description: Provide the exposure level you want to consider - e.g. High, Medium, Low + Required: false + - Name: inputUPN + Description: Provide the user primary name (UPN) + Required: true + Settings: + Target: Defender + Template: |- + let userExposureLevel='{{inputExposureLevel}}'; + let userUPN='{{inputUPN}}'; + IntuneDevices + | where UPN == userUPN + | project DeviceName = tolower(DeviceName) + | join kind=inner ( + DeviceInfo + | where ExposureLevel == userExposureLevel or isempty(userExposureLevel) + | project DeviceName = tolower(DeviceName), DeviceId,ExposureLevel, CloudPlatforms, OSPlatform, OSArchitecture, TimeGenerated + ) on DeviceName + diff --git a/Plugins/Community Based Plugins/Microsoft Sentinel Custom Plugin Scenarios/High Blast Radius User investigation/HighBlastRaidusUserInvestigation.yaml b/Plugins/Community Based Plugins/Microsoft Sentinel Custom Plugin Scenarios/High Blast Radius User investigation/HighBlastRaidusUserInvestigation.yaml index 85dbb803..80955111 100644 --- a/Plugins/Community Based Plugins/Microsoft Sentinel Custom Plugin Scenarios/High Blast Radius User investigation/HighBlastRaidusUserInvestigation.yaml +++ b/Plugins/Community Based Plugins/Microsoft Sentinel Custom Plugin Scenarios/High Blast Radius User investigation/HighBlastRaidusUserInvestigation.yaml @@ -45,8 +45,7 @@ SkillGroups: TimeGenerated, AccountUPN, AccountDisplayName, - AccountCreationTime, - RiskState, + AccountCreationTime, BlastRadius, GroupMembership, AssignedRoles, diff --git a/Technical Workshops/Custom Plugin Calling Webservice/FlaskWebsite/requirements.txt b/Technical Workshops/Custom Plugin Calling Webservice/FlaskWebsite/requirements.txt index 100cabad..225c854c 100644 --- a/Technical Workshops/Custom Plugin Calling Webservice/FlaskWebsite/requirements.txt +++ b/Technical Workshops/Custom Plugin Calling Webservice/FlaskWebsite/requirements.txt @@ -1 +1 @@ -Flask==3.0.2 \ No newline at end of file +Flask==3.1.3 \ No newline at end of file