pythoncidrport-scanningshodan

Shodan. Get all open ports for a net


I want to get all the open ports for a network with Shodan (I know I can use nmap but I want to carry this out with Shodan).

The problem is that the website only shows the "TOP Services", and I would like to be given all the services.

For example, for this net: 195.53.102.0/24 I am given the following ports:

TOP SERVICES
HTTP 15
HTTPS 2
DNS 2
FTP 2
IKE-NAT-T 1

But if I scan this net: 195.53.0.0/16, I am given these ports:

TOP SERVICES
HTTP 1,012
HTTPS 794
179 290
IKE 238
IKE-NAT-T 227

So I am missing services like dns and ftp.

I am trying with the API, from python:

import shodan

SHODAN_API_KEY = "XXXXXXXXXXXXXXXXXXXXXXx"

api = shodan.Shodan(SHODAN_API_KEY)

# Wrap the request in a try/ except block to catch errors
try:

    # Search Shodan


    results = api.search('net:195.53.102.0/24')
    for service in results['matches']:
        print service['ip_str']
        print service['port']

except shodan.APIError, e:
        print 'Error: %s' % e

And this is the results I get:

195.53.102.193
80
195.53.102.138
80
195.53.102.148
80
195.53.102.136
80
195.53.102.157
80
195.53.102.226
443
195.53.102.66
500
195.53.102.133
80
195.53.102.142
80
195.53.102.66
4500
195.53.102.141
80
195.53.102.131
21
195.53.102.152
53
195.53.102.153
21
195.53.102.209
80
195.53.102.132
53
195.53.102.226
80
195.53.102.147
80
195.53.102.142
443
195.53.102.178
80
195.53.102.135
143
195.53.102.146
80
195.53.102.143
80
195.53.102.144
80

Just 1 port per IP, and for example, this IP: 195.53.102.131 has ports 21, 80 and 443 open, my results say just:

195.53.102.131
21

Instead of:

195.53.102.131
21
80
443

So I want either to, from the website, be given all the ports/services instead of just the TOP SERVICES or, from the API, being able to get all the ports per IP, not just 1. Or if anyone has a better solution, I would like to hear it too.

As I said, I would like to perform it with Shodan, not nmap. Thank you in advance.


Solution

  • When you use the api.search() method, Shodan searches for a service banner and a service banner only has 1 port. If you want to return all the ports for a host, you should use api.host() instead. For example:

    import shodan
    
    SHODAN_API_KEY = "XXXXXXXXXXXXXXXXXXXXXXx"
    
    api = shodan.Shodan(SHODAN_API_KEY)
    
    # Wrap the request in a try/ except block to catch errors
    try:
    # Search Shodan
        results = api.search('net:195.53.102.0/24')
        for service in results['matches']:
            hostinfo = api.host(service['ip_str'])
    
            print service['ip_str']
            #Not sure if it's correct, but you should do something,
            #like this:
            for port in hostinfo['port']:
                print port
    
    except shodan.APIError, e:
        print 'Error: %s' % e