id = "shodan" name = "Shodan" homepage = "https://www.shodan.io/" description = "Shodan is a search engine for Internet-connected devices." executables = ["shodan"] [dotfiles] # The official shodan-python settings.py selects ~/.shodan when it exists and # otherwise ~/.config/shodan; helpers.py reads api_key in that directory. # https://github.com/achillean/shodan-python/blob/master/shodan/cli/settings.py # https://github.com/achillean/shodan-python/blob/master/shodan/cli/helpers.py paths = [] secret = ["~/.shodan/api_key", "~/.config/shodan/api_key"] [commands] format = 1 label = "Shodan" description = "Search Shodan, look up a host or domain, and count results. Needs an API key set with shodan init. Download, stream, alerts and scanning are left out." quality = "ai-draft" parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = true, short_bundles = false } [[commands.subcommand]] path = ["search"] label = "Search" description = "Search Shodan and print matching banners." [[commands.subcommand.source]] id = "shodan-src" kind = "manual" url = "https://github.com/achillean/shodan-python/blob/master/shodan/__main__.py" revision = "shodan-python master" evidence = '''@main.command() @click.option('--fields', help='List of properties to show in the search results.', default='ip_str,port,hostnames,data') @click.option('--limit', help='The number of search results that should be returned. Maximum: 1000', default=100, type=int) @click.option('--separator', help='The separator between the properties of the search results.', default='\t') @click.argument('query', metavar='', nargs=-1) def search(color, fields, limit, separator, query):''' [[commands.subcommand.field]] id = "query" label = "Search query" type = "string" position = 0 multiple = true min = 1 sources = ["shodan-src"] [[commands.subcommand.field]] id = "limit" label = "Result limit" type = "integer" option = ["--limit"] sources = ["shodan-src"] [[commands.subcommand.field]] id = "fields" label = "Fields" description = "Comma-separated properties." type = "string" option = ["--fields"] sources = ["shodan-src"] [[commands.subcommand.field]] id = "separator" label = "Separator" type = "string" option = ["--separator"] sources = ["shodan-src"] [[commands.subcommand.task]] id = "search" label = "Search" fields = ["query", "limit", "fields"] required = ["query"] [[commands.subcommand.group]] id = "basic" label = "Basic" fields = ["query", "limit", "fields"] [[commands.subcommand.group]] id = "advanced" label = "Advanced" fields = ["separator"] [[commands.subcommand]] path = ["host"] label = "Host lookup" description = "Show everything known about an IP address." [[commands.subcommand.source]] id = "shodan-src" kind = "manual" url = "https://github.com/achillean/shodan-python/blob/master/shodan/__main__.py" revision = "shodan-python master" evidence = '''@main.command() @click.option('--format', help='The output format for the host information. Possible values are: pretty, tsv.', default='pretty', type=click.Choice(['pretty', 'tsv'])) @click.option('--history', help='Show the complete history of the host.', default=False, is_flag=True) @click.option('--filename', '-O', help='Save the host information in the given file (append if file exists).', default=None) @click.argument('ip', metavar='') def host(format, history, filename, save, ip):''' [[commands.subcommand.field]] id = "ip" label = "IP address" type = "string" position = 0 min = 1 sources = ["shodan-src"] [[commands.subcommand.field]] id = "history" label = "Include history" type = "boolean" option = ["--history"] sources = ["shodan-src"] [[commands.subcommand.field]] id = "format" label = "Format" type = "enum" option = ["--format"] choices = [{ value = "pretty", label = "Pretty" }, { value = "tsv", label = "TSV" }] sources = ["shodan-src"] [[commands.subcommand.field]] id = "filename" label = "Save to file" type = "path" option = ["--filename", "-O"] path = { kind = "file", role = "output" } sources = ["shodan-src"] [[commands.subcommand.task]] id = "host" label = "Look up an IP" fields = ["ip", "history", "format"] required = ["ip"] [[commands.subcommand.group]] id = "basic" label = "Basic" fields = ["ip", "history", "format", "filename"] [[commands.subcommand]] path = ["count"] label = "Count results" description = "Count how many results match a query." [[commands.subcommand.source]] id = "shodan-src" kind = "manual" url = "https://github.com/achillean/shodan-python/blob/master/shodan/__main__.py" revision = "shodan-python master" evidence = '''@main.command() @click.argument('query', metavar='', nargs=-1) def count(query):''' [[commands.subcommand.field]] id = "query" label = "Search query" type = "string" position = 0 multiple = true min = 1 sources = ["shodan-src"] [[commands.subcommand.task]] id = "count" label = "Count" fields = ["query"] required = ["query"] [[commands.subcommand.group]] id = "basic" label = "Basic" fields = ["query"] [[commands.subcommand]] path = ["domain"] label = "Domain info" description = "Show DNS records and subdomains for a domain." [[commands.subcommand.source]] id = "shodan-src" kind = "manual" url = "https://github.com/achillean/shodan-python/blob/master/shodan/__main__.py" revision = "shodan-python master" evidence = '''@main.command(name='domain') @click.argument('domain', metavar='') @click.option('--details', '-D', help='Lookup host information for any IPs in the domain results', default=False, is_flag=True) @click.option('--history', '-H', help='Include historical DNS data in the results', default=False, is_flag=True) @click.option('--type', '-T', help='Only returns DNS records of the provided type', default=None)''' [[commands.subcommand.field]] id = "domain" label = "Domain" type = "string" position = 0 min = 1 sources = ["shodan-src"] [[commands.subcommand.field]] id = "details" label = "Look up host details" type = "boolean" option = ["--details", "-D"] sources = ["shodan-src"] [[commands.subcommand.field]] id = "history" label = "Historical DNS data" type = "boolean" option = ["--history", "-H"] sources = ["shodan-src"] [[commands.subcommand.field]] id = "type" label = "Record type" type = "string" option = ["--type", "-T"] suggestions = [{ value = "A", label = "A" }, { value = "MX", label = "MX" }, { value = "TXT", label = "TXT" }] sources = ["shodan-src"] [[commands.subcommand.task]] id = "domain" label = "Look up a domain" fields = ["domain", "type"] required = ["domain"] [[commands.subcommand.group]] id = "basic" label = "Basic" fields = ["domain", "details", "history", "type"]