A powershell script for running reverse lookups on many IP addresses at once

I often find myself looking at web logs when researching anomalous traffic on our servers.  It’s not uncommon for a poorly written web scraper to come through the system and generate spurious errors, and I start looking at what IP addresses are generating the most hits to see if I can pinpoint who it is.

One of my first steps is run a reverse lookup on the IP to see if there is a PTR record registered in DNS that might identify them.  For example, Amazon’s EC2 servers have registered PTR records:

> nslookup 184.169.245.120

Name: ec2-184-169-245-120.us-west-1.compute.amazonaws.com
Address: 184.169.245.120

Running nslookup by hand is fine if I need to look up just one or two sites, but sometimes I found myself with a long list of addresses that I want to look up.  I could easily write a script around nslookup, but the output was too verbose (usually 5 or 6 lines per IP address) to easily scan through the results.

I also wanted to take it a step further than just a PTR lookup.  Many IPs have no PTR record, but over time I have accumulated a list of IPs that I have identified and recognize.  For example, I have a long list of Akamai servers that are frequently intermediate nodes for traffic on our Akamai urls.  I also have the IPs of proxy servers for several clients that have large numbers of users sharing a single address.  I wanted to combine the results of my home-grown list with the reverse lookup in easy-to-use command.

I ended up writing a powershell script to do just that.  It takes a list of IPs (or a single IP on a command line), and runs an nslookup.   Rather than spitting many lines of output, it parses the results to extract the part I am interested – the name record.  It then also checks the IP address against my known list of IPs, and then finally outputs it in a tab-delimited, easy-to-read format with one IP per line:

> ip_lookup.ps1 -k knownips.txt -f input_ips.txt
204.236.179.177   ec2-204-236-179-177.us-west-1.compute.amazonaws.com
204.236.188.194   ec2-204-236-188-194.us-west-1.compute.amazonaws.com
204.236.188.206   ec2-204-236-188-206.us-west-1.compute.amazonaws.com
209.170.118.215   NOT FOUND                Akamai
216.246.87.201    unknown.scnet.net        Akamai
50.18.0.118       ec2-50-18-0-118.us-west-1.compute.amazonaws.com

As I run the tool looking at different issues, I learn about new IPs and add them to my known IP list, saving me troubleshooting time in the future.

Here is the powershell script:


$stop = $args.Count
$inputIP = ""
$inputFile = ""
$knownIPFile = ""
$showUsage = 0
$verbose = 0
for ($i = 0; $i -lt $stop; $i++)
{
if ($args[$i] -eq "-f") {
if ( ($i + 1) -eq $stop) {
$showUsage = 1
}
else {
$i++
$inputFile = $args[$i]
}
}
elseif ($args[$i] -eq "-k") {
if ( ($i + 1) -eq $stop) {
$showUsage = 1
}
else {
$i++
$knownIPFile = $args[$i]
}
}
elseif ($args[$i] -eq "-verbose") {
$verbose = 1
}
else {
if ( ($i + 1) -eq $stop) {
$inputIP = $args[$i]
}
else {
$showUsage = 1
}
}
}
if ($stop -eq 0) {
$showUsage = 1
}
if ($showUsage) {
Write-Host "Usage: ip_lookup.ps1 [-multiline] [-k <KNOWN_IP_FILE] -f <FILENAME>"
Write-Host " ip_lookup.ps1 [-multiline] [-k <KNOWN_IP_FILE] <IP_ADDRESS>"
Write-Error "Bad Input"
exit
}
$knownIPs = @{}
function LoadKnownIPs($knownIPList)
{
# File should be IP<TAB>Description
$reader = [System.IO.File]::OpenText($knownIPList)
$line = $reader.ReadLine()
while( $line)
{
$result = $line.Split("`t")
if ($result.Count -le 2) {
$knownIPs[$result[0].Trim()] = $result[1]
}
else {
Write-Output ("" + $result[0].Trim() + "")
Write-Output "Error at $line with " + $result.Count
}
$line = $reader.ReadLine()
}
$reader.Close()
}
if ( $knownIPFile -ne "" ) {
LoadKnownIPs($knownIPFile)
}
function LookupIP($ip) {
$result = nslookup $ip 2> $null | select-string pattern "Name:"
if ( ! $result ) { $result = "" }
$result = $result.ToString()
if ($result.StartsWith("Name:")) {
$result = $result.Split()
$result = $result[$result.Count -1 ]
}
else {
$result = "NOT FOUND"
}
$knownMatch = ""
if ($knownIPs.ContainsKey($ip)) {
$knownMatch = $knownIPs[$ip]
}
if ($verbose) {
Write-Output $ip
Write-Output $result
Write-Output $knownMatch
}
else {
Write-Output "$ip `t $result `t $knownMatch"
}
}
if ( $inputFile -ne "") {
$reader = [System.IO.File]::OpenText($inputFile)
$line = $reader.ReadLine()
while( $line)
{
LookupIP $line.Trim()
$line = $reader.ReadLine()
}
$reader.Close()
}
else {
LookupIP $inputIP
}

