From c798e754b715a6da42b6a7b722b27579ae877a6d Mon Sep 17 00:00:00 2001 From: John Matherly Date: Wed, 20 Feb 2019 01:41:15 -0600 Subject: [PATCH] Release 1.11.0 New command: shodan alert info Improved output of alert and trigger information --- CHANGELOG.md | 5 +++- setup.py | 2 +- shodan/cli/alert.py | 65 ++++++++++++++++++++++++++++++++++++--------- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b107676..ba2044f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,17 @@ CHANGELOG ========= -unreleased +1.11.0 ---------- * New command **shodan scan list** to list recently launched scans * New command **shodan alert triggers** to list the available notification triggers * New command **shodan alert enable** to enable a notification trigger * New command **shodan alert disable** to disable a notification trigger +* New command **shodan alert info** to show details of a specific alert * Include timestamp, vulns and tags in CSV converter (#85) +* Fixed bug that caused an exception when parsing uncompressed data files in Python3 * Code quality improvements +* Thank you for contributions from @wagner-certat, @cclauss, @opt9, @voldmar and Antoine Neuenschwander 1.10.4 ------ diff --git a/setup.py b/setup.py index c925129..4686a81 100755 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='shodan', - version='1.10.4', + version='1.11.0', description='Python library and command-line utility for Shodan (https://developer.shodan.io)', long_description=README, long_description_content_type='text/x-rst', diff --git a/shodan/cli/alert.py b/shodan/cli/alert.py index 112c1cf..a4c2e29 100644 --- a/shodan/cli/alert.py +++ b/shodan/cli/alert.py @@ -1,6 +1,7 @@ import click import shodan +from operator import itemgetter from shodan.cli.helpers import get_api_key @@ -45,6 +46,42 @@ def alert_create(name, netblock): click.secho('Alert ID: {}'.format(alert['id']), fg='cyan') +@alert.command(name='info') +@click.argument('alert', metavar='') +def alert_info(alert): + """Show information about a specific alert""" + key = get_api_key() + api = shodan.Shodan(key) + + try: + info = api.alerts(aid=alert) + except shodan.APIError as e: + raise click.ClickException(e.value) + + click.secho(info['name'], fg='cyan') + click.secho('Created: ', nl=False, dim=True) + click.secho(info['created'], fg='magenta') + + click.secho('Notifications: ', nl=False, dim=True) + if 'triggers' in info and info['triggers']: + click.secho('enabled', fg='green') + else: + click.echo('disabled') + + click.echo('') + click.secho('Network Range(s):', dim=True) + + for network in info['filters']['ip']: + click.echo(u' > {}'.format(click.style(network, fg='yellow'))) + + click.echo('') + if 'triggers' in info and info['triggers']: + click.secho('Triggers:', dim=True) + for trigger in info['triggers']: + click.echo(u' > {}'.format(click.style(trigger, fg='yellow'))) + click.echo('') + + @alert.command(name='list') @click.option('--expired', help='Whether or not to show expired alerts.', default=True, type=bool) def alert_list(expired): @@ -100,7 +137,7 @@ def alert_remove(alert_id): @alert.command(name='triggers') def alert_list_triggers(): - """List all the available triggers""" + """List the available notification triggers""" key = get_api_key() # Get the list @@ -111,16 +148,20 @@ def alert_list_triggers(): raise click.ClickException(e.value) if len(results) > 0: - click.echo(u'# {:14} {:<21} {:<15s}'.format('Name', 'Description', 'Rule')) + click.secho('The following triggers can be enabled on alerts:', dim=True) + click.echo('') - for trigger in results: - click.echo( - u'{:16} {:<30} {:<35} '.format( - click.style(trigger['name'], fg='yellow'), - click.style(trigger['description'], fg='cyan'), - trigger['rule'] - ) - ) + for trigger in sorted(results, key=itemgetter('name')): + click.secho('{:<12} '.format('Name'), dim=True, nl=False) + click.secho(trigger['name'], fg='yellow') + + click.secho('{:<12} '.format('Description'), dim=True, nl=False) + click.secho(trigger['description'], fg='cyan') + + click.secho('{:<12} '.format('Rule'), dim=True, nl=False) + click.echo(trigger['rule']) + + click.echo('') else: click.echo("No triggers currently available.") @@ -139,7 +180,7 @@ def alert_enable_trigger(alert_id, trigger): except shodan.APIError as e: raise click.ClickException(e.value) - click.secho('Successfully enabled the trigger {}'.format(trigger), color='green') + click.secho('Successfully enabled the trigger: {}'.format(trigger), fg='green') @alert.command(name='disable') @@ -156,4 +197,4 @@ def alert_disable_trigger(alert_id, trigger): except shodan.APIError as e: raise click.ClickException(e.value) - click.secho('Successfully disabled the trigger {}'.format(trigger), color='green') + click.secho('Successfully disabled the trigger: {}'.format(trigger), fg='green')