Microsoft Security Tech Accelerator
Dec 06 2023, 07:00 AM - 12:00 PM (PST)
Microsoft Tech Community

Mapping IPs to autonomous systems number and name

Brass Contributor



On other SIEM's I have found it really effective to map IP addresses to BGP AS numbers and then use the AS number in anomaly detection and the AS name when displaying related logs/events. This is an alternate to relying on often inaccurate IP-to-location mapping.


Does anyone know whether this is mapping capability is already built-in to sentinel or if not, whether there's a way to build-in?



3 Replies
best response confirmed by mrboxx (Brass Contributor)



You could approach this with the  externaldata operator as mentioned here:


I downloaded the "IP4 to ASN map" from here:  (use a source you trust and you validate...this is just an example)


I uploaded that file to Azure Blob (after unpacking it to a .CSV file), then generated a SAS token and URL.  I use the URL created in this query


let iptofind = "";
externaldata (first_ip:string, end_ip:string, as_num:int, country_code:string, description:string)
[@"https://< insert your URL here>"]
| project iptofind, first_ip, end_ip, as_num, description
| where parse_ipv4(iptofind) between (parse_ipv4(first_ip).. parse_ipv4(end_ip))
Annotation 2020-03-02 120730.jpg


I use parse_ipv4 to work out where in the range the IP address I want is, it then returns the AS_Number (as_num) and description data.


You will have to download a new file on a regular basis (if required), maybe automate that with Logic Apps or another option is to use Logic Apps to read the data using the api?


I hope that helps.





Hi Clive,
Cool search syntax.
Just a quick follow up question,
How can we make this iteratively through a dynamic list? Thank you.

e.g. let ip_list = dynamic(["","",""]);


This would be one way

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)
let ip_list = dynamic(["","","",""]);
| extend justIP = split(network,@"/").[0]
| where justIP in (ip_list)

 Ip_data gets a list from the ...geoip2-ip4.csv file.   The column "network" is an ip address list (in the format, so with the extend = justIp I remove the "/32" part.   You can then use that IP address to compare against you dynamic list using the .

| where justIP in (ip_list)