如何在Azure Sentinel中实现Azure IP范围白名单并对比CIDR与CallerIP
问题描述
我有一个用于获取Azure公网IP范围的KQL查询,需要把这些IP范围加入到检测可疑资源部署的现有警报白名单中:
// Pulling Azure IPs from link and parsing them in to a readable format for query. let AzureIPRangesPublicCloud = (externaldata(changeNumber:string, cloud:string, values: dynamic) [@"https://download.microsoft.com/download/7/1/D/71D86715-5596-4529-9B13-DA13A5DE5B63/ServiceTags_Public_20240722.json"] with (format="multijson")); let AzureSubnetRangeWhitelist = AzureIPRangesPublicCloud | mvexpand values | extend addressPrefixes = parse_json(parse_json(values).properties).addressPrefixes | mvexpand addressPrefixes | project addressPrefixes; AzureSubnetRangeWhitelist
另外,我还有一个检测可疑资源部署的查询:
// Add or remove operation names below as per your requirements. let szOperationNames = dynamic(["Microsoft.Compute/virtualMachines/write", "Microsoft.Resources/deployments/write", "Microsoft.Resources/subscriptions/resourceGroups/write"]); let starttime = 14d; let endtime = 1d; let RareCaller = AzureActivity | where TimeGenerated between (ago(starttime) .. ago(endtime)) | where OperationNameValue in~ (szOperationNames) | summarize count() by CallerIpAddress, Caller, OperationNameValue, bin(TimeGenerated,1d) // Returns all the records from the right side that don't have matches from the left. | join kind=rightantisemi ( AzureActivity | where TimeGenerated > ago(endtime) | where OperationNameValue in~ (szOperationNames) | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ActivityTimeStamp = make_set(TimeGenerated,100), ActivityStatusValue = make_set(ActivityStatusValue,100), CorrelationIds = make_set(CorrelationId,100), ResourceGroups = make_set(ResourceGroup,100), ResourceIds = make_set(_ResourceId,100), ActivityCountByCallerIPAddress = count() by CallerIpAddress, Caller, OperationNameValue) on CallerIpAddress, Caller, OperationNameValue; RareCaller | extend Name = iif(Caller has '@',tostring(split(Caller,'@',0)[0]),"") | extend UPNSuffix = iif(Caller has '@',tostring(split(Caller,'@',1)[0]),"") | extend AadUserId = iif(Caller !has '@',Caller,"")
请问如何将格式为4.145.74.52/30的addressPrefixes与CallerIpAddress进行对比,从而将落在该JSON文件IP范围内的CallerIpAddress加入白名单,避免触发警报?
解决方案
使用KQL的ipv4_is_in_range()函数判断单个IP是否属于CIDR范围,再将白名单逻辑整合到可疑资源检测查询中即可实现需求。具体实现如下:
整合后的完整查询
// 获取Azure公网IP范围白名单 let AzureIPRangesPublicCloud = (externaldata(changeNumber:string, cloud:string, values: dynamic) [@"https://download.microsoft.com/download/7/1/D/71D86715-5596-4529-9B13-DA13A5DE5B63/ServiceTags_Public_20240722.json"] with (format="multijson")); let AzureSubnetRangeWhitelist = AzureIPRangesPublicCloud | mvexpand values | extend addressPrefixes = parse_json(parse_json(values).properties).addressPrefixes | mvexpand addressPrefixes | project CIDRRange = tostring(addressPrefixes); // 确保格式为字符串类型CIDR // 可疑资源部署检测(含白名单过滤) let szOperationNames = dynamic(["Microsoft.Compute/virtualMachines/write", "Microsoft.Resources/deployments/write", "Microsoft.Resources/subscriptions/resourceGroups/write"]); let starttime = 14d; let endtime = 1d; let RareCaller = AzureActivity | where TimeGenerated between (ago(starttime) .. ago(endtime)) | where OperationNameValue in~ (szOperationNames) | summarize count() by CallerIpAddress, Caller, OperationNameValue, bin(TimeGenerated,1d) | join kind=rightantisemi ( AzureActivity | where TimeGenerated > ago(endtime) | where OperationNameValue in~ (szOperationNames) // 过滤白名单IP范围:排除落在Azure IP范围内的请求 | join kind=leftanti (AzureSubnetRangeWhitelist | extend dummy=1) on dummy | where ipv4_is_in_range(CallerIpAddress, CIDRRange) == false | summarize StartTimeUtc = min(TimeGenerated), EndTimeUtc = max(TimeGenerated), ActivityTimeStamp = make_set(TimeGenerated,100), ActivityStatusValue = make_set(ActivityStatusValue,100), CorrelationIds = make_set(CorrelationId,100), ResourceGroups = make_set(ResourceGroup,100), ResourceIds = make_set(_ResourceId,100), ActivityCountByCallerIPAddress = count() by CallerIpAddress, Caller, OperationNameValue ) on CallerIpAddress, Caller, OperationNameValue; RareCaller | extend Name = iif(Caller has '@',tostring(split(Caller,'@',0)[0]),"") | extend UPNSuffix = iif(Caller has '@',tostring(split(Caller,'@',1)[0]),"") | extend AadUserId = iif(Caller !has '@',Caller,"")
核心逻辑说明
ipv4_is_in_range():校验CallerIpAddress是否属于指定的CIDR范围,返回布尔值。leftanti连接:将白名单范围与请求日志关联,过滤掉所有在白名单内的IP请求,仅保留可疑的非白名单请求。- 类型转换:将
addressPrefixes转为字符串类型的CIDRRange,确保函数能正确解析格式。
可选优化:针对特定服务标签白名单
如果只需白名单特定Azure服务的IP范围(如AzureCloud),可在白名单查询中添加过滤条件:
let AzureSubnetRangeWhitelist = AzureIPRangesPublicCloud | mvexpand values | extend serviceTag = parse_json(values).name | extend addressPrefixes = parse_json(parse_json(values).properties).addressPrefixes | where serviceTag == "AzureCloud" // 指定目标服务标签 | mvexpand addressPrefixes | project CIDRRange = tostring(addressPrefixes);
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

