Looking at these SHODAN docs I'm not sure I understand why I am only getting the first port details returned when I run the script. When I look in the web interface I can see there are multiple ports/services detected for some of the devices...
http://shodan.readthedocs.io/en/latest/tutorial.html#connect-to-the-api
#!/usr/bin/python
import shodan
SHODAN_API_KEY = "xxxxxxx"
api = shodan.Shodan(SHODAN_API_KEY)
try:
results = api.search('ics country:"US"')
for item in results['matches']:
print """
Port: %s
Banner: %s
""" % (item['port'], item['data'])
except shodan.APIError, e:
print 'Error: %s' % e
Your script is searching the main Shodan database for service banners that contain the string "ics" and where the devices are located in the US. The results of the search are banners though; i.e. services - not hosts! And a service banner can only have 1 port associated with it which is why that's all you're seeing. However, a host can run multiple services and have many open ports. It sounds like that's what you're actually interested in. If you want to get the full list of ports/ services that a host has then you need to use the "api.host()" method.
host = api.host('8.8.8.8')
That will return a list of all the ports/ services that a given IP has public on the Internet.
Also note that searching for "ics" in the banner is not the same as searching for industrial control systems. You will need to use search filters such as:
category:ics
There is a section on Shodan that outlines the various ICS protocols that are crawled and how to search for them:
https://www.shodan.io/explore/category/industrial-control-systems