1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
# Helper methods for printing `host` information to the terminal.
import click
from shodan.helpers import get_ip
def host_print_pretty(host, history=False):
"""Show the host information in a user-friendly way and try to include
as much relevant information as possible."""
# General info
click.echo(click.style(get_ip(host), fg='green'))
if len(host['hostnames']) > 0:
click.echo(u'{:25s}{}'.format('Hostnames:', ';'.join(host['hostnames'])))
if 'city' in host and host['city']:
click.echo(u'{:25s}{}'.format('City:', host['city']))
if 'country_name' in host and host['country_name']:
click.echo(u'{:25s}{}'.format('Country:', host['country_name']))
if 'os' in host and host['os']:
click.echo(u'{:25s}{}'.format('Operating System:', host['os']))
if 'org' in host and host['org']:
click.echo(u'{:25s}{}'.format('Organization:', host['org']))
if 'last_update' in host and host['last_update']:
click.echo('{:25s}{}'.format('Updated:', host['last_update']))
click.echo('{:25s}{}'.format('Number of open ports:', len(host['ports'])))
# Output the vulnerabilities the host has
if 'vulns' in host and len(host['vulns']) > 0:
vulns = []
for vuln in host['vulns']:
if vuln.startswith('!'):
continue
if vuln.upper() == 'CVE-2014-0160':
vulns.append(click.style('Heartbleed', fg='red'))
else:
vulns.append(click.style(vuln, fg='red'))
if len(vulns) > 0:
click.echo('{:25s}'.format('Vulnerabilities:'), nl=False)
for vuln in vulns:
click.echo(vuln + '\t', nl=False)
click.echo('')
click.echo('')
# If the user doesn't have access to SSL/ Telnet results then we need
# to pad the host['data'] property with empty banners so they still see
# the port listed as open. (#63)
if len(host['ports']) != len(host['data']):
# Find the ports the user can't see the data for
ports = host['ports']
for banner in host['data']:
if banner['port'] in ports:
ports.remove(banner['port'])
# Add the placeholder banners
for port in ports:
banner = {
'port': port,
'transport': 'tcp', # All the filtered services use TCP
'timestamp': host['data'][-1]['timestamp'], # Use the timestamp of the oldest banner
'placeholder': True, # Don't store this banner when the file is saved
}
host['data'].append(banner)
click.echo('Ports:')
for banner in sorted(host['data'], key=lambda k: k['port']):
product = ''
version = ''
if 'product' in banner and banner['product']:
product = banner['product']
if 'version' in banner and banner['version']:
version = '({})'.format(banner['version'])
click.echo(click.style('{:>7d}'.format(banner['port']), fg='cyan'), nl=False)
if 'transport' in banner:
click.echo('/', nl=False)
click.echo(click.style('{} '.format(banner['transport']), fg='yellow'), nl=False)
click.echo('{} {}'.format(product, version), nl=False)
if history:
# Format the timestamp to only show the year-month-day
date = banner['timestamp'][:10]
click.echo(click.style('\t\t({})'.format(date), fg='white', dim=True), nl=False)
click.echo('')
# Show optional ssl info
if 'ssl' in banner:
if 'versions' in banner['ssl'] and banner['ssl']['versions']:
click.echo('\t|-- SSL Versions: {}'.format(', '.join([item for item in sorted(banner['ssl']['versions']) if not version.startswith('-')])))
if 'dhparams' in banner['ssl'] and banner['ssl']['dhparams']:
click.echo('\t|-- Diffie-Hellman Parameters:')
click.echo('\t\t{:15s}{}\n\t\t{:15s}{}'.format('Bits:', banner['ssl']['dhparams']['bits'], 'Generator:', banner['ssl']['dhparams']['generator']))
if 'fingerprint' in banner['ssl']['dhparams']:
click.echo('\t\t{:15s}{}'.format('Fingerprint:', banner['ssl']['dhparams']['fingerprint']))
def host_print_tsv(host, history=False):
"""Show the host information in a succinct, grep-friendly manner."""
for banner in sorted(host['data'], key=lambda k: k['port']):
click.echo(click.style('{:>7d}'.format(banner['port']), fg='cyan'), nl=False)
click.echo('\t', nl=False)
click.echo(click.style('{} '.format(banner['transport']), fg='yellow'), nl=False)
if history:
# Format the timestamp to only show the year-month-day
date = banner['timestamp'][:10]
click.echo(click.style('\t({})'.format(date), fg='white', dim=True), nl=False)
click.echo('')
HOST_PRINT = {
'pretty': host_print_pretty,
'tsv': host_print_tsv,
}
|