Merge pull request #4139 from clivewatson/UserMapv1.4

User Map v1.4
This commit is contained in:
NikTripathi 2022-04-05 14:58:25 +05:30 коммит произвёл GitHub
Родитель 0e1f5815ac eff79bbf8b
Коммит 61fbcdb4f2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 270 добавлений и 171 удалений

Двоичные данные
Workbooks/Images/Preview/UserMapBlack.png Normal file

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

После

Ширина:  |  Высота:  |  Размер: 29 KiB

Двоичные данные
Workbooks/Images/Preview/UserMapWhite.png Normal file

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

После

Ширина:  |  Высота:  |  Размер: 33 KiB

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

@ -5,6 +5,9 @@
"type": 9,
"content": {
"version": "KqlParameterItem/1.0",
"crossComponentResources": [
"{Subscription}"
],
"parameters": [
{
"id": "1ca69445-60fc-4806-b43d-ac7e6aad630a",
@ -16,7 +19,8 @@
"typeSettings": {
"additionalResourceOptions": [],
"includeAll": false
}
},
"label": "☁️ Subscription"
},
{
"id": "e94aafa3-c5d9-4523-89f0-4e87aa754511",
@ -36,7 +40,7 @@
},
"queryType": 1,
"resourceType": "microsoft.resourcegraph/resources",
"value": "/subscriptions/d1d8779d-38d7-4f06-91db-9cbc8de0176f/resourceGroups/SOC/providers/Microsoft.OperationalInsights/workspaces/CyberSecuritySOC"
"label": "🗂️ Workspace"
},
{
"id": "c4b69c01-2263-4ada-8d9c-43433b739ff3",
@ -45,7 +49,7 @@
"type": 4,
"isRequired": true,
"value": {
"durationMs": 5184000000
"durationMs": 1209600000
},
"typeSettings": {
"selectableValues": [
@ -93,7 +97,8 @@
}
],
"allowCustom": true
}
},
"label": "⏱️ Time Range"
},
{
"id": "6ed3bbc6-be3f-44ed-84b3-9908e7c92315",
@ -104,11 +109,12 @@
"typeSettings": {
"additionalResourceOptions": []
},
"jsonData": "[\r\n { \"value\": \"Yes\", \"label\": \"Yes\"},\r\n {\"value\": \"No\", \"label\": \"No\", \"selected\":true },\r\n { \"value\": \"Change Log\", \"label\": \"Change Log\"}\r\n]"
"jsonData": "[\r\n { \"value\": \"Yes\", \"label\": \"Yes\"},\r\n {\"value\": \"No\", \"label\": \"No\", \"selected\":true },\r\n { \"value\": \"Change Log\", \"label\": \"Change Log\"}\r\n]",
"label": "📖 Help"
}
],
"style": "above",
"queryType": 0,
"queryType": 1,
"resourceType": "microsoft.resourcegraph/resources"
},
"customWidth": "70",
@ -189,7 +195,7 @@
{
"type": 1,
"content": {
"json": "#### Tab One. Malicious IP \r\nThis report can get data from a number of sources (six are defined in this release) to show the distance from the Malicious IP addresses to a selected users default location. \r\nYou may see an error if one or more data sources are missing. There will be no entries if *all* sources are missing - there is a warning dialog box displayed if this happens.\r\nThis is a similar view to the one shown on the Summary page of Azure Sentinel, but this is showing distance data as well.\r\nThere are three options to aid filtering:\r\n1. Select a Location from a list (for that you will have to edit this workbook and amend the \"CityList\" parameter if you require changes to the capital cities I have provided). Please save the JSON of any co-ordinates you add, as you will need to add them back if you ever update the workbook to a newer version. This is useful if you have some office locations or important places that you wish to add.\r\n2. Select from Azure Active Directory (AAD), if the SigninLogs table exists, this will populate from the latest record, a entry per City /( Country ) with Longitude and Latitude data.\r\n3. Enter a Latitude and Longitude of your choice, and a label to describe the location. \r\nYou may also select to show the data in Kilometers (KM) or Miles. You can also set how many locations to show, 5, 10, 20 etc...\r\n\r\nDatasources: WireData, VMconnection, CommonSecurityLog, WindowsFirewall, W3CIISLog and DnsEvents \r\n\t\t\t Note: SigninLogs is required to build the AAD list, if you dont have this critical datasource, please use options #1 or #3.\r\n\r\n#### Tab two. Locations and distances (User Data)\r\nInformation using Azure Active Directory (AAD) Signinlogs data, this shows user Signin Locations and distance between as well as order visited (you select a User from dropdown options, ordered by their signin count). \r\n\r\nDatasources:SigninLogs\r\n\r\n#### Tab three. Microsoft WAF \r\nShow Azure Front door and Application Gateway Web Application Firewall \r\n\r\nDatasources: AzureDiagnostics\r\n",
"json": "#### Tab One. Malicious IP \r\nThis report can get data from a number of sources (six are defined in this release) to show the distance from the Malicious IP addresses to a selected users default location. \r\nYou may see an error if one or more data sources are missing. There will be no entries if *all* sources are missing - there is a warning dialog box displayed if this happens.\r\nThis is a similar view to the one shown on the Summary page of Azure Sentinel, but this is showing distance data as well.\r\nThere are three options to aid filtering:\r\n1. Select a Location from a list (for that you will have to edit this workbook and amend the \"CityList\" parameter if you require changes to the capital cities I have provided). Please save the JSON of any co-ordinates you add, as you will need to add them back if you ever update the workbook to a newer version. This is useful if you have some office locations or important places that you wish to add.\r\n2. Select from Azure Active Directory (AAD), if the SigninLogs table exists, this will populate from the latest record, a entry per City /( Country ) with Longitude and Latitude data.\r\n3. Enter a Latitude and Longitude of your choice, and a label to describe the location. \r\nYou may also select to show the data in Kilometers (KM) or Miles. You can also set how many locations to show, 5, 10, 20 etc...\r\n4. Use a Watchlist. Create a Watchlist. The csv file, needs a row with three columns Long, Lat, City (City will be the searchkey). You must set the Watchlist Alias to **userMapCityList**\r\n\r\n|Long|Lat|City|\r\n|---|---|---|\r\n|51.507351\t|-0.127758\t|London|\r\n|48.856613\t|2.352222\t|Paris|\r\n| etc...\r\n\r\n\r\nDatasources: WireData, VMconnection, CommonSecurityLog, WindowsFirewall, W3CIISLog and DnsEvents \r\n\t\t\t Note: SigninLogs is required to build the AAD list, if you dont have this critical datasource, please use options #1 or #3.\r\n\r\n#### Tab two. Locations and distances (User Data)\r\nInformation using Azure Active Directory (AAD) Signinlogs data, this shows user Signin Locations and distance between as well as order visited (you select a User from dropdown options, ordered by their signin count). \r\n\r\nDatasources:SigninLogs\r\n\r\n#### Tab three. Microsoft WAF \r\nShow Azure Front door and Application Gateway Web Application Firewall \r\n\r\nDatasources: AzureDiagnostics\r\n",
"style": "info"
},
"conditionalVisibility": {
@ -202,7 +208,7 @@
{
"type": 1,
"content": {
"json": "### Change Log\r\n|Version|Description|\r\n|---|---|\r\n|v1.0\t|Initial Version|\r\n|V1.1.0\t|Updated from 2019 version, combining new features and improving the look and feel. | \r\n|V1.1.1\t|Updated chart to display Location, Latitude, Longitude when a region is clicked| \r\n|V1.2\t|Added info when you select a region on the 'Map showing locations for User', fixed a time display message. Added dwell time (the time delay between the entries), in the \"looking for\" grid to augment the distance travelled.|\r\n|V1.3| Add support for a drop down warning, and UserMap user selection options (user by count, User by first Letter & free text search) |"
"json": "### Change Log\r\n|Version|Description|\r\n|---|---|\r\n|v1.0\t|Initial Version|\r\n|V1.1.0\t|Updated from 2019 version, combining new features and improving the look and feel. | \r\n|V1.1.1\t|Updated chart to display Location, Latitude, Longitude when a region is clicked| \r\n|V1.2\t|Added info when you select a region on the 'Map showing locations for User', fixed a time display message. Added dwell time (the time delay between the entries), in the \"looking for\" grid to augment the distance travelled.|\r\n|V1.3| Add support for a drop down warning, and UserMap user selection options (user by count, User by first Letter & free text search) |\r\n|V1.4\t| Add GeoLocation api from Microsoft. Add a watchlist alias == userMapCityList|"
},
"conditionalVisibility": {
"parameterName": "Help",
@ -231,13 +237,14 @@
"type": 10,
"isRequired": true,
"typeSettings": {
"additionalResourceOptions": []
"additionalResourceOptions": [],
"showDefault": false
},
"jsonData": "[\r\n { \"value\": \"mylist\", \"label\": \"From a list\",\"selected\":true},\r\n {\"value\": \"aad\", \"label\": \"From AAD\"},\r\n { \"value\": \"manual\", \"label\": \"Add a manual entry\"}\r\n]",
"jsonData": "[\r\n { \"value\": \"mylist\", \"label\": \"From a list\",\"selected\":true},\r\n { \"value\": \"aad\", \"label\": \"From AAD\"},\r\n { \"value\": \"manual\", \"label\": \"Add a manual entry\"},\r\n { \"value\": \"watchlist\", \"label\": \"From a Watchlist\"}\r\n ]",
"timeContext": {
"durationMs": 86400000
},
"value": "aad"
"value": "watchlist"
}
],
"style": "above",
@ -260,7 +267,7 @@
"type": 2,
"description": "Edit this parameter to provide your own locations - please see Help",
"isRequired": true,
"value": "48.856613,2.352222",
"value": "-33.865143,151.209900",
"typeSettings": {
"additionalResourceOptions": [],
"showDefault": false
@ -272,7 +279,6 @@
"version": "KqlParameterItem/1.0",
"name": "defaultCityList",
"type": 1,
"value": "Paris",
"isHiddenWhenLocked": true,
"criteriaData": [
{
@ -324,7 +330,7 @@
"crossComponentResources": [
"{Workspace}"
],
"value": "Aeroskobing (DK),54.89149856567382,10.40470027923584",
"value": "Amsterdam (NL),52.30905151367188,4.940189838409424",
"typeSettings": {
"additionalResourceOptions": [],
"showDefault": false
@ -338,7 +344,6 @@
"name": "defaultCityListAAD",
"type": 1,
"isRequired": true,
"value": "Aeroskobing (DK),54.89149856567382,10.40470027923584",
"isHiddenWhenLocked": true,
"criteriaData": [
{
@ -373,10 +378,91 @@
},
"name": "parameters - aad"
},
{
"type": 9,
"content": {
"version": "KqlParameterItem/1.0",
"crossComponentResources": [
"{watchlistWorkspace}"
],
"parameters": [
{
"id": "83f03fac-040e-45c4-88d6-a7657a5e0139",
"version": "KqlParameterItem/1.0",
"name": "watchlistSubscription",
"label": "☁️ WatchList Sub",
"type": 6,
"description": "Alternate Subscription/Workspace if the watchlist is centrally stored",
"isRequired": true,
"value": "",
"typeSettings": {
"additionalResourceOptions": [],
"includeAll": false,
"showDefault": false
},
"timeContext": {
"durationMs": 2592000000
}
},
{
"id": "482aba80-177d-4742-bb9c-1f5e84dcf63c",
"version": "KqlParameterItem/1.0",
"name": "watchlistWorkspace",
"label": "🗂️ watchlist Workspace",
"type": 5,
"isRequired": true,
"query": "Resources \r\n| where type =~ \"microsoft.operationalinsights/workspaces\" \r\n| order by name \r\n| project id, name, selected=row_number()==1, group=resourceGroup",
"crossComponentResources": [
"{watchlistSubscription}"
],
"value": "",
"typeSettings": {
"additionalResourceOptions": []
},
"timeContext": {
"durationMs": 2592000000
},
"queryType": 1,
"resourceType": "microsoft.resourcegraph/resources"
},
{
"id": "0bf475c1-3f4f-4daf-9b9e-21184856d237",
"version": "KqlParameterItem/1.0",
"name": "watchList",
"label": "watchList City",
"type": 2,
"description": "Watchlist alias: userMapCityList required, please see Help",
"query": "let wl_ = _GetWatchlist('userMapCityList');\r\nlet Long = dynamic(['']);\r\nlet Lat = dynamic(['']);\r\nlet SearchKey = dynamic(['']);\r\nwl_ \r\n| order by SearchKey asc\r\n| extend a = iif(isnotempty(SearchKey),1,0)\r\n| project value=strcat(Long,',', Lat), display=SearchKey, selected=row_number()==1",
"crossComponentResources": [
"{watchlistWorkspace}"
],
"typeSettings": {
"additionalResourceOptions": [],
"showDefault": false
},
"timeContext": {
"durationMs": 0
},
"timeContextFromParameter": "TimeRange",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces"
}
],
"style": "above",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces"
},
"conditionalVisibility": {
"parameterName": "getLocation",
"comparison": "isEqualTo",
"value": "watchlist"
},
"name": "parameters - watchList"
},
{
"type": 1,
"content": {
"json": "### Please select a Location, or confirm data source: SigninLogs exists\r\n\tif there are no values you may not have the [SigninLogs] table in this workspace.\r\nPlease use a Location Selection of:\r\n\r\n\tFrom a List\r\nor\r\n\r\n\tAdd a manual entry\r\n",
"json": "### Please select a Location, or confirm data source: SigninLogs exists\r\n\tif there are no values you may not have the [SigninLogs] table in this workspace.\r\nPlease use a Location Selection of:\r\n\r\n\tFrom a List\r\nor\r\n\r\n\tAdd a manual entry\r\nor\r\n\r\n\tFrom a Watchlist called userMapCityList\r\n",
"style": "warning"
},
"conditionalVisibilities": [
@ -404,7 +490,6 @@
"name": "Latitude",
"type": 1,
"description": "Add a Latitude value",
"value": "51.461377",
"criteriaData": [
{
"criteriaContext": {
@ -422,7 +507,6 @@
"name": "Longitude",
"type": 1,
"description": "Add a Longitude value",
"value": "-0.925915",
"criteriaData": [
{
"criteriaContext": {
@ -435,12 +519,10 @@
]
},
{
"id": "e10c4b13-f3af-4faf-a5cd-605b7660c019",
"version": "KqlParameterItem/1.0",
"name": "defaultLocationName",
"type": 1,
"description": "Add a name for your custom Latitude/Longitude",
"value": "Microsoft Campus, Reading (UK)",
"criteriaData": [
{
"criteriaContext": {
@ -450,7 +532,8 @@
"resultVal": "Microsoft Campus, Reading (UK)"
}
}
]
],
"id": "945b9c5e-c7f0-419f-99d7-58a389290f80"
}
],
"style": "above",
@ -478,7 +561,7 @@
"version": "KqlParameterItem/1.0",
"name": "locationName",
"type": 1,
"query": " // create a common location for chart titles\r\n extend locationName = case( \r\n '{getLocation}' == 'mylist', '{defaultCityList}',\r\n '{getLocation}' == 'aad' , '{defaultCityListAAD}',\r\n '{getLocation}' == 'manual', '{defaultLocationName}',\r\n //else\r\n \"fail\"\r\n )\r\n|project locationName | limit 1",
"query": " // create a common location for chart titles\r\n extend locationName = case( \r\n '{getLocation}' == 'mylist', '{defaultCityList}',\r\n '{getLocation}' == 'aad' , '{defaultCityListAAD}',\r\n '{getLocation}' == 'manual', '{defaultLocationName}',\r\n '{getLocation}' == 'watchlist', '{watchList:label}',\r\n //else\r\n \"fail\"\r\n )\r\n|project locationName | limit 1",
"crossComponentResources": [
"{Subscription}"
],
@ -500,11 +583,11 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "// Look back at data and see if any from six named tables have Malicious IP info \r\n// This query is based on the Sentinel home page \"Potential malicious events\" view \r\n// We'll also enrich the data with distance data (in KM or miles) of each entry to defined home location \r\n//\r\n// Please enter how many days worth of data to look at?\r\n// Microsoft Campus UK is used as a base parameter - adjust as required with your own Location Longitude / Latitude \r\n// isFuzzy will allow us to continue on errors or if a table is empty etc...\r\nunion isfuzzy=true \r\n(W3CIISLog\r\n| extend TrafficDirection = \"InboundOrUnknown\", Country=RemoteIPCountry, Latitude=RemoteIPLatitude, Longitude=RemoteIPLongitude), \r\n(DnsEvents\r\n| extend TrafficDirection = \"InboundOrUnknown\", Country= RemoteIPCountry, Latitude = RemoteIPLatitude, Longitude = RemoteIPLongitude),\r\n(WireData\r\n| extend TrafficDirection = iff(Direction != \"Outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=RemoteIPCountry, Latitude=RemoteIPLatitude, Longitude=RemoteIPLongitude), \r\n(WindowsFirewall\r\n| extend TrafficDirection = iff(CommunicationDirection != \"SEND\",\"InboundOrUnknown\", \"Outbound\"), Country=MaliciousIPCountry, Latitude=MaliciousIPLatitude, Longitude=MaliciousIPLongitude), \r\n(CommonSecurityLog\r\n| extend TrafficDirection = iff(CommunicationDirection != \"Outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=MaliciousIPCountry, Latitude=MaliciousIPLatitude, Longitude=MaliciousIPLongitude, Confidence=ThreatDescription, Description=ThreatDescription), \r\n(VMConnection\r\n| where Type == \"VMConnection\"\r\n| extend TrafficDirection = iff(Direction != \"outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=RemoteCountry, Latitude=RemoteLatitude, Longitude=RemoteLongitude)\r\n// Start of main logic\r\n// Supply a default location (long/lat) from selected parameter \r\n| extend myLatitude = case( \r\n '{getLocation}' == 'mylist', todouble(split('{CityList:value}',\",\").[0]),\r\n '{getLocation}' == 'aad' , todouble(split('{defaultCityListAAD:value}',\",\").[1]),\r\n '{getLocation}' == 'manual', todouble({Latitude}),\r\n //else\r\n todouble(0)\r\n )\r\n| extend myLongitude = case( \r\n '{getLocation}' == 'mylist', todouble(split('{CityList:value}',\",\").[1]),\r\n '{getLocation}' == 'aad' , todouble(split('{defaultCityListAAD:value}',\",\").[2]),\r\n '{getLocation}' == 'manual', todouble({Longitude}),\r\n //else\r\n todouble(0)\r\n )\r\n| where isnotempty(MaliciousIP) and isnotempty(Country) and isnotempty(Latitude) and isnotempty(Longitude)\r\n// measure the distance between the base/city and maliciousIP location in km or miles\r\n| extend distance_in = iif('{Measurement}' == \"KM\", geo_distance_2points(Longitude, Latitude, myLongitude, myLatitude)/1000.00, geo_distance_2points(Longitude, Latitude, myLongitude, myLatitude)/1609.344 )\r\n| summarize count(), arg_max(TimeGenerated,TimeGenerated) by Country, distance_in, Latitude , Longitude, '{getLocation}', myLatitude, myLongitude\r\n| top {Top} by count_\r\n\r\n",
"query": "// Look back at data and see if any from six named tables have Malicious IP info \r\n// This query is based on the Sentinel home page \"Potential malicious events\" view \r\n// We'll also enrich the data with distance data (in KM or miles) of each entry to defined home location \r\n//\r\n// Please enter how many days worth of data to look at?\r\n// Microsoft Campus UK is used as a base parameter - adjust as required with your own Location Longitude / Latitude \r\n// isFuzzy will allow us to continue on errors or if a table is empty etc...\r\nunion isfuzzy=true \r\n(W3CIISLog\r\n| extend TrafficDirection = \"InboundOrUnknown\", Country=RemoteIPCountry, Latitude=RemoteIPLatitude, Longitude=RemoteIPLongitude), \r\n(DnsEvents\r\n| extend TrafficDirection = \"InboundOrUnknown\", Country= RemoteIPCountry, Latitude = RemoteIPLatitude, Longitude = RemoteIPLongitude),\r\n(WireData\r\n| extend TrafficDirection = iff(Direction != \"Outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=RemoteIPCountry, Latitude=RemoteIPLatitude, Longitude=RemoteIPLongitude), \r\n(WindowsFirewall\r\n| extend TrafficDirection = iff(CommunicationDirection != \"SEND\",\"InboundOrUnknown\", \"Outbound\"), Country=MaliciousIPCountry, Latitude=MaliciousIPLatitude, Longitude=MaliciousIPLongitude), \r\n(CommonSecurityLog\r\n| extend TrafficDirection = iff(CommunicationDirection != \"Outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=MaliciousIPCountry, Latitude=MaliciousIPLatitude, Longitude=MaliciousIPLongitude, Confidence=ThreatDescription, Description=ThreatDescription), \r\n(VMConnection\r\n| where Type == \"VMConnection\"\r\n| extend TrafficDirection = iff(Direction != \"outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=RemoteCountry, Latitude=RemoteLatitude, Longitude=RemoteLongitude)\r\n// Start of main logic\r\n// Supply a default location (long/lat) from selected parameter \r\n| extend myLatitude = case( \r\n '{getLocation}' == 'mylist', todouble(split('{CityList:value}',\",\").[0]),\r\n '{getLocation}' == 'aad' , todouble(split('{defaultCityListAAD:value}',\",\").[1]),\r\n '{getLocation}' == 'manual', todouble({Latitude}),\r\n '{getLocation}' == 'watchlist', split('{watchList:value}',\",\").[1],\r\n //else\r\n todouble(0)\r\n )\r\n| extend myLongitude = case( \r\n '{getLocation}' == 'mylist', todouble(split('{CityList:value}',\",\").[1]),\r\n '{getLocation}' == 'aad' , todouble(split('{defaultCityListAAD:value}',\",\").[2]),\r\n '{getLocation}' == 'manual', todouble({Longitude}),\r\n '{getLocation}' == 'watchlist', split('{watchList:value}',\",\").[0],\r\n //else\r\n todouble(0)\r\n )\r\n| where isnotempty(MaliciousIP) and isnotempty(Country) and isnotempty(Latitude) and isnotempty(Longitude)\r\n// measure the distance between the base/city and maliciousIP location in km or miles\r\n| extend distance_in = iif('{Measurement}' == \"KM\", geo_distance_2points(Longitude, Latitude, myLongitude, myLatitude)/1000.00, geo_distance_2points(Longitude, Latitude, myLongitude, myLatitude)/1609.344 )\r\n| summarize count(), arg_max(TimeGenerated,TimeGenerated) by Country, distance_in, Latitude , Longitude, '{getLocation}', myLatitude, myLongitude\r\n| top {Top} by count_\r\n\r\n",
"size": 0,
"title": "Top: '{Top}' Malicious IP distances from {locationName} in ('{Measurement}') ",
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"exportParameterName": "Selected",
@ -514,20 +597,7 @@
"{Workspace}"
],
"visualization": "map",
"gridSettings": {
"sortBy": [
{
"itemKey": "distance_in",
"sortOrder": 2
}
]
},
"sortBy": [
{
"itemKey": "distance_in",
"sortOrder": 2
}
],
"sortBy": [],
"graphSettings": {
"type": 0,
"topContent": {
@ -566,76 +636,6 @@
"customWidth": "50",
"name": "query - 8"
},
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "// Look back at data and see if any from six named tables have Malicious IP info \r\n// This query is based on the Sentinel home page \"Potential malicious events\" view \r\n// We'll also enrich the data with distance data (in KM or miles) of each entry to defined home location \r\n//\r\n// Please enter how many days worth of data to look at?\r\n// Microsoft Campus UK is used as a base parameter - adjust as required with your own Location Longitude / Latitude \r\n// isFuzzy will allow us to continue on errors or if a table is empty etc...\r\nunion isfuzzy=true \r\n(W3CIISLog\r\n| extend TrafficDirection = \"InboundOrUnknown\", Country=RemoteIPCountry, Latitude=RemoteIPLatitude, Longitude=RemoteIPLongitude), \r\n(DnsEvents\r\n| extend TrafficDirection = \"InboundOrUnknown\", Country= RemoteIPCountry, Latitude = RemoteIPLatitude, Longitude = RemoteIPLongitude),\r\n(WireData\r\n| extend TrafficDirection = iff(Direction != \"Outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=RemoteIPCountry, Latitude=RemoteIPLatitude, Longitude=RemoteIPLongitude), \r\n(WindowsFirewall\r\n| extend TrafficDirection = iff(CommunicationDirection != \"SEND\",\"InboundOrUnknown\", \"Outbound\"), Country=MaliciousIPCountry, Latitude=MaliciousIPLatitude, Longitude=MaliciousIPLongitude), \r\n(CommonSecurityLog\r\n| extend TrafficDirection = iff(CommunicationDirection != \"Outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=MaliciousIPCountry, Latitude=MaliciousIPLatitude, Longitude=MaliciousIPLongitude, Confidence=ThreatDescription, Description=ThreatDescription), \r\n(\r\nAzureDiagnostics\r\n| where ResourceType == \"FRONTDOORS\" and Category == \"FrontdoorWebApplicationFirewallLog\"\r\n| extend TrafficDirection = iff(isReceivedFromClient_b != false,\"InboundOrUnknown\", \"Outbound\")\r\n),\r\n(VMConnection\r\n| where Type == \"VMConnection\"\r\n| extend TrafficDirection = iff(Direction != \"outbound\",\"InboundOrUnknown\", \"Outbound\"), Country=RemoteCountry, Latitude=RemoteLatitude, Longitude=RemoteLongitude)\r\n// Start of main logic\r\n// Supply a default location (long/lat) from selected parameter \r\n| extend myLatitude = case( \r\n '{getLocation}' == 'mylist', todouble(split('{CityList:value}',\",\").[0]),\r\n '{getLocation}' == 'aad' , todouble(split('{defaultCityListAAD:value}',\",\").[1]),\r\n '{getLocation}' == 'manual', todouble({Latitude}),\r\n //else\r\n todouble(0)\r\n )\r\n| extend myLongitude = case( \r\n '{getLocation}' == 'mylist', todouble(split('{CityList:value}',\",\").[1]),\r\n '{getLocation}' == 'aad' , todouble(split('{defaultCityListAAD:value}',\",\").[2]),\r\n '{getLocation}' == 'manual', todouble({Longitude}),\r\n //else\r\n todouble(0)\r\n )\r\n| where isnotempty(MaliciousIP) and isnotempty(Country) and isnotempty(Latitude) and isnotempty(Longitude)\r\n// measure the distance between the base/city and maliciousIP location in km or miles\r\n| extend distance_in = iif('{Measurement}' == \"KM\", geo_distance_2points(Longitude, Latitude, myLongitude, myLatitude)/1000.00, geo_distance_2points(Longitude, Latitude, myLongitude, myLatitude)/1609.344 )\r\n| summarize count(), arg_max(TimeGenerated,TimeGenerated) by Country, distance_in, Latitude , Longitude, '{getLocation}', myLatitude, myLongitude\r\n| top {Top} by count_\r\n\r\n",
"size": 0,
"title": "Top: '{Top}' Malicious IP distances from {locationName} in ('{Measurement}') ",
"timeContext": {
"durationMs": 7776000000
},
"timeContextFromParameter": "TimeRange",
"exportParameterName": "Selected",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces",
"crossComponentResources": [
"{Workspace}"
],
"visualization": "table",
"gridSettings": {
"sortBy": [
{
"itemKey": "distance_in",
"sortOrder": 2
}
]
},
"sortBy": [
{
"itemKey": "distance_in",
"sortOrder": 2
}
],
"graphSettings": {
"type": 0,
"topContent": {
"columnMatch": "Country",
"formatter": 1
},
"centerContent": {
"columnMatch": "distance_in",
"formatter": 1,
"numberFormat": {
"unit": 17,
"options": {
"maximumSignificantDigits": 3,
"maximumFractionDigits": 2
}
}
}
},
"mapSettings": {
"locInfo": "LatLong",
"latitude": "Latitude",
"longitude": "Longitude",
"sizeSettings": "count_",
"sizeAggregation": "Sum",
"labelSettings": "Country",
"legendMetric": "distance_in",
"legendAggregation": "Sum",
"itemColorSettings": {
"nodeColorField": "count_",
"colorAggregation": "Sum",
"type": "heatmap",
"heatmapPalette": "orange"
}
}
},
"customWidth": "50",
"name": "query - 8 - Copy"
},
{
"type": 3,
"content": {
@ -662,7 +662,7 @@
"showAnalytics": true,
"title": "Top: '{Top}' Malicious IP distances from {locationName} in ('{Measurement}') ",
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"showExportToExcel": true,
@ -705,9 +705,6 @@
}
],
"labelSettings": [
{
"columnId": "Country"
},
{
"columnId": "distance_in",
"label": "Distance"
@ -720,10 +717,6 @@
"columnId": "Longitude",
"label": "Destination Longitude"
},
{
"columnId": "toggle",
"label": ""
},
{
"columnId": "myLatitude",
"label": "Source Latitude"
@ -731,15 +724,6 @@
{
"columnId": "myLongitude",
"label": "Source Longitude"
},
{
"columnId": "count_"
},
{
"columnId": "TimeGenerated"
},
{
"columnId": "TimeGenerated1"
}
]
},
@ -848,7 +832,7 @@
"crossComponentResources": [
"{Workspace}"
],
"value": "Chris Boehm",
"value": "Alessio Filippin",
"typeSettings": {
"additionalResourceOptions": []
},
@ -880,7 +864,8 @@
},
"timeContextFromParameter": "TimeRange",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces"
"resourceType": "microsoft.operationalinsights/workspaces",
"value": "240 of 1000"
}
],
"style": "above",
@ -908,18 +893,17 @@
"version": "KqlParameterItem/1.0",
"name": "UserFilter",
"type": 2,
"isRequired": true,
"query": "SigninLogs\r\n| distinct UserDisplayName\r\n| project Alpha = toupper(substring(UserDisplayName,0,1))\r\n| summarize Count = count() by Alpha\r\n| order by Alpha asc\r\n| project Value=Alpha, Label=Alpha, selected = false",
"crossComponentResources": [
"{Workspace}"
],
"value": "A",
"value": "B",
"typeSettings": {
"additionalResourceOptions": [],
"showDefault": false
},
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"queryType": 0,
@ -931,18 +915,17 @@
"name": "SelectUserLetter",
"label": " Select User Letter",
"type": 2,
"isRequired": true,
"query": "SigninLogs\r\n| where UserDisplayName startswith '{UserFilter:label}'\r\n| summarize by UserDisplayName\r\n| order by UserDisplayName asc",
"crossComponentResources": [
"{Workspace}"
],
"value": "Alex Humphrey",
"value": "Banks, Alex",
"typeSettings": {
"additionalResourceOptions": [],
"showDefault": false
},
"timeContext": {
"durationMs": 0
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"queryType": 0,
@ -1115,7 +1098,7 @@
"showAnalytics": true,
"title": "Map showing locations for user: '{SelectUser}'",
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"exportedParameters": [
@ -1278,18 +1261,32 @@
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "SigninLogs\r\n| where UserDisplayName !=\"On-Premises Directory Synchronization Service Account\"\r\n| where UserDisplayName == '{SelectUser}'\r\n| extend city_ = tostring(LocationDetails.city) \r\n| extend state_ = tostring(LocationDetails.state) \r\n| extend countryOrRegion_ = tostring(LocationDetails.countryOrRegion) \r\n| extend latitude_ = tostring(parse_json(tostring(LocationDetails.geoCoordinates)).latitude) \r\n| extend longitude_ = tostring(parse_json(tostring(LocationDetails.geoCoordinates)).longitude) \r\n| order by TimeGenerated asc , city_ asc\r\n| serialize \r\n| extend pLat = prev(latitude_,1)\r\n| extend pLon = prev(longitude_,1)\r\n| extend distanceType = iif('{Measurement}' == \"KM\", todouble(1000), todouble(1609.344))\r\n| extend distance_in = iif(row_number() > 1,tostring(round(geo_distance_2points(todouble(longitude_), todouble(latitude_), todouble(pLon), todouble(pLat))/distanceType ,2)),strcat(\"FirstLocation\",' ','({Measurement})') ) \r\n| extend dwell_in = datetime_diff(\"second\",TimeGenerated, prev(TimeGenerated))\r\n| where distance_in !=\"0.0\"\r\n| summarize by TimeGenerated,\r\n UserDisplayName,\r\n City=city_ ,\r\n Location=countryOrRegion_, \r\n visitOrder = row_number(),\r\n distanceBetweenLocations = distance_in, // strcat(distance_in,' ','({Measurement})')\r\n dwell_in\r\n| order by TimeGenerated asc, visitOrder asc",
"query": "SigninLogs\r\n| where UserDisplayName !=\"On-Premises Directory Synchronization Service Account\"\r\n| where UserDisplayName == '{SelectUser}'\r\n| extend city_ = tostring(LocationDetails.city) \r\n| extend state_ = tostring(LocationDetails.state) \r\n| extend countryOrRegion_ = tostring(LocationDetails.countryOrRegion) \r\n| extend latitude_ = tostring(parse_json(tostring(LocationDetails.geoCoordinates)).latitude) \r\n| extend longitude_ = tostring(parse_json(tostring(LocationDetails.geoCoordinates)).longitude) \r\n| order by TimeGenerated asc , city_ asc\r\n| serialize \r\n| extend pLat = prev(latitude_,1)\r\n| extend pLon = prev(longitude_,1)\r\n| extend distanceType = iif('{Measurement}' == \"KM\", todouble(1000), todouble(1609.344))\r\n| extend distance_in = iif(row_number() > 1,tostring(round(geo_distance_2points(todouble(longitude_), todouble(latitude_), todouble(pLon), todouble(pLat))/distanceType ,2)),strcat(\"FirstLocation\",' ','({Measurement})') ) \r\n| extend dwell_in = datetime_diff(\"second\",TimeGenerated, prev(TimeGenerated))\r\n| where distance_in !=\"0.0\"\r\n| summarize by TimeGenerated,\r\n UserDisplayName,\r\n City=city_ ,\r\n State = state_,\r\n Location=countryOrRegion_, \r\n visitOrder = row_number(),\r\n distanceBetweenLocations = distance_in, // strcat(distance_in,' ','({Measurement})')\r\n dwell_in, IPAddress, IsRisky, ResourceGroup, AppDisplayName, ClientAppUsed, AuthenticationRequirement, ConditionalAccessStatus\r\n| order by TimeGenerated asc, visitOrder asc",
"size": 1,
"showAnalytics": true,
"title": "Looking for '{SelectUser}'",
"title": "Looking for '{SelectUser}' - click a row for more IP detail",
"color": "green",
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"exportFieldName": "Namespace",
"exportParameterName": "Namespace",
"exportDefaultValue": "All",
"exportedParameters": [
{
"fieldName": "Namespace",
"parameterName": "Namespace",
"defaultValue": "All"
},
{
"fieldName": "IPAddress",
"parameterName": "ipAddress",
"parameterType": 1
},
{
"fieldName": "ResourceGroup",
"parameterName": "resourceGroup",
"parameterType": 1
}
],
"showExportToExcel": true,
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces",
@ -1299,6 +1296,13 @@
"visualization": "table",
"gridSettings": {
"formatters": [
{
"columnMatch": "distanceBetweenLocations",
"formatter": 8,
"formatOptions": {
"palette": "greenRed"
}
},
{
"columnMatch": "dwell_in",
"formatter": 8,
@ -1315,11 +1319,8 @@
}
},
{
"columnMatch": "distanceBetweenLocations",
"formatter": 8,
"formatOptions": {
"palette": "greenRed"
}
"columnMatch": "ResourceGroup",
"formatter": 5
},
{
"columnMatch": "Table Entries",
@ -1359,23 +1360,19 @@
}
],
"filter": true,
"labelSettings": [
"sortBy": [
{
"columnId": "UserDisplayName"
},
{
"columnId": "City"
},
{
"columnId": "distanceBetweenLocations"
},
{
"columnId": "dwell_in",
"label": "Dwell time"
"itemKey": "IsRisky",
"sortOrder": 2
}
]
},
"sortBy": [],
"sortBy": [
{
"itemKey": "IsRisky",
"sortOrder": 2
}
],
"tileSettings": {
"titleContent": {
"columnMatch": "visit_order",
@ -1450,7 +1447,98 @@
}
}
},
"name": "query - 6 - Copy - Copy"
"name": "query - get User details"
},
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "{\"version\":\"ARMEndpoint/1.0\",\"data\":null,\"headers\":[],\"method\":\"GET\",\"path\":\"/subscriptions/{Workspace:subscriptionid}/resourceGroups/{resourceGroup}/providers/Microsoft.SecurityInsights/enrichment/ip/geodata/?ipaddress={ipAddress}&api-version=2021-09-01-preview\",\"urlParams\":[],\"batchDisabled\":false,\"transformers\":[{\"type\":\"jsonpath\",\"settings\":{\"tablePath\":\"$\",\"columns\":[]}}]}",
"size": 4,
"title": "🖧 Lookup IP Address: {ipAddress} from Microsoft geoLocation api",
"queryType": 12,
"gridSettings": {
"formatters": [
{
"columnMatch": "country",
"formatter": 18,
"formatOptions": {
"thresholdsOptions": "icons",
"thresholdsGrid": [
{
"operator": "Default",
"thresholdValue": null,
"representation": "Globe",
"text": "{0}{1}"
}
]
}
},
{
"columnMatch": "ipAddr",
"formatter": 18,
"formatOptions": {
"thresholdsOptions": "colors",
"thresholdsGrid": [
{
"operator": "Default",
"thresholdValue": null,
"representation": "gray",
"text": "{0}{1}"
}
]
}
}
]
}
},
"conditionalVisibility": {
"parameterName": "ipAddress",
"comparison": "isNotEqualTo"
},
"name": "query - geoLocation api"
},
{
"type": 3,
"content": {
"version": "KqlItem/1.0",
"query": "let IP_Data = external_data(network:string,geoname_id:long,continent_code:string,continent_name:string ,country_iso_code:string,country_name:string,is_anonymous_proxy:bool,is_satellite_provider:bool)\r\n ['https://raw.githubusercontent.com/datasets/geoip2-ipv4/master/data/geoip2-ipv4.csv']\r\n with (ignoreFirstRecord=true, format=\"csv\");\r\nIP_Data\r\n| evaluate ipv4_lookup(IP_Data, '{ipAddress}', network)\r\n| summarize arg_max(network,*) by '{ipAddress}'\r\n| extend IPaddress = '{ipAddress}'\r\n| project-away *1\r\n| project-reorder IPaddress\r\n\r\n",
"size": 4,
"title": "🖧 Lookup IP Address: {ipAddress} from GeoIP2",
"timeContext": {
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"queryType": 0,
"resourceType": "microsoft.operationalinsights/workspaces",
"crossComponentResources": [
"{Workspace}"
],
"gridSettings": {
"formatters": [
{
"columnMatch": "IPaddress",
"formatter": 18,
"formatOptions": {
"thresholdsOptions": "colors",
"thresholdsGrid": [
{
"operator": "Default",
"thresholdValue": null,
"representation": "gray",
"text": "{0}{1}"
}
]
}
}
]
}
},
"conditionalVisibility": {
"parameterName": "ipAddress",
"comparison": "isNotEqualTo"
},
"name": "query - ip lookup GeoIP2"
},
{
"type": 3,
@ -1462,7 +1550,7 @@
"title": " '{SelectUser}' : Cities visitied",
"color": "green",
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"exportFieldName": "Namespace",
@ -1612,7 +1700,7 @@
"title": " '{SelectUser}' : distance travelled",
"color": "green",
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"exportFieldName": "Namespace",
@ -1762,7 +1850,7 @@
"title": " '{SelectUser}' : Countries visitied ",
"color": "green",
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"exportFieldName": "Namespace",
@ -1912,7 +2000,7 @@
"title": "All Users : Countries by most frequent",
"color": "green",
"timeContext": {
"durationMs": 7776000000
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"exportFieldName": "Namespace",
@ -2076,7 +2164,7 @@
"size": 0,
"title": "Front door",
"timeContext": {
"durationMs": 0
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"showExportToExcel": true,
@ -2100,7 +2188,7 @@
"size": 4,
"title": "Front door",
"timeContext": {
"durationMs": 0
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"queryType": 0,
@ -2157,7 +2245,7 @@
"size": 0,
"title": "Application Gateway Web Application Firewall (WAF) Logs",
"timeContext": {
"durationMs": 0
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"showExportToExcel": true,
@ -2181,7 +2269,7 @@
"size": 4,
"title": "Application Gateway Web Application Firewall (WAF) Logs",
"timeContext": {
"durationMs": 0
"durationMs": 1209600000
},
"timeContextFromParameter": "TimeRange",
"queryType": 0,
@ -2214,7 +2302,7 @@
}
},
"customWidth": "30",
"name": "query - 0 - Copy - Copy"
"name": "query - App Gateway"
}
]
},
@ -2226,8 +2314,6 @@
"name": "group - WAF"
}
],
"fallbackResourceIds": [
"Azure Monitor"
],
"fromTemplateId": "sentinel-UserMapWorkbook",
"$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
}

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

@ -1482,6 +1482,19 @@
"subtitle": "",
"provider": "Microsoft Sentinel Community"
},
{
"workbookKey": "UserMap",
"logoFileName": "",
"description": "This Workbook shows MaliciousIP, User SigninLog Data (this shows user Signin Locations and distance between as well as order visited) and WAF information.",
"dataTypesDependencies": [ "SigninLogs", "AzureDiagnostics", "WireData", "VMconnection", "CommonSecurityLog", "WindowsFirewall", "W3CIISLog","DnsEvents"],
"dataConnectorsDependencies": ["AzureActiveDirectory"],
"previewImagesFileNames": [ "UserMapBlack.png", "UserMapWhite.png" ],
"version": "1.0",
"title": "User Map information",
"templateRelativePath": "UserMap.json",
"subtitle": "",
"provider": "Microsoft Sentinel Community"
},
{
"workbookKey": "AWSS3",
"logoFileName": "",