IP Geo Location Lookup Using PowerShell

Geo Location and PowerShell

So, you’ve got a list of IPs and wonder where they are based geographically.

Maybe you compiled the IP list from your Office 365 audit logs using the Search-UnifiedAuditLog as part of researching a hacked Office 365 account? Or maybe it’s from your VPN service, password-protected extranet, or remote desktop session list.

In any case, you can use PowerShell and one of the many free online IP geolocation APIs to find out where these IPs are based geographically. I’ll show you how.

Geolocation Lookup Service Usage

One such online IP geolocation API provider is ip-api. ip-api allows you to query any IP address and will return a well-formed JSON object with geolocation information. As an example, let’s try to look up whitehouse.gov using PowerShell:

PS C:\> Resolve-DnsName whitehouse.gov -Type A | ft Name,IPAddress

Name           IPAddress
----           ---------
whitehouse.gov 23.197.12.199


PS C:\> Invoke-RestMethod -Method Get -Uri "http://ip-api.com/json/23.197.12.199"


as          : AS16625 Akamai Technologies, Inc.
city        : Düsseldorf
country     : Germany
countryCode : DE
isp         : Akamai Technologies
lat         : 51.2277
lon         : 6.77346
org         : Akamai International, BV
query       : 23.197.12.199
region      : NW
regionName  : North Rhine-Westphalia
status      : success
timezone    : Europe/Berlin
zip         : 40213

The DNS hostname is resolved to an IP address, and the IP address is used in a regular web query to ip-api.com.

To no surprise, whitehouse.gov is, of course, based in the western part of Germany! 🙂

Multiple properties are returned in the JSON response. For standard forensic analysis of a list of IP addresses, I suggest grabbing these four properties:

  • Query (the IP address being queried)
  • City
  • Country
  • ISP

Analyzing a List of IP Addresses

Assuming you have a long list of (unique) IP’s you want to analyze, let’s make a script that will provide you with valuable geographical information for each IP address.

To make life more easy let’s start by making a PowerShell function that will objectify the geolocation information:

function Get-IPGeolocation {
  Param
  (
    [string]$IPAddress
  )
 
  $request = Invoke-RestMethod -Method Get -Uri "http://ip-api.com/json/$IPAddress"
 
  [PSCustomObject]@{
    IP      = $request.query
    City    = $request.city
    Country = $request.country
    Isp     = $request.isp
  }
}

Now it’s only a matter of iterating your list of IPs against this function.

But – be warned! The ip-api.com provider is protected from abuse by a 45-queries-per-minute limit! If you exceed this limit, your IP will get blocked, and you will have to log in to their website to unblock it again (which is not easy when you’re blocked!).

Since you may have a long list of +45 IPs, I have saved you the trouble and created a script that will wait 70 seconds for every 40 queries (to be on the safe side).

Please note! If you’re already a customer at ip-api.com, you need to use a slightly different URL and include your API key in the body of the request, like so:

$request = Invoke-RestMethod -Method Get -Uri "http://pro.ip-api.com/json/$IPAddress" -Body @{key='API_KEY'}

The final script looks like this:

function Get-IPGeolocation {
  Param
  (
    [string]$IPAddress
  ) 
  $request = Invoke-RestMethod -Method Get -Uri "http://ip-api.com/json/$IPAddress"
  [PSCustomObject]@{
    IP      = $request.query
    City    = $request.city
    Country = $request.country
    Isp     = $request.isp
  }
}
$OutputFile = ".\IP_GeoLocation.csv"
$i = 0
$IPs = Get-Content ".\IPs.txt"
ForEach ($IP In $IPs) {
  $i++    # More than 45 queries per minute gets you banned from ip-api.com
  If ($i -gt 40) {
    Write-Host Just pausing a minute to avoid IP blocking from ip-api.com
    Start-Sleep 70
    $i = 0
  }
  Get-IPGeolocation($IP) | Select-Object IP, City, Country, Isp | Export-Csv $OutputFile -NoTypeInformation -Append
}

The script assumes you have an input file, “IPs.txt” with a list of unique IP addresses. 

Looking at the Data

The above script generates an output to Excel that may look similar to this:

IP Geo Location Data

Now, this is just an example – I’m not trying to insinuate there’s anything suspicious about Nigeria. But assuming you don’t have any employees working or visiting that country, it may appear strange that a Nigerian IP address is found connecting to your Office 365 environment (or VPN or remote desktop or whatever log file you’re analyzing).

Further Analysis

When you have identified one or more suspicious IPs, use them to analyze your log files further. For example, if you’re investigating an Office 365 breach, put the suspicious IP’s in an input file and run the following script:

$IPs = get-content ".\Suspicious_IPs.txt"
$OutputFile = ".\UnifiedAuditLog_IPs.csv"
$EndDate = Get-Date -Date (Get-Date -Format “yyyy-MM-dd”)
$intDays = 90
For ($i=0; $i -le $intDays; $i++){
  $Audit = Search-UnifiedAuditLog -EndDate $EndDate.AddDays(-$i + 1) -StartDate $EndDate.AddDays(-$i) -IPAddresses $IPs -ResultSize 5000
  $ConvertAudit = $Audit | Select-Object -ExpandProperty AuditData | ConvertFrom-Json
  $ConvertAudit | Select-Object CreationTime,UserId,Operation,Workload,ObjectID,SiteUrl,SourceFileName,ClientIP,UserAgent | Export-Csv $OutputFile -NoTypeInformation -Append
  Write-Host $i `t $Audit.Count
}

This will generate an output file which lists exactly what credentials were used and what resources were accessed using the suspicious IP’s. This is very useful information for further damage control and as evidence in case you want to pursue legal action.

Wrapping It Up

I highly recommend proactive use of this technique: If your user base is limited geographically (certain countries or regions) you can set up alerts for critical resources in case of irregular accesses being detected.

For more details on analysis of the Office 365 audit log using PowerShell refer to this post.

Did you like this post? Maybe your friends will too!