{
  "version": "Notebook/1.0",
  "items": [
    {
      "type": 1,
      "content": {
        "json": "## HIPAA Compliance Reporting and Analysis"
      },
      "name": "text - 1",
      "styleSettings": {
        "margin": "0"
      }
    },
    {
      "type": 9,
      "content": {
        "version": "KqlParameterItem/1.0",
        "parameters": [
          {
            "id": "0190326b-1fe3-4072-b4ab-b5e24c81399a",
            "version": "KqlParameterItem/1.0",
            "name": "Subscription",
            "type": 6,
            "description": "Choose your subscription in which HIPAA assets are deployed",
            "isRequired": true,
            "typeSettings": {
              "additionalResourceOptions": [],
              "includeAll": true,
              "showDefault": false
            },
            "timeContext": {
              "durationMs": 86400000
            }
          },
          {
            "id": "5fd8e8dd-6eef-480f-b0e4-aae142bb3f51",
            "version": "KqlParameterItem/1.0",
            "name": "Workspace",
            "type": 5,
            "description": "Choose Workspace where HIPAA assets reports logs",
            "isRequired": true,
            "typeSettings": {
              "additionalResourceOptions": [],
              "showDefault": false
            },
            "timeContext": {
              "durationMs": 86400000
            }
          },
          {
            "id": "70ca879b-56d8-4325-995c-9923f0d46cde",
            "version": "KqlParameterItem/1.0",
            "name": "TimeRange",
            "type": 4,
            "description": "Choose the time range appropriate for your analysis",
            "isRequired": true,
            "typeSettings": {
              "selectableValues": [
                {
                  "durationMs": 1800000
                },
                {
                  "durationMs": 3600000
                },
                {
                  "durationMs": 14400000
                },
                {
                  "durationMs": 43200000
                },
                {
                  "durationMs": 86400000
                },
                {
                  "durationMs": 172800000
                },
                {
                  "durationMs": 259200000
                },
                {
                  "durationMs": 604800000
                },
                {
                  "durationMs": 1209600000
                },
                {
                  "durationMs": 2592000000
                },
                {
                  "durationMs": 5184000000
                },
                {
                  "durationMs": 7776000000
                }
              ]
            },
            "timeContext": {
              "durationMs": 86400000
            },
            "value": {
              "durationMs": 604800000
            }
          }
        ],
        "style": "pills",
        "queryType": 0,
        "resourceType": "microsoft.operationalinsights/workspaces"
      },
      "name": "parameters - 0"
    },
    {
      "type": 11,
      "content": {
        "version": "LinkItem/1.0",
        "style": "tabs",
        "links": [
          {
            "id": "02a6f9e1-ea0c-4c4e-a1eb-3bf2fd602e4e",
            "cellValue": "seltab",
            "linkTarget": "parameter",
            "linkLabel": "Getting Started",
            "subTarget": "gettingstarted",
            "preText": "Getting Started",
            "style": "link"
          },
          {
            "id": "abe1a2a8-7d52-446c-9afb-43ed9ccbc7d6",
            "cellValue": "seltab",
            "linkTarget": "parameter",
            "linkLabel": "Overview",
            "subTarget": "overview",
            "style": "link"
          },
          {
            "id": "1222512a-7f14-4819-a4d4-25bf2603de28",
            "cellValue": "seltab",
            "linkTarget": "parameter",
            "linkLabel": "Attack Range",
            "subTarget": "attackrange",
            "style": "link"
          },
          {
            "id": "c5f19a15-b335-4916-91d2-b5a53c79025a",
            "cellValue": "seltab",
            "linkTarget": "parameter",
            "linkLabel": "Audit Trail Reporting",
            "subTarget": "audittrailreporting",
            "style": "link"
          },
          {
            "id": "6a16a966-40ef-4deb-a350-d924f8e6e1cb",
            "cellValue": "seltab",
            "linkTarget": "parameter",
            "linkLabel": "Further Analysis",
            "subTarget": "furtheranalysis",
            "style": "link"
          }
        ]
      },
      "name": "links - 11"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nAzureDiagnostics\r\n|where isnotempty(msg_s)\r\n|where Resource in~ (watchlist)\r\n|summarize count() by Resource ,msg_s\r\n|project-away count_ ",
              "size": 0,
              "title": "Network Traffic logs of HIPAA assets",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "msg_s",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "170ch"
                    }
                  }
                ]
              }
            },
            "customWidth": "65",
            "name": "query - 6",
            "styleSettings": {
              "maxWidth": "65",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nunion SecurityEvent,Syslog \r\n|where Computer in~ (watchlist)\r\n|where Process != \"\"\r\n|extend Process = coalesce(Process,ProcessName)\r\n|summarize count() by Process,Computer\r\n|project-away count_",
              "size": 0,
              "title": "Process running on HIPAA assets",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Process",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "46ch"
                    }
                  },
                  {
                    "columnMatch": "Computer",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "41ch"
                    }
                  }
                ]
              }
            },
            "customWidth": "35",
            "name": "query - 7",
            "styleSettings": {
              "maxWidth": "35",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nSecurityEvent \r\n|where isnotempty(Account)\r\n|where Computer in~ (watchlist)\r\n| summarize count() by Account , AccountType ,Computer , Activity ,ParentProcessName",
              "size": 0,
              "title": "Security events of HIPAA assets",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Account",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "sourceColumn": "AccountType",
                          "operator": "==",
                          "thresholdValue": "User",
                          "representation": "AddTeamMember",
                          "text": "{0}{1}"
                        },
                        {
                          "sourceColumn": "AccountType",
                          "operator": "==",
                          "thresholdValue": "Machine",
                          "representation": "Initial_Access",
                          "text": "{0}{1}"
                        },
                        {
                          "sourceColumn": "AccountType",
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "success",
                          "text": "{0}{1}"
                        }
                      ],
                      "customColumnWidthSetting": "42ch"
                    }
                  },
                  {
                    "columnMatch": "ParentProcessName",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "100ch"
                    }
                  },
                  {
                    "columnMatch": "count_",
                    "formatter": 8,
                    "formatOptions": {
                      "palette": "redBright"
                    }
                  }
                ]
              }
            },
            "name": "query - 8",
            "styleSettings": {
              "showBorder": true
            }
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "seltab",
        "comparison": "isEqualTo",
        "value": "audittrailreporting"
      },
      "name": "AuditGroup"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nDeviceProcessEvents\r\n| where ProcessCommandLine has_any(\r\n    \"-ExclusionPath\", \"Set-MpPreference\", \"advfirewall\", \"-ExclusionExtension\",\r\n    \"-EnableControlledFolderAccess\", \"windefend\", \"onstart\", \"bcdedit\", \"Startup\"\r\n)\r\n|extend split_devicename = split(DeviceName, \".\" ,0)[0]\r\n|where split_devicename in~ (watchlist)\r\n| summarize ProcessCommandLine = make_set(ProcessCommandLine) by DeviceName, DeviceId, bin(TimeGenerated, 6h)\r\n// Convert to \"Found\"/\"Not Found\"\r\n| extend StartUpExclusionPath = iif(ProcessCommandLine has_all(\"-ExclusionPath\", \"Startup\"), \"Found\", \"Not Found\")\r\n| extend DefenderTamp = iif(\r\n    ProcessCommandLine has \"Set-MpPreference\" and ProcessCommandLine has_any(\r\n        \"-SevereThreatDefaultAction 6\", \r\n        \"-HighThreatDefaultAction 6\", \r\n        \"-ModerateThreatDefaultAction 6\", \r\n        \"-LowThreatDefaultAction 6\", \r\n        \"-ScanScheduleDay 8\"\r\n    ), \"Found\", \"Not Found\")\r\n| extend NetshFirewallTampering = iif(ProcessCommandLine has_all(\"netsh\", \"advfirewall\", \"allprofiles state off\"), \"Found\", \"Not Found\")\r\n| extend BatExclusion = iif(ProcessCommandLine has_all(\"-ExclusionExtension\", \".bat\"), \"Found\", \"Not Found\")\r\n| extend ExeExclusion = iif(ProcessCommandLine has_all(\"-ExclusionExtension\", \".exe\"), \"Found\", \"Not Found\")\r\n| extend DisableControlledFolderAccess = iif(ProcessCommandLine has_all(\"-EnableControlledFolderAccess\", \"Disabled\"), \"Found\", \"Not Found\")\r\n| extend ScDeleteDefend = iif(ProcessCommandLine has_all(\"sc\", \"delete\", \"windefend\"), \"Found\", \"Not Found\")\r\n| extend BootTampering = iif(ProcessCommandLine has_all(\"bcdedit\", \"default\") and ProcessCommandLine has_any(\"recoveryenabled No\", \"bootstatuspolicy ignoreallfailures\"), \"Found\", \"Not Found\")\r\n| extend SchTasks = iif(ProcessCommandLine has_all(\"/sc\", \"onstart\", \"system\", \"/create\", \"/delay\"), \"Found\", \"Not Found\")\r\n// Count how many were \"Found\"\r\n| extend EvidenceCount = countof(tostring(pack_array(\r\n    iff(StartUpExclusionPath == \"Found\", 1, 0),\r\n    iff(DefenderTamp == \"Found\", 1, 0),\r\n    iff(NetshFirewallTampering == \"Found\", 1, 0),\r\n    iff(BatExclusion == \"Found\", 1, 0),\r\n    iff(ExeExclusion == \"Found\", 1, 0),\r\n    iff(DisableControlledFolderAccess == \"Found\", 1, 0),\r\n    iff(ScDeleteDefend == \"Found\", 1, 0),\r\n    iff(BootTampering == \"Found\", 1, 0),\r\n    iff(SchTasks == \"Found\", 1, 0)\r\n)),\"1\")\r\n|sort by EvidenceCount",
              "size": 2,
              "title": "Detect Ransomware Activity (Macaw ransomware)",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "EvidenceCount",
                    "formatter": 8,
                    "formatOptions": {
                      "min": 0,
                      "max": 4,
                      "palette": "red"
                    }
                  }
                ]
              }
            },
            "name": "query - 0",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": " let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\n let abusedProcedures = dynamic([\"xp_cmdshell\", \"xp_regwrite\", \"xp_regdeletekey\", \"xp_regdeletevalue\", \"xp_dirtree\", \"xp_fileexist\", \"xp_msver\", \"xp_makecab\", \"xp_sqlshell\", \"xp_fixeddrivesd\", \"xp_regread\", \"sp_configure\", \"sp_oacreate\", \"sp_password\", \"sp_OACreate\", \"sp_addextendedproc\", \"sp_dropextendedproc\", \"sp_makewebtask\", \"sp_delete\", \"SP_OAcreate\", \"sp_OADestroy\"]);\r\n  AzureDiagnostics\r\n  |where Resource in~ (watchlist) or server_instance_name_s in~ (watchlist) or LogicalServerName_s in~ (watchlist)\r\n  | where Category =~ \"SQLSecurityAuditEvents\"\r\n  | where statement_s has_any (abusedProcedures)\r\n  | project TimeGenerated,ResourceId, ClientIp=client_ip_s, PrincipalName=session_server_principal_name_s, statement_s, action_id_s, HostName=host_name_s, ApplicationName=application_name_s , Resource",
              "size": 0,
              "title": "SQL queries with suspicious stored procedures",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ]
            },
            "name": "query - 1",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nDeviceFileEvents\r\n|where isnotempty(SHA256)\r\n|extend split_devicename = split(DeviceName, \".\" ,0)[0]\r\n|where split_devicename in~ (watchlist)\r\n| join kind=inner (ThreatIntelIndicators |where ObservableKey == \"file:hashes.'SHA-256'\") on $left.SHA256 == $right.ObservableValue\r\n| project TimeGenerated, DeviceName, FileName, SHA256, Data.description",
              "size": 0,
              "title": "Detect Known Ransomware Hashes or IOCs",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table"
            },
            "name": "query - 2",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nDeviceNetworkEvents\r\n|extend split_devicename = split(DeviceName, \".\" ,0)[0]\r\n|where split_devicename in~ (watchlist)\r\n| where ActionType == \"ConnectionSuccess\"\r\n| where RemotePort == 445 or RemotePort == 139\r\n| summarize Connections = count(), DistinctTargets = dcount(RemoteIP) by DeviceName, bin(TimeGenerated, 1d) \r\n|sort by DistinctTargets",
              "size": 0,
              "title": "Unusual SMB/Network Activity (possible worm/ransomware spread)",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "DeviceName",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "60ch"
                    }
                  },
                  {
                    "columnMatch": "DistinctTargets",
                    "formatter": 8,
                    "formatOptions": {
                      "min": 1,
                      "max": 10,
                      "palette": "red"
                    }
                  }
                ]
              }
            },
            "customWidth": "50",
            "name": "query - 3",
            "styleSettings": {
              "maxWidth": "50",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_users_details') |project UserName);\r\nSigninLogs\r\n|where ResultSignature == \"FAILURE\"  and isnotempty( UserPrincipalName) and UserPrincipalName in~ (watchlist)\r\n| summarize Failures_in_5_minutes = count() by UserPrincipalName, bin(TimeGenerated, 5m)\r\n|where Failures_in_5_minutes > 5",
              "size": 0,
              "title": "Password Spray / Credential Stuffing(Multiple failed login attempts on a single account in a short window)",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "UserPrincipalName",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "35ch"
                    }
                  },
                  {
                    "columnMatch": "TimeGenerated",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "40ch"
                    }
                  },
                  {
                    "columnMatch": "Failures_in_5_minutes",
                    "formatter": 3,
                    "formatOptions": {
                      "min": 5,
                      "max": 20,
                      "palette": "red",
                      "customColumnWidthSetting": "200px"
                    }
                  }
                ]
              }
            },
            "customWidth": "50",
            "name": "query - 4",
            "styleSettings": {
              "maxWidth": "50",
              "showBorder": true
            }
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "seltab",
        "comparison": "isEqualTo",
        "value": "attackrange"
      },
      "name": "attackrange"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_users_details') |project UserName,TrainingStatus,AccessLevel );\r\nwatchlist\r\n| extend TrainingStatus = case(\r\n    TrainingStatus =~ \"Completed\", strcat(\"🟩 \", TrainingStatus),\r\n    strcat(\"🟥 \", TrainingStatus)\r\n)",
              "size": 1,
              "title": "HIPAA DB Users status",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "TrainingStatus",
                    "formatter": 1,
                    "formatOptions": {
                      "compositeBarSettings": {
                        "labelText": "",
                        "columnSettings": [
                          {
                            "columnName": "TrainingStatus",
                            "color": "redBright"
                          }
                        ]
                      }
                    }
                  }
                ],
                "sortBy": [
                  {
                    "itemKey": "TrainingStatus",
                    "sortOrder": 2
                  }
                ]
              },
              "sortBy": [
                {
                  "itemKey": "TrainingStatus",
                  "sortOrder": 2
                }
              ]
            },
            "customWidth": "25",
            "name": "query - 1",
            "styleSettings": {
              "maxWidth": "25",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nunion AzureDiagnostics , Heartbeat\r\n|where Resource in~ (watchlist) \r\n|extend Lastlog = TimeGenerated\r\n|summarize arg_max(Lastlog, *) by Resource\r\n|extend Current = now()\r\n|extend Offline_past_hour = datetime_diff('hour',now(),Lastlog)\r\n|project Resource,Lastlog,Current,Offline_past_hour\r\n|sort by Offline_past_hour desc",
              "size": 1,
              "title": "HIPAA Assets status",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Offline_past_hour",
                    "formatter": 8,
                    "formatOptions": {
                      "min": 10,
                      "max": 48,
                      "palette": "redBright"
                    }
                  }
                ]
              }
            },
            "customWidth": "45",
            "name": "query - 2",
            "styleSettings": {
              "maxWidth": "45",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert  \r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n|where Entity.HostName in~ (watchlist)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n|where DeviceName != \"\"\r\n| summarize DeviceName = make_set(DeviceName, 1), any(AlertName), any(AlertSeverity), any(TimeGenerated) by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner (\r\n    SecurityIncident\r\n    | mv-expand AlertIds\r\n    | extend AlertId = tostring(AlertIds)\r\n    | project IncidentName, IncidentNumber, Title, Severity, Status, IncidentCreatedTime = TimeGenerated, AlertId\r\n) on AlertId\r\n|summarize make_set(DeviceName) by IncidentNumber,Title,Severity,Status\r\n|summarize count() by Severity",
              "size": 1,
              "title": "New/Active Incidents ",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "piechart",
              "tileSettings": {
                "showBorder": false
              }
            },
            "customWidth": "15",
            "name": "query - 7",
            "styleSettings": {
              "maxWidth": "15",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nlet watchlist1 = (_GetWatchlist('hipaa_users_details') |project UserName);\r\n// Azure SQL Logins\r\nlet SQLLogins = AzureDiagnostics\r\n| where Category == \"SQLSecurityAuditEvents\"\r\n| where action_name_s in (\"DATABASE AUTHENTICATION FAILED\", \"DATABASE AUTHENTICATION SUCCEEDED\")\r\n|where Resource in~ (watchlist) or server_instance_name_s in~ (watchlist) or LogicalServerName_s in~ (watchlist)\r\n| summarize Count = count() by Status = iff(action_name_s == \"DATABASE AUTHENTICATION FAILED\", \"Failed\", \"Success\");\r\n// Windows VM Logins\r\nlet WinVMLogins = SecurityEvent\r\n| where EventID in (4624, 4625) // 4624=Success, 4625=Failed\r\n|where Computer in~ (watchlist)\r\n| summarize Count = count() by Status = iff(EventID == 4625, \"Failed\", \"Success\");\r\n// Linux VM Logins\r\nlet LinuxVMLogins = Syslog\r\n| where Facility in (\"authpriv\",\"auth\")\r\n| where ProcessName == \"sshd\"\r\n|where Computer in~ (watchlist)\r\n| where SyslogMessage has_any (\"Failed password\", \"Accepted password\")\r\n| summarize Count = count() by Status = iff(SyslogMessage has \"Failed password\", \"Failed\", \"Success\");\r\n// Azure AD Logins\r\nlet AzureADLogins = SigninLogs\r\n| where isnotempty(UserPrincipalName) and UserPrincipalName in~ (watchlist1)\r\n| summarize Count = count() by Status = iff(ResultSignature == \"FAILURE\", \"Failed\", \"Success\");\r\n// Combine all and summarize into two rows: Failed & Success\r\nunion SQLLogins, WinVMLogins, LinuxVMLogins, AzureADLogins\r\n| summarize TotalCount = sum(Count) by Status\r\n| order by Status asc",
              "size": 1,
              "title": "Failure vs Success logins",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "piechart",
              "chartSettings": {
                "seriesLabelSettings": [
                  {
                    "seriesName": "Success",
                    "color": "green"
                  },
                  {
                    "seriesName": "Failed",
                    "color": "redBright"
                  }
                ]
              }
            },
            "customWidth": "15",
            "name": "query - 10",
            "styleSettings": {
              "maxWidth": "15",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nDeviceInfo\r\n| where DeviceName != \"\"\r\n|extend split_devicename = split(DeviceName, \".\" ,0)[0]\r\n|where split_devicename in~ (watchlist)\r\n| summarize arg_max(TimeGenerated, OSPlatform, DeviceName, OnboardingStatus, SensorHealthState, ExposureLevel, IsExcluded) by DeviceName\r\n| extend OnboardingStatus = case(\r\n        OnboardingStatus == \"Can be onboarded\" or OnboardingStatus == \"Insufficient info\", \"Not Onboarded\",\r\n        OnboardingStatus // otherwise keep original value\r\n    )\r\n| project TimeGenerated, DeviceName, OSPlatform, OnboardingStatus, SensorHealthState, ExposureLevel, IsExcluded\r\n| extend SensorHealthState = iff(SensorHealthState==\"Active\" and OnboardingStatus == \"Onboarded\",\"🟩 Active\", iff(SensorHealthState==\"Inactive\" and OnboardingStatus == \"Onboarded\",\"🟥 Inactive\",SensorHealthState))\r\n| extend HealthOrder = case(\r\n        SensorHealthState contains \"Inactive\", 1,\r\n        SensorHealthState contains \"Active\", 2,\r\n        3 // fallback for other states\r\n    )\r\n| order by HealthOrder asc, TimeGenerated desc\r\n| project-away HealthOrder",
              "size": 2,
              "title": "Defender for Endpoint (Antivirus) Status ",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "DeviceName",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "60ch"
                    }
                  },
                  {
                    "columnMatch": "OSPlatform",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "60ch"
                    }
                  },
                  {
                    "columnMatch": "OnboardingStatus",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "50ch"
                    }
                  },
                  {
                    "columnMatch": "SensorHealthState",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "50ch"
                    }
                  },
                  {
                    "columnMatch": "ExposureLevel",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "50ch"
                    }
                  },
                  {
                    "columnMatch": "IsExcluded",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "50ch"
                    }
                  }
                ]
              }
            },
            "name": "query - 3",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nAzureDiagnostics\r\n| where Category == \"SQLSecurityAuditEvents\"\r\n|where Resource in~ (watchlist) or server_instance_name_s in~ (watchlist) or LogicalServerName_s in~ (watchlist)\r\n| extend CRUDOperation = case(\r\n        statement_s startswith \"SELECT\", \"READ\",\r\n        statement_s startswith \"INSERT\", \"CREATE\",\r\n        statement_s startswith \"UPDATE\", \"UPDATE\",\r\n        statement_s startswith \"DELETE\", \"DELETE\",\r\n        statement_s startswith \"DROP\", \"DELETE\",            // <-- NEW: drop table/database = delete\r\n        statement_s startswith \"TRUNCATE\", \"DELETE\",        // <-- NEW: truncate table = delete\r\n        statement_s startswith \"ALTER\", \"MODIFY\",\r\n        statement_s startswith \"CREATE\", \"CreateTable\",\r\n        statement_s startswith \"\", \"Null\",           // <-- NEW: schema/role change\r\n        \"OTHER\"\r\n    )\r\n| project TimeGenerated, LogicalServerName_s, session_server_principal_name_s, client_ip_s, CRUDOperation, statement_s , Resource",
              "size": 0,
              "title": "Dangerous Crud operations performed by DB users",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "TimeGenerated",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "26ch"
                    }
                  },
                  {
                    "columnMatch": "session_server_principal_name_s",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "33ch"
                    }
                  }
                ]
              }
            },
            "customWidth": "50",
            "name": "query - 4",
            "styleSettings": {
              "maxWidth": "50",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nAzureDiagnostics\r\n| where Category == \"SQLSecurityAuditEvents\"\r\n|where Resource in~ (watchlist) or server_instance_name_s in~ (watchlist) or LogicalServerName_s in~ (watchlist)\r\n| extend CRUDOperation = case(\r\n        statement_s startswith \"SELECT\", \"READ\",\r\n        statement_s startswith \"INSERT\", \"CREATE\",\r\n        statement_s startswith \"UPDATE\", \"UPDATE\",\r\n        statement_s startswith \"DELETE\", \"DELETE\",\r\n        statement_s startswith \"DROP\", \"DELETE\",            // <-- NEW: drop table/database = delete\r\n        statement_s startswith \"TRUNCATE\", \"DELETE\",        // <-- NEW: truncate table = delete\r\n        statement_s startswith \"ALTER\", \"MODIFY\",\r\n        statement_s startswith \"CREATE\", \"CreateTable\",\r\n        statement_s startswith \"\", \"Null\",           // <-- NEW: schema/role change\r\n        \"OTHER\"\r\n    )\r\n| project TimeGenerated, LogicalServerName_s, session_server_principal_name_s, client_ip_s, CRUDOperation, statement_s\r\n| summarize OperationCount = count() by bin(TimeGenerated, 1d),CRUDOperation",
              "size": 0,
              "title": "Operations performed on DB server over 1 day interval",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "areachart"
            },
            "customWidth": "50",
            "name": "query - 6",
            "styleSettings": {
              "maxWidth": "50",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nSecurityAlert  \r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n|extend split_devicename = split(CompromisedEntity, \".\" ,0)[0]\r\n|where split_devicename in~ (watchlist)\r\n|extend Incident = tostring(parse_json(ExtendedProperties).IncidentId)\r\n|where CompromisedEntity != \"\" and EntityType == \"host\"\r\n|summarize Incidents = make_set(Incident) by CompromisedEntity",
              "size": 0,
              "title": "Compromised HIPAA Assets",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ]
            },
            "customWidth": "50",
            "name": "query - 8",
            "styleSettings": {
              "maxWidth": "50",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_users_details') |project UserName);\r\nSigninLogs\r\n|where isnotempty(UserPrincipalName)\r\n|where UserPrincipalName in~ (watchlist) or UserDisplayName in~ (watchlist)\r\n| project UserPrincipalName,\r\n          AuthenticationRequirement,          // \"singleFactorAuthentication\" or \"multiFactorAuthentication\"\r\n          AuthenticationDetails,\r\n          ResultType,\r\n          ResultDescription,\r\n          ConditionalAccessStatus,\r\n          TimeGenerated,\r\n          UserDisplayName\r\n| summarize SignIns = count(),\r\n            MFASuccess = countif(AuthenticationRequirement == \"multiFactorAuthentication\")\r\n        by UserPrincipalName,UserDisplayName\r\n| extend MFAStatus = iff(MFASuccess > 0, \"MFA Used\", \"No MFA Used\"), MFAFailure = SignIns - MFASuccess\r\n| sort by MFAStatus desc, SignIns desc",
              "size": 0,
              "title": "DB Users MFA status",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "UserPrincipalName",
                    "formatter": 18,
                    "formatOptions": {
                      "thresholdsOptions": "icons",
                      "thresholdsGrid": [
                        {
                          "operator": "Default",
                          "thresholdValue": null,
                          "representation": "AddTeamMember",
                          "text": "{0}{1}"
                        }
                      ],
                      "customColumnWidthSetting": "35ch"
                    }
                  },
                  {
                    "columnMatch": "MFAStatus",
                    "formatter": 2,
                    "formatOptions": {
                      "customColumnWidthSetting": "25ch"
                    }
                  },
                  {
                    "columnMatch": "MFAFailure",
                    "formatter": 8,
                    "formatOptions": {
                      "min": 0,
                      "max": 20,
                      "palette": "red"
                    }
                  }
                ]
              }
            },
            "customWidth": "50",
            "name": "query - 9",
            "styleSettings": {
              "maxWidth": "50",
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nlet myAlert = SecurityAlert  \r\n| mv-expand Entity = todynamic(Entities)\r\n| extend EntityType = tostring(Entity.Type)\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)\r\n| summarize \r\n    DeviceName = make_set(DeviceName), \r\n    AlertName = any(AlertName), \r\n    AlertSeverity = any(AlertSeverity), \r\n    TimeGenerated = any(TimeGenerated),\r\n    ProductName = any(ProductName), \r\n    Tactics = any(Tactics), \r\n    CompromisedEntity = any(CompromisedEntity), \r\n    AlertLink = any(AlertLink)\r\n    by AlertId = SystemAlertId;\r\nmyAlert\r\n| join kind=inner (\r\n    SecurityIncident\r\n    | mv-expand AlertIds\r\n    | extend AlertId = tostring(AlertIds)\r\n    | project IncidentName, IncidentNumber, Title, Severity, Status, IncidentCreatedTime = TimeGenerated, AlertId\r\n) on AlertId\r\n| summarize \r\n    DeviceName = make_set(DeviceName) \r\n    by IncidentNumber, Title, Severity, Status, Tactics, ProductName, AlertLink\r\n| extend SeverityOrder = case(\r\n    Severity == \"High\", 1,\r\n    Severity == \"Medium\", 2,\r\n    Severity == \"Low\", 3,\r\n    4 // for anything else (Informational, Unknown)\r\n)\r\n| order by SeverityOrder asc\r\n| project-away SeverityOrder\r\n",
              "size": 0,
              "title": "Incidents on HIPAA Servers ",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "crossComponentResources": [
                "{Workspace}"
              ],
              "visualization": "table",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Title",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "90ch"
                    }
                  },
                  {
                    "columnMatch": "Severity",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "20ch"
                    }
                  },
                  {
                    "columnMatch": "Status",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "20ch"
                    }
                  },
                  {
                    "columnMatch": "Tactics",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "30ch"
                    }
                  },
                  {
                    "columnMatch": "AlertLink",
                    "formatter": 7,
                    "formatOptions": {
                      "linkTarget": "Url",
                      "customColumnWidthSetting": "80ch"
                    }
                  },
                  {
                    "columnMatch": "DeviceName",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "50ch"
                    }
                  }
                ],
                "sortBy": [
                  {
                    "itemKey": "Status",
                    "sortOrder": 1
                  }
                ]
              },
              "sortBy": [
                {
                  "itemKey": "Status",
                  "sortOrder": 1
                }
              ],
              "tileSettings": {
                "showBorder": false,
                "titleContent": {
                  "columnMatch": "DeviceName",
                  "formatter": 1
                },
                "leftContent": {
                  "columnMatch": "IncidentNumber",
                  "formatter": 12,
                  "formatOptions": {
                    "palette": "auto"
                  },
                  "numberFormat": {
                    "unit": 17,
                    "options": {
                      "maximumSignificantDigits": 3,
                      "maximumFractionDigits": 2
                    }
                  }
                }
              },
              "mapSettings": {
                "locInfo": "LatLong",
                "sizeSettings": "IncidentNumber",
                "sizeAggregation": "Sum",
                "legendMetric": "IncidentNumber",
                "legendAggregation": "Sum",
                "itemColorSettings": {
                  "type": "heatmap",
                  "colorAggregation": "Sum",
                  "nodeColorField": "IncidentNumber",
                  "heatmapPalette": "greenRed"
                }
              }
            },
            "name": "query - 5",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nAzureDiagnostics\r\n|where Resource in~ (watchlist)\r\n| where Category == \"AzureFirewallNetworkRule\"\r\n| extend SourceIP = extract(@\"from\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+):\", 1, msg_s),\r\n         SourcePort = extract(@\"from\\s+\\d+\\.\\d+\\.\\d+\\.\\d+:(\\d+)\", 1, msg_s),\r\n         DestinationIP = extract(@\"to\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+):\", 1, msg_s),\r\n         DestinationPort = extract(@\"to\\s+\\d+\\.\\d+\\.\\d+\\.\\d+:(\\d+)\", 1, msg_s),\r\n         TranslatedIP = extract(@\"was DNAT'ed to\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+):\", 1, msg_s),\r\n         TranslatedPort = extract(@\"was DNAT'ed to\\s+\\d+\\.\\d+\\.\\d+\\.\\d+:(\\d+)\", 1, msg_s),\r\n         Action = extract(@\"Action:\\s*(\\w+)\", 1, msg_s)\r\n| project TimeGenerated,Resource, SourceIP, DestinationIP, DestinationPort, TranslatedIP, TranslatedPort,Action\r\n|extend Action = iff(Action == \"Deny\" ,\"🟥 Deny\",\"🟩 Allow\")\r\n|summarize AllSourceIp = make_set(SourceIP) by DestinationIP , DestinationPort,Action,Resource\r\n|extend Count_Sourceip = array_length(AllSourceIp)",
              "size": 2,
              "title": "Network Ports utilization status",
              "timeContextFromParameter": "TimeRange",
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "gridSettings": {
                "formatters": [
                  {
                    "columnMatch": "Resource",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "35ch"
                    }
                  },
                  {
                    "columnMatch": "AllSourceIp",
                    "formatter": 0,
                    "formatOptions": {
                      "customColumnWidthSetting": "150ch"
                    }
                  }
                ]
              }
            },
            "name": "query - 10",
            "styleSettings": {
              "showBorder": true
            }
          },
          {
            "type": 3,
            "content": {
              "version": "KqlItem/1.0",
              "query": "let watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );\r\nAzureDiagnostics\r\n|where Resource in~ (watchlist)\r\n| where Category == \"AzureFirewallNetworkRule\"\r\n| extend SourceIP = extract(@\"from\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+):\", 1, msg_s),\r\n         SourcePort = extract(@\"from\\s+\\d+\\.\\d+\\.\\d+\\.\\d+:(\\d+)\", 1, msg_s),\r\n         DestinationIP = extract(@\"to\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+):\", 1, msg_s),\r\n         DestinationPort = extract(@\"to\\s+\\d+\\.\\d+\\.\\d+\\.\\d+:(\\d+)\", 1, msg_s),\r\n         TranslatedIP = extract(@\"was DNAT'ed to\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+):\", 1, msg_s),\r\n         TranslatedPort = extract(@\"was DNAT'ed to\\s+\\d+\\.\\d+\\.\\d+\\.\\d+:(\\d+)\", 1, msg_s),\r\n         Action = extract(@\"Action:\\s*(\\w+)\", 1, msg_s)\r\n| project TimeGenerated, Resource, SourceIP, DestinationIP, DestinationPort, TranslatedIP, TranslatedPort, Action\r\n| extend Action = iff(Action == \"Deny\", \"🟥 Deny\", \"🟩 Allow\")\r\n| summarize \r\n    AllSourceIp = make_set(SourceIP),\r\n    ConnectionCount = count()         // 🔹 Count total connections\r\n    by bin(TimeGenerated, 3d), DestinationIP, DestinationPort, Action, Resource\r\n| extend Count_Sourceip = array_length(AllSourceIp)\r\n| order by TimeGenerated desc",
              "size": 0,
              "title": "Network ports utilization over 3 days interval",
              "timeContext": {
                "durationMs": 2592000000
              },
              "queryType": 0,
              "resourceType": "microsoft.operationalinsights/workspaces",
              "visualization": "linechart",
              "chartSettings": {
                "xAxis": "TimeGenerated",
                "yAxis": [
                  "ConnectionCount"
                ],
                "group": "DestinationIP",
                "createOtherGroup": 15,
                "xSettings": {
                  "label": "Time Generated"
                }
              }
            },
            "name": "query - 11",
            "styleSettings": {
              "showBorder": true
            }
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "seltab",
        "comparison": "isEqualTo",
        "value": "overview"
      },
      "name": "overviewgroup"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "The Microsoft Sentinel Solution for HIPAA Compliance provides real-time visibility into security activity and potential risks within your protected health information (PHI) environment. This solution is tailored for Compliance Officers, Security Architects, SOC Analysts, and IT Administrators to help define and monitor HIPAA-related assets, detect violations, and investigate compliance issues.\r\n<br><br>\r\nThe workbook includes pre-written KQL queries that can be exported for further analysis, helping your team perform detailed investigations and meet audit requirements.\r\n<br><br>\r\nThe Microsoft Sentinel team welcomes your feedback on this HIPAA Compliance Solution, and how we can expand our compliance content to better meet your organization’s needs. Please share any feedback with us [Here](https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR5vpbw39GIlPr6oh7FnjxTFUOVhBOFowTFlaT1pOSTAxVDdRT1pIUDlINy4u)",
              "style": "info"
            },
            "name": "text - 0"
          },
          {
            "type": 1,
            "content": {
              "json": "### Getting Started with the HIPAA Compliance Solution\r\n\r\nThe HIPAA compliance report in Microsoft Sentinel helps healthcare organizations and business associates monitor and validate their adherence to HIPAA’s Security and Privacy Rules. It provides visibility into access logs, anomalies, and safeguard controls across administrative, technical, and physical domains. Users can leverage the dashboard to detect violations, track policy changes, and ensure secure handling of protected health information (PHI), with support for private preview feedback and integration with Azure services.\r\n\r\nThere are two pre-requisites to getting started with the HIPAA Compliance Solution:<br>\r\n\r\n1. **<u>Connect Data Sources:</u>**  \r\n   Users will need to connect applicable data sources to populate the reports.  \r\n   This solution provides support for the following data sources:</br>\r\n<u>Note: Kindly Install sentinel Solutions by using the corresponding links provided below for each corresponding data sources, Post installation configure their data connectors , ignore if already done.</u></br>\r\n   - ***AzureDiagnostics*** (to collect logs from firewalls, network devices, SQL servers and other HIPAA-relevant infrastructure). Link : [Install Azure SQL Database](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/sentinel4sql.sentinel4sql), [Install Azure Firewall](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/sentinel4azurefirewall.sentinel4azurefirewall), and [Install Azure Web Application Firewall](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-azurewebapplicationfirewal)\r\n   - ***SecurityEvent / SecurityAlert / SecurityIncident*** (for Windows server event logs — login activity, access attempts, anomaly and incident detection). Link :  [Install Microsoft Defender for Cloud](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderforcloud), [Install Microsoft Defender for Office 365](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderforo365) ,[Install Microsoft Defender XDR](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoft365defender) and [Install Microsoft Defender for Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderendpoint)\r\n   - ***DeviceNetworkEvents / DeviceProcessEvents / DeviceInfo / DeviceFileEvents*** (for endpoint protection status, details and Defender for Endpoint alerts). Link : [Install Microsoft Defender XDR](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoft365defender), [Install Microsoft Defender for Endpoint](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-microsoftdefenderendpoint)\r\n   - ***Syslog*** (For Detecting failure logins and status of servers). Link : [Install Syslog](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-syslog)\r\n   - ***SQLSecurityAuditEvents*** (for HIPAA database activity auditing). Link : [Install Azure SQL Database](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/sentinel4sql.sentinel4sql).\r\n   - ***SigninLogs*** (for HIPAA Assets login activity auditing). Link : [Install Microsoft Entra ID](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-azureactivedirectory).\r\n   - ***ThreatIntelIndicators*** (for fetching latest threatID's). Link : [Install Threat Intel](https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/azuresentinel.azure-sentinel-solution-threatintelligence-updated)<br>\r\n\r\n2. **<u>Define HIPAA Users and Assets:</u>**<br>\r\n   Users will need to define HIPAA-relevant users and assets within their compliance scope via two Watchlists:<br><br>\r\n\r\n   **<u>HIPAA Users Details Watchlist</u>**  \r\n   - Save the CSV file with the following columns: `UserName, TrainingStatus, AccessLevel`\r\n   - Open your workspace in Microsoft Sentinel\r\n   - Go to **Watchlist** under the **Configuration** tab\r\n   - Click on **Add new**\r\n   - Enter **\"hipaa_users_details\"** in the **Name** field\r\n   - Enter **Description**\r\n   - Enter **\"hipaa_users_details\"** in the **Alias** field\r\n   - Set **SourceType** to **LocalFile**\r\n   - Set **File type** to **CSV**\r\n   - Upload the CSV file\r\n   - Enter **\"UserName\"** as the search key\r\n   - Click **Review and Create**, then **Create**<br><br>\r\n\r\n   **<u>HIPAA Assets Watchlist</u>**  \r\n   - Save the CSV file with the following columns: `DeviceName, DeviceType`\r\n   - Repeat the same steps as above but use:\r\n     - **Name:** `hipaa_assets`\r\n     - **Alias:** `hipaa_assets`\r\n     - **SearchKey:** `DeviceName`  \r\n<br>\r\n\r\n### Included in the Microsoft Sentinel HIPAA Compliance Solution\r\n\r\nThis solution enables Microsoft Sentinel users to harness the power of their SIEM to help meet HIPAA Security Rule requirements, including access control, audit controls, integrity monitoring, and incident response.<br>\r\n\r\nThe Watchlist included in this solution allows users to define the HIPAA Assets included in their organization’s compliance scope.  \r\nThe Workbook included in this solution contains three tabs, with the following information.  \r\nThe solution comes with pre-defined dashboards, visualizations, and reports, providing immediate insights into your HIPAA environment.<br>\r\n\r\n**<u>Overview Tab</u>**  \r\nThis Workbook tab provides an overview of recent activity on the HIPAA Assets you define and trends over time, through the following tables and charts:  \r\n\r\n1. **HIPAA DB Users Status:** Maintain a record of users, their training status, and their access levels.  \r\n2. **HIPAA Asset Status:** Online and offline status of network/DB assets in HIPAA scope, including how long an asset has been offline.  \r\n3. **New/Active Incidents:** Count and trend of incidents related to HIPAA assets.\r\n4. **Failure vs Success logins:** Bird Eye View on how many users have failed and successfull logins in given time range   \r\n5. **Defender for Endpoint (Antivirus) Status:** Uncovered Hipaa Assets which doesn't has anitvirus installed or antivirus in disabled state  \r\n6. **Dangerous Crud operations performed by DB users:** Highlight of critical database actions such as DELETE, DROP, ALTER or reading data on large scale performed by HIPAA DB users.  \r\n7. **Operations performed on DB server over 1 day interval:** Visualization of all DB operations over the given time range with an interval of one day.  \r\n8. **Compromised HIPAA Assets:** Summary of devices flagged as compromised or under attack.  \r\n9. **DB Users MFA Status:** Status of multi-factor authentication for all HIPAA DB users.  \r\n10. **Incidents on HIPAA Servers:** Detailed incident listing and correlation to MITRE ATT&CK techniques.  \r\n11. **Network Port Utilization:** Stats of open/active network ports and their usage trends.\r\n12. **Network ports utilization over 3 days interval:** Visualization of open/active network ports and their usage trends.<br>\r\n\r\n**<u>Attack Range Tab</u>**  \r\nThis tab is dedicated to the detection and triage of active intrusion behaviors associated with ransomware campaigns and account compromise. It surfaces high-fidelity signals such as suspicious stored procedure executions, anomalous SMB traffic, and lateral movement patterns that may indicate worm-like propagation or ransomware spread. Integrated threat intelligence enables matching of known ransomware hashes and IOCs, while behavioral analytics flag credential-based attacks like password spray and credential stuffing. The tab also highlights PowerShell and SSH activity correlated with memory access and file archiving, helping security teams identify stealthy credential theft and privilege escalation attempts. These insights empower defenders to respond swiftly to emerging threats and harden their environments against advanced persistent threats.\r\n\r\n1. **Detect Ransomware Activity (Macaw ransomware):** Highlights behaviors and patterns consistent with Macaw ransomware execution and spread.\r\n2. **SQL queries with suspicious stored procedures:** Surfaces anomalous or risky stored procedure executions that may indicate malicious activity.\r\n3. **Detect Known Ransomware Hashes or IOCs:** Flags files and activities matching ransomware indicators from threat intelligence feeds. \r\n4. **Unusual SMB/Network Activity (possible worm/ransomware spread):** Detects abnormal SMB or lateral-movement traffic often linked to worm/ransomware propagation.\r\n4. **Password Spray / Credential Stuffing(Multiple failed login attempts on a single account in a short window):** Identifies multiple failed login attempts on a single account in a short timeframe.<br>\r\n\r\n**<u>Audit Trail Reporting Tab</u>**  \r\nProvides detailed visibility into HIPAA asset activities, including network traffic, running processes, and security events. This tab enables auditors and security teams to track user and system activity for compliance, investigation, and forensic analysis.:\r\n\r\n1. **Network Traffic logs of HIPAA assets:** Displays captured network traffic messages from HIPAA assets to help identify unusual communication patterns or anomalies.\r\n2. **Process running on HIPAA assets:** Lists all processes executing on HIPAA assets to detect unauthorized or suspicious applications.\r\n3. **Security events of HIPAA assets** Shows security-related events (logins, account activity, parent process relationships) to support compliance audits and threat investigations. <br>\r\n\r\n**<u>Further Analysis Tab</u>**  \r\nThis Workbook tab provides users with the ability to dive deeper into these results, with pre-written queries provided for export and further exploration.  ",
              "style": "upsell"
            },
            "name": "text - 1"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "seltab",
        "comparison": "isEqualTo",
        "value": "gettingstarted"
      },
      "name": "GettingStartedGroup"
    },
    {
      "type": 12,
      "content": {
        "version": "NotebookGroup/1.0",
        "groupType": "editable",
        "items": [
          {
            "type": 1,
            "content": {
              "json": "## For complete analysis, We are providing the analytic KQL queries through which more in depth detailed can be extracted .",
              "style": "info"
            },
            "name": "text - 0"
          },
          {
            "type": 1,
            "content": {
              "json": "### Steps on how to run the query :\r\n\r\n1> Search and Select microsoft sentinel on azure portal </br>\r\n2> choose the correct workspace </br>\r\n3> choose logs and then paste the query </br>\r\n4> Run it for suitable time range </br>",
              "style": "info"
            },
            "name": "text - 1"
          },
          {
            "type": 1,
            "content": {
              "json": "## Query for Defender for Endpoint (Antivirus) Status </br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nDeviceInfo</br>\r\n| where DeviceName != \"\"</br>\r\n|extend split_devicename = split(DeviceName, \".\" ,0)[0]</br>\r\n|where split_devicename in~ (watchlist)</br>\r\n| summarize arg_max(TimeGenerated, OSPlatform, DeviceName, OnboardingStatus, SensorHealthState, </br>ExposureLevel, IsExcluded) by DeviceName\r\n| extend OnboardingStatus = case(\r\n        OnboardingStatus == \"Can be onboarded\" or OnboardingStatus == \"Insufficient info\", \"Not Onboarded\",\r\n        OnboardingStatus // otherwise keep original value\r\n    )\r\n| project TimeGenerated, DeviceName, OSPlatform, OnboardingStatus, SensorHealthState, </br>ExposureLevel, IsExcluded\r\n| extend SensorHealthState = iff(SensorHealthState==\"Active\" and OnboardingStatus == \"Onboarded\",\"🟩 Active\", iff(SensorHealthState==\"Inactive\" and OnboardingStatus == \"Onboarded\",\"🟥 Inactive\",SensorHealthState))</br>\r\n| extend HealthOrder = case(\r\n        SensorHealthState contains \"Inactive\", 1,\r\n        SensorHealthState contains \"Active\", 2,\r\n        3 // fallback for other states\r\n    )</br>\r\n| order by HealthOrder asc, TimeGenerated desc</br>\r\n| project-away HealthOrder</br>\r\n</br>\r\n</br>\r\n## Dangerous Crud operations performed by DB users </br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nAzureDiagnostics</br>\r\n| where Category == \"SQLSecurityAuditEvents\"</br>\r\n|where Resource in~ (watchlist) or server_instance_name_s in~ (watchlist) or LogicalServerName_s </br>in~ (watchlist)\r\n| extend CRUDOperation = case(\r\n        statement_s startswith \"SELECT\", \"READ\",\r\n        statement_s startswith \"INSERT\", \"CREATE\",\r\n        statement_s startswith \"UPDATE\", \"UPDATE\",\r\n        statement_s startswith \"DELETE\", \"DELETE\",\r\n        statement_s startswith \"DROP\", \"DELETE\",            // <-- NEW: drop table/database = delete\r\n        statement_s startswith \"TRUNCATE\", \"DELETE\",        // <-- NEW: truncate table = delete\r\n        statement_s startswith \"ALTER\", \"MODIFY\",\r\n        statement_s startswith \"CREATE\", \"CreateTable\",\r\n        statement_s startswith \"\", \"Null\",           // <-- NEW: schema/role change\r\n        \"OTHER\"\r\n    )</br>\r\n| project TimeGenerated, LogicalServerName_s, session_server_principal_name_s, client_ip_s, CRUDOperation, statement_s , Resource\r\n</br>\r\n</br>\r\n## DB Users MFA status</br>\r\nlet watchlist = (_GetWatchlist('hipaa_users_details') |project UserName);\r\nSigninLogs</br>\r\n|where isnotempty(UserPrincipalName)</br>\r\n|where UserPrincipalName in~ (watchlist) or UserDisplayName in~ (watchlist)\r\n| project UserPrincipalName,\r\n          AuthenticationRequirement,          // \"singleFactorAuthentication\" or \"multiFactorAuthentication\"\r\n          AuthenticationDetails,\r\n          ResultType,\r\n          ResultDescription,\r\n          ConditionalAccessStatus,\r\n          TimeGenerated,\r\n          UserDisplayName\r\n| summarize SignIns = count(),\r\n            MFASuccess = countif(AuthenticationRequirement == \"multiFactorAuthentication\")\r\n        by UserPrincipalName,UserDisplayName</br>\r\n| extend MFAStatus = iff(MFASuccess > 0, \"MFA Used\", \"No MFA Used\"), MFAFailure = SignIns - MFASuccess</br>\r\n| sort by MFAStatus desc, SignIns desc\r\n</br>\r\n</br>\r\n## Incidents on HIPAA Servers </br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nlet myAlert = SecurityAlert  </br>\r\n| mv-expand Entity = todynamic(Entities)</br>\r\n| extend EntityType = tostring(Entity.Type)</br>\r\n| extend DeviceName = iff(EntityType == \"host\", tostring(Entity.HostName), \"\")</br>\r\n| where DeviceName != \"\" and DeviceName in~ (watchlist)</br>\r\n| summarize \r\n    DeviceName = make_set(DeviceName), \r\n    AlertName = any(AlertName), \r\n    AlertSeverity = any(AlertSeverity), \r\n    TimeGenerated = any(TimeGenerated),\r\n    ProductName = any(ProductName), \r\n    Tactics = any(Tactics), \r\n    CompromisedEntity = any(CompromisedEntity), \r\n    AlertLink = any(AlertLink)\r\n    by AlertId = SystemAlertId;</br>\r\nmyAlert</br>\r\n| join kind=inner (\r\n    SecurityIncident\r\n    | mv-expand AlertIds\r\n    | extend AlertId = tostring(AlertIds)\r\n    | project IncidentName, IncidentNumber, Title, Severity, Status, IncidentCreatedTime = TimeGenerated, AlertId</br>\r\n) on AlertId</br>\r\n| summarize </br>\r\n    DeviceName = make_set(DeviceName) \r\n    by IncidentNumber, Title, Severity, Status, Tactics, ProductName, AlertLink\r\n| extend SeverityOrder = case(\r\n    Severity == \"High\", 1,\r\n    Severity == \"Medium\", 2,\r\n    Severity == \"Low\", 3,\r\n    4 // for anything else (Informational, Unknown)\r\n)</br>\r\n| order by SeverityOrder asc</br>\r\n| project-away SeverityOrder</br>\r\n</br>\r\n</br>\r\n## Detect Ransomware Activity (Macaw ransomware)</br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nDeviceProcessEvents</br>\r\n| where ProcessCommandLine has_any(\r\n    \"-ExclusionPath\", \"Set-MpPreference\", \"advfirewall\", \"-ExclusionExtension\",\r\n    \"-EnableControlledFolderAccess\", \"windefend\", \"onstart\", \"bcdedit\", \"Startup\"\r\n)</br>\r\n|extend split_devicename = split(DeviceName, \".\" ,0)[0]</br>\r\n|where split_devicename in~ (watchlist)</br>\r\n| summarize ProcessCommandLine = make_set(ProcessCommandLine) by DeviceName, DeviceId, bin(TimeGenerated, 6h)</br>\r\n// Convert to \"Found\"/\"Not Found\"\r\n| extend StartUpExclusionPath = iif(ProcessCommandLine has_all(\"-ExclusionPath\", \"Startup\"), \"Found\", \"Not Found\")</br>\r\n| extend DefenderTamp = iif(\r\n    ProcessCommandLine has \"Set-MpPreference\" and ProcessCommandLine has_any(\r\n        \"-SevereThreatDefaultAction 6\", \r\n        \"-HighThreatDefaultAction 6\", \r\n        \"-ModerateThreatDefaultAction 6\", \r\n        \"-LowThreatDefaultAction 6\", \r\n        \"-ScanScheduleDay 8\"\r\n    ), \"Found\", \"Not Found\")</br>\r\n| extend NetshFirewallTampering = iif(ProcessCommandLine has_all(\"netsh\", \"advfirewall\", \"allprofiles state off\"), \"Found\", \"Not Found\")</br>\r\n| extend BatExclusion = iif(ProcessCommandLine has_all(\"-ExclusionExtension\", \".bat\"), \"Found\", \"Not Found\")</br>\r\n| extend ExeExclusion = iif(ProcessCommandLine has_all(\"-ExclusionExtension\", \".exe\"), \"Found\", \"Not Found\")</br>\r\n| extend DisableControlledFolderAccess = iif(ProcessCommandLine has_all(\"-EnableControlledFolderAccess\", \"Disabled\"), \"Found\", \"Not Found\")\r\n| extend ScDeleteDefend = iif(ProcessCommandLine has_all(\"sc\", \"delete\", \"windefend\"), \"Found\", \"Not Found\")</br>\r\n| extend BootTampering = iif(ProcessCommandLine has_all(\"bcdedit\", \"default\") and ProcessCommandLine has_any(\"recoveryenabled No\", \"bootstatuspolicy ignoreallfailures\"), \"Found\", \"Not Found\")</br>\r\n| extend SchTasks = iif(ProcessCommandLine has_all(\"/sc\", \"onstart\", \"system\", \"/create\", \"/delay\"), \"Found\", \"Not Found\")</br>\r\n// Count how many were \"Found\"\r\n| extend EvidenceCount = countof(tostring(pack_array(\r\n    iff(StartUpExclusionPath == \"Found\", 1, 0),\r\n    iff(DefenderTamp == \"Found\", 1, 0),\r\n    iff(NetshFirewallTampering == \"Found\", 1, 0),\r\n    iff(BatExclusion == \"Found\", 1, 0),\r\n    iff(ExeExclusion == \"Found\", 1, 0),\r\n    iff(DisableControlledFolderAccess == \"Found\", 1, 0),\r\n    iff(ScDeleteDefend == \"Found\", 1, 0),\r\n    iff(BootTampering == \"Found\", 1, 0),\r\n    iff(SchTasks == \"Found\", 1, 0)\r\n)),\"1\")</br>\r\n|sort by EvidenceCount</br>\r\n</br>\r\n</br>\r\n## Detect Known Ransomware Hashes or IOCs</br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nDeviceFileEvents</br>\r\n|where isnotempty(SHA256)</br>\r\n|extend split_devicename = split(DeviceName, \".\" ,0)[0]</br>\r\n|where split_devicename in~ (watchlist)</br>\r\n| join kind=inner (ThreatIntelIndicators |where ObservableKey == \"file:hashes.'SHA-256'\") on $left.SHA256 == $right.ObservableValue</br>\r\n| project TimeGenerated, DeviceName, FileName, SHA256, Data.description</br>\r\n<br>\r\n<br>\r\n## Unusual SMB/Network Activity (possible worm/ransomware spread)<br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nDeviceNetworkEvents</br>\r\n|extend split_devicename = split(DeviceName, \".\" ,0)[0]</br>\r\n|where split_devicename in~ (watchlist)</br>\r\n| where ActionType == \"ConnectionSuccess\"</br>\r\n| where RemotePort == 445 or RemotePort == 139</br>\r\n| summarize Connections = count(), DistinctTargets = dcount(RemoteIP) by DeviceName, bin(TimeGenerated, 1d) </br>\r\n|sort by DistinctTargets</br>\r\n<br>\r\n<br>\r\n## Network Traffic logs of HIPAA assets<br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nAzureDiagnostics</br>\r\n|where isnotempty(msg_s)</br>\r\n|where Resource in~ (watchlist)</br>\r\n|summarize count() by Resource ,msg_s</br>\r\n|project-away count_ </br>\r\n<br>\r\n<br>\r\n## Process running on HIPAA assets<br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nunion SecurityEvent,Syslog </br>\r\n|where Computer in~ (watchlist)</br>\r\n|where Process != \"\"</br>\r\n|extend Process = coalesce(Process,ProcessName)</br>\r\n|summarize count() by Process,Computer</br>\r\n|project-away count_</br>\r\n<br>\r\n<br>\r\n## Security events of HIPAA assets<br>\r\nlet watchlist = (_GetWatchlist('hipaa_assets') |project DeviceName );</br>\r\nSecurityEvent </br>\r\n|where isnotempty(Account)</br>\r\n|where Computer in~ (watchlist)</br>\r\n| summarize count() by Account , AccountType ,Computer , Activity ,ParentProcessName</br>",
              "style": "upsell"
            },
            "name": "text - 2"
          }
        ]
      },
      "conditionalVisibility": {
        "parameterName": "seltab",
        "comparison": "isEqualTo",
        "value": "furtheranalysis"
      },
      "name": "furtheranalysisgroup"
    }
  ],
  "fromTemplateId": "sentinel-HIPAAComplianceWorkbook",
  "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
}