view raw

ip_lookup.ps1

hosted with ❤ by GitHub

Or you can download it directly from GitHub at https://gist.github.com/jrothmanshore/2656003.

This entry was posted in Uncategorized and tagged , , , , , , , . Bookmark the permalink.

18 Responses to A powershell script for running reverse lookups on many IP addresses at once

  1. Arshad says:

    It worked. THANKs.
    What is knownips.txt for ?

    • It allows you to maintain a list of IP addresses that you recognize that may not have an associated reverse IP looked or the reverse may give cryptic information. It’s useful if you do this regularly and want to avoid researching mysterious IP addresses multiple times because you forgot what they were.

  2. Paul Duffany says:

    Seems the script was pulled down?

    • Odd, thank you for bringing that to my attention. The link to the script was there, and I’m not sure why it stopped displaying it. I updated the post and it has magically re-appeared.

  3. Adam says:

    🙂 !!! Worked like a charm. I was about to write my own reverse lookup by IP and found your script while researching. Thanks for sharing your work 🙂 made my day easier !!

  4. Mike Yazbeck says:

    Absolute legend, I tried to use other scripts like this one here:

    http://community.spiceworks.com/scripts/show/1201-powershell-script-dns-forward-lookup-script-with-auto-generate-excel-file

    I substituted the “GetHostAddresses” with “GetHostByAddress” and turned off the piping into Add-Member, but although it works pretty well, if $FWDIP is $null, when you change the for loop to have an if else statement, the variable $FWDIP never saves the $null value, plus if it is $null or leads to an error… then it takes soo long to execute.

    This script on the other hand is bad ass and does all the hard leg work for you. Thanks for sharing this with the world, you my friend are a legend! 😀

  5. Matt says:

    Doesn’t work

  6. Ray says:

    nice work – even for me as a total newbie it worked fine.
    I have a huge list of IP-Adresses I want to lookup. is there a way to write/save the output directly to a file?
    Thanks!

  7. Matt says:

    Thanks a bunch. This will save me loads of time each week.

  8. Kelvin says:

    Forgive my ignorance, but I am new to PS and am having problems executing this script against my list of IPs. Could you please advise how to correctly run this script and which where the IP list file needs to be located? much appreciated

  9. Sheky says:

    i cant understand. show me error

    ./ip_lookup.ps1: line 1: =: command not found
    ./ip_lookup.ps1: line 2: =: command not found
    ./ip_lookup.ps1: line 3: =: command not found
    ./ip_lookup.ps1: line 4: =: command not found
    ./ip_lookup.ps1: line 5: =: command not found
    ./ip_lookup.ps1: line 6: =: command not found
    ./ip_lookup.ps1: line 7: syntax error near unexpected token `(‘
    ./ip_lookup.ps1: line 7: `for ($i = 0; $i -lt $stop; $i++)’

  10. Bob says:

    Worked great! Thank you, very much!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s