Monitoring with PowerShell: Monitoring Shodan results (in-depth)

Sometime ago I made a blog about monitoring your environments by using PowerShell and the Shodan API. This blog was well received but I felt like it could use a lot of improvements. The data returned wasn’t all that useful for some, and sometimes you want to exclude specific ports in case of an actual webserver for example.

So I’ve made an updated version that is able to return more info, This version allows you to add both exclusions, and get more information like who the ISP is, and if known vulnerabilities have been found. It also keeps a history of the previous result and runs a compare against this, to check if something has been changed.

As always these scripts are designed to run with your RMM, on environments where you’d expect no open ports or a very limited subset. Monitoring this on all your devices probably aint the best plan 🙂

$PortExclusions = @('80', '443')
$CurrentIP = (Invoke-WebRequest -uri "http://ifconfig.me/ip" -UseBasicParsing ).Content
$ListIPs = @($CurrentIP)
$Shodan = foreach ($ip in $ListIPs) {
    try {
        $ReqFull = Invoke-RestMethod -uri "https://api.shodan.io/shodan/host/$($ip)?key=$APIKEY"
    }
    catch {
        write-host "Could not get information for host $IP. Error was:  $($_.Exception.Message)"
        continue
    }
    foreach ($req in $ReqFull.data | Where-Object { $_.port -notin $PortExclusions }) {
        [PSCustomObject]@{
            'IP'                    = $req.ip_str
            'Detected OS'           = $Req.data.OS
            'Detected Port'         = $req.port
            'Detected ISP'          = $req.isp
            'Detected Data'         = $req.data
            'Found vulnerabilities' = $req.opts.vulns
        }
    }
}

$previousResult = get-content "$($Env:Programdata)\ShodanScan\LastScan.txt" -ErrorAction SilentlyContinue | ConvertFrom-Json
if($previousResult) {$CompareObject = Compare-Object $previousresult $Shodan}
if ($CompareObject) { Write-Host "There is a different between the previous result and the current result. Please investigate" }
new-item "$($Env:Programdata)\ShodanScan" -ItemType Directory -Force
ConvertTo-Json $Shodan  | Out-File "$($Env:Programdata)\ShodanScan\LastScan.txt"


if (!$Shodan) { write-host "Healthy - Hosts are not found in Shodan." } else { write-host "Hosts are found in Shodan. Information: $($Shodan | out-string)" } 

And that’s it! as always, Happy PowerShelling.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.