Tutorial

API client

Create client object

To interact with the API, a client object needs to be created:

>>> from greynoise import GreyNoise
>>> api_client = GreyNoise(api_key=<api_key>, timeout=<timeout_in_seconds>, proxy=<proxy_url>,
    use_cache=True, cache_max_size=1000, cache_ttl=3600, integration_name=<name_of_integration>)

where:

  • api_key is the key you have been given to use the API.

  • timeout_in_seconds is the timeout for each request sent to the API.

  • proxy is the url (ex http://myproxy.corp.io:1234) for requests to be routed through.

  • use_cache is used to disable (enabled by default) use of local cache for lookups.

  • cache_max_size is used to define the max size of the cache, if enabled.

  • cache_ttl is used to define the TTL of the data in the cache, if enabled.

  • integration_name is used to define the name of an integration the SDK is built into, if needed.

Note

All parameters are optional and might not be required if a configuration file has been created using the greynoise setup CLI command.

Check specific IPs

Once the client object has been created, it’s possible to check if a given IP is considered internet noise or has been observed scanning or attacking devices across the Internet as follows:

>>> api_client.quick('8.8.8.8')
{
  "ip": "8.8.8.8",
  "noise": false,
  "code": "0x05",
  "code_message": "This IP is commonly spoofed in Internet-scan activity"
}

When there’s a list of IP addresses to verify, they can be checked all at once like this:

>>> api_client.quick(['8.8.8.8', '58.220.219.247'])
[
  {
    "ip": "8.8.8.8",
    "noise": false,
    "code": "0x05",
    "code_message": "This IP is commonly spoofed in Internet-scan activity"
  },
  {
    "ip": "58.220.219.247",
    "noise": true,
    "code": "0x01",
    "code_message": "The IP has been observed by the GreyNoise sensor network"
  }
]

When there’s a list of IP addresses to verify, and invalid IPs provide should be included in the output they can be checked all at once like this:

>>> api_client.quick(['8.8.8.8', '58.220.219.247', '110.153.82.818'],include_invalid=True)
[
  {
    "ip": "8.8.8.8",
    "noise": false,
    "code": "0x05",
    "code_message": "This IP is commonly spoofed in Internet-scan activity"
  },
  {
    "ip": "58.220.219.247",
    "noise": true,
    "code": "0x01",
    "code_message": "The IP has been observed by the GreyNoise sensor network"
  },
  {
  "ip": "110.153.82.818",
  "noise": False,
  "code": "404",
  "code_message": "IP is Invalid"}
]

Detailed context information for any given IP address is also available:

>>> api_client.ip('58.220.219.247')
{
  "ip": "58.220.219.247",
  "seen": true,
  "classification": "malicious",
  "first_seen": "2019-04-04",
  "last_seen": "2019-08-21",
  "actor": "unknown",
  "tags": [
    "MSSQL Bruteforcer",
    "MSSQL Scanner",
    "RDP Scanner"
  ],
  "metadata": {
    "country": "China",
    "country_code": "CN",
    "city": "Kunshan",
    "organization": "CHINANET jiangsu province network",
    "asn": "AS4134",
    "tor": false,
    "os": "Windows 7/8",
    "category": "isp"
  },
  "raw_data": {
    "scan": [
      {
        "port": 1433,
        "protocol": "TCP"
      },
      {
        "port": 3389,
        "protocol": "TCP"
      },
      {
        "port": 65529,
        "protocol": "TCP"
      }
    ],
    "web": {
      "paths": [],
      "useragents": []
    },
    "ja3": []
  }
}

When there’s a list of IP addresses to get full context from, they can be checked all at once like this (this method also supports the include_invalid flag:

  >>> api_client.ip_multi(['8.8.8.8', '58.220.219.247'])
    [
  {
    'ip': '8.8.8.8',
    'first_seen': '',
    'last_seen': '',
    'seen': False,
    'tags': None,
    'actor': '',
    'spoofable': False,
    'classification': '',
    'cve': None,
    'bot': False,
    'vpn': False,
    'vpn_service': '',
    'metadata': {
      'asn': '',
      'city': '',
      'country': '',
      'country_code': '',
      'organization': '',
      'category': '',
      'tor': False,
      'rdns': '',
      'os': ''
    },
    'raw_data': {
      'scan': [],
      'web': {},
      'ja3': [],
      'hassh': []
    }
  },
  {
    'ip': '58.220.219.247',
    'first_seen': '',
    'last_seen': '',
    'seen': False,
    'tags': None,
    'actor': '',
    'spoofable': False,
    'classification': '',
    'cve': None,
    'bot': False,
    'vpn': False,
    'vpn_service': '',
    'metadata': {
      'asn': '',
      'city': '',
      'country': '',
      'country_code': '',
      'organization': '',
      'category': '',
      'tor': False,
      'rdns': '',
      'os': ''
    },
    'raw_data': {
      'scan': [],
      'web': {},
      'ja3': [],
      'hassh': []
    }
  }
]

Any IP can also be checked to see if it exists within the RIOT dataset:

>>> api_client.riot('8.8.8.8')
{
  'ip': '8.8.8.8',
  'riot': True,
  'category': 'public_dns',
  'name': 'Google Public DNS',
  'description': "Google's global domain name system (DNS) resolution service.",
  'explanation': "Public DNS services are used as alternatives to ISP's name servers. You may see devices on your network communicating with Google Public DNS over port 53/TCP or 53/UDP to resolve DNS lookups.",
  'last_updated': '2022-02-08T18:58:27Z',
  'logo_url': 'https://upload.wikimedia.org/wikipedia/commons/2/2f/Google_2015_logo.svg',
  'reference': 'https://developers.google.com/speed/public-dns/docs/isp#alternative',
  'trust_level': '1'
}

Note

The ip and quick methods use an LRU cache with a timeout of one hour to return faster responses in case the same addresses are queried multiple times. It can be disabled to get live responses from the API by passing use_cache=False when the GreyNoise class is instantiated.

GNQL

Run a query

A GNQL (GreyNoise Query Language) query can be executed to dig deeper into the GreyNoise dataset. For example, to get context information related to activity has been classified as malicious and tagged as a Bluekeep Exploit:

>>> api_client.query('classification:malicious tags:"Bluekeep Exploit"')
{
  "complete": true,
  "count": 2,
  "data": [
    {
      "ip": "144.217.253.168",
      "seen": true,
      "classification": "malicious",
      "first_seen": "2019-06-04",
      "last_seen": "2019-08-21",
      "actor": "unknown",
      "tags": [
        "RDP Scanner",
        "Bluekeep Exploit"
      ],
      "metadata": {
        "country": "Canada",
        "country_code": "CA",
        "city": "Montréal",
        "organization": "OVH SAS",
        "rdns": "ns541387.ip-144-217-253.net",
        "asn": "AS16276",
        "tor": false,
        "os": "Linux 3.11+",
        "category": "hosting"
      },
      "raw_data": {
        "scan": [
          {
            "port": 3389,
            "protocol": "TCP"
          }
        ],
        "web": {},
        "ja3": []
      }
    },
    {
      "ip": "91.213.112.119",
      "seen": true,
      "classification": "malicious",
      "first_seen": "2019-04-18",
      "last_seen": "2019-06-03",
      "actor": "unknown",
      "tags": [
        "Bluekeep Exploit",
        "RDP Scanner",
        "TLS/SSL Crawler",
        "Tor",
        "VNC Scanner",
        "Web Scanner",
        "Windows RDP Cookie Hijacker CVE-2014-6318"
      ],
      "metadata": {
        "country": "Netherlands",
        "country_code": "NL",
        "city": "",
        "organization": "Onsweb B.V.",
        "rdns": "no-reverse.onlinesystemen.nl",
        "asn": "AS42755",
        "tor": true,
        "os": "Linux 3.11+",
        "category": "business"
      },
      "raw_data": {
        "scan": [
          {
            "port": 443,
            "protocol": "TCP"
          },
          {
            "port": 3389,
            "protocol": "TCP"
          },
          {
            "port": 5900,
            "protocol": "TCP"
          }
        ],
        "web": {},
        "ja3": []
      }
    }
  ],
  "message": "ok",
  "query": "classification:malicious tags:'Bluekeep Exploit'"
}

Get statistics

It’s also possible to get statistics related to a GNQL query to better understand how results are distributed in terms of different information such as organization, country, operating system, etc.:

>>> api_client.stats('classification:malicious tags:"Bluekeep Exploit"')
{
  "query": "classification:malicious tags:'Bluekeep Exploit'",
  "count": 24,
  "stats": {
    "classifications": [
      {
        "classification": "malicious",
        "count": 24
      }
    ],
    "organizations": [
      {
        "organization": "DigitalOcean, LLC",
        "count": 7
      },
      {
        "organization": "OVH SAS",
        "count": 6
      },
      {
        "organization": "China Unicom Shanghai network",
        "count": 3
      },
      {
        "organization": "Linode, LLC",
        "count": 3
      },
      {
        "organization": "Amarutu Technology Ltd",
        "count": 1
      },
      {
        "organization": "Amazon.com, Inc.",
        "count": 1
      },
      {
        "organization": "CHINANET-BACKBONE",
        "count": 1
      },
      {
        "organization": "INT-NETWORK",
        "count": 1
      },
      {
        "organization": "WideOpenWest Finance LLC",
        "count": 1
      }
    ],
    "actors": null,
    "countries": [
      {
        "country": "Canada",
        "count": 6
      },
      {
        "country": "United States",
        "count": 6
      },
      {
        "country": "China",
        "count": 4
      },
      {
        "country": "Germany",
        "count": 3
      },
      {
        "country": "Netherlands",
        "count": 3
      },
      {
        "country": "France",
        "count": 1
      },
      {
        "country": "United Kingdom",
        "count": 1
      }
    ],
    "tags": [
      {
        "tag": "Bluekeep Exploit",
        "count": 24
      },
      {
        "tag": "RDP Scanner",
        "count": 24
      },
      {
        "tag": "Telnet Scanner",
        "count": 1
      }
    ],
    "operating_systems": [
      {
        "operating_system": "Linux 3.11+",
        "count": 16
      },
      {
        "operating_system": "Windows 7/8",
        "count": 3
      },
      {
        "operating_system": "Mac OS X",
        "count": 2
      },
      {
        "operating_system": "Linux 2.2-3.x",
        "count": 1
      }
    ],
    "categories": [
      {
        "category": "hosting",
        "count": 17
      },
      {
        "category": "isp",
        "count": 6
      },
      {
        "category": "business",
        "count": 1
      }
    ],
    "asns": [
      {
        "asn": "AS14061",
        "count": 7
      },
      {
        "asn": "AS16276",
        "count": 6
      },
      {
        "asn": "AS17621",
        "count": 3
      },
      {
        "asn": "AS63949",
        "count": 3
      },
      {
        "asn": "AS12083",
        "count": 1
      },
      {
        "asn": "AS14618",
        "count": 1
      },
      {
        "asn": "AS202425",
        "count": 1
      },
      {
        "asn": "AS206264",
        "count": 1
      },
      {
        "asn": "AS4134",
        "count": 1
      }
    ]
  }
}

Command line interface

The same operations available through the API client are also available through the command line using the greynoise tool. To get a list of all the available subcommands, use the –help option:

$ greynoise -h
Usage: greynoise [OPTIONS] COMMAND [ARGS]...

GreyNoise CLI.

Options:
-h, --help  Show this message and exit.

Commands:
query*       Run a GNQL (GreyNoise Query Language) query.
account      View information about your GreyNoise account.
alerts       List, create, delete, and manage your GreyNoise alerts.
analyze      Analyze the IP addresses in a log file, stdin, etc.
feedback     Send feedback directly to the GreyNoise team.
filter       "Filter the noise from a log file, stdin, etc.
help         Show this message and exit.
interesting  Report an IP as "interesting".
ip           Query GreyNoise for all information on a given IP.
pcap         Get PCAP for a given IP address.
quick        Quickly check whether or not one or many IPs are "noise".
repl         Start an interactive shell.
riot         Query GreyNoise IP to see if it is in the RIOT dataset.
setup        Configure API key.
signature    Submit an IDS signature to GreyNoise to be deployed to all...
stats        Get aggregate stats from a given GNQL query.
version      Get version and OS information for your GreyNoise
            commandline...

Setup

To configure greynoise to use a given API key:

$ greynoise setup --api-key "<api_key>"
Configuration saved to '/home/username/.config/greynoise/config'

Note

This is the default configuration method. Alternatively, the API key can be passed to every command using the -k/–api-key option or through the GREYNOISE_API_KEY environment variable.

if for some reason, requests are timing out, it’s possible to set the request timeout for the API client with the setup command as well:

$ greynoise setup --api-key "<api_key>" --timeout <time_in_seconds>
Configuration saved to '/home/username/.config/greynoise/config'

Note

The API client request timeout can also be configured for a particular command using the GREYNOISE_TIMEOUT environment variable.

Check specific IPs

Once the command line tool has been created, it’s possible to check if a given IP is considered internet noise or has been observed scanning or attacking devices across the Internet as follows:

$ greynoise quick 58.220.219.247
58.220.219.247 is classified as NOISE.

When there’s a list of IP addresses to verify, they can be checked all at once like this (a comma seperated list is also supported:

$ greynoise quick 8.8.8.8 58.220.219.247
8.8.8.8 is classified as NOT NOISE.
58.220.219.247 is classified as NOISE.

Detailed context information for any given IP address is also available:

$ greynoise ip 58.220.219.247
╔═══════════════════════════╗
║      Context 1 of 1       ║
╚═══════════════════════════╝
IP address: 58.220.219.247

          OVERVIEW
----------------------------
Actor: unknown
Classification: malicious
First seen: 2019-04-04
IP: 58.220.219.247
Last seen: 2019-09-06
Tags:
- MSSQL Bruteforcer
- MSSQL Scanner
- RDP Scanner

          METADATA
----------------------------
ASN: AS4134
Category: isp
Location: Kunshan, China (CN)
Organization: CHINANET jiangsu province network
OS: Windows 7/8
rDNS:
Tor: False

          RAW DATA
----------------------------
[Scan]
- Port/Proto: 1433/TCP
- Port/Proto: 3389/TCP
- Port/Proto: 65529/TCP

When there’s a list of IP addresses to verify, they can be checked all at once like this (a comma seperated list is also supported:

$ greynoise ip-multi 8.8.8.8 58.220.219.247
       OVERVIEW
 ----------------------------
 Actor: unknown
 Classification: malicious
 First seen: 2020-12-21
 IP: 42.230.170.174
 Last seen: 2022-02-08
 Tags:
 - Mirai

           METADATA
 ----------------------------
 ASN: AS4837
 Category: isp
 Location:
 Region: Heilongjiang
 Organization: CHINA UNICOM China169 Backbone
 OS: Linux 2.2-3.x
 rDNS: hn.kd.ny.adsl
 Spoofable: False
 Tor: False

           RAW DATA
 ----------------------------
 [Scan]
 - Port/Proto: 23/TCP
 - Port/Proto: 8080/TCP

 [Paths]
 - /setup.cgi

 8.8.8.8 is classified as NOT NOISE.

GNQL

Run a query

A GNQL (GreyNoise Query Language) query can be executed to dig deeper into the GreyNoise dataset. For example, to get context information related to activity has been classified as malicious and tagged as a Bluekeep Exploit:

$ greynoise query "classification:malicious tags:Bluekeep Exploit"
╔═══════════════════════════╗
║       Query 1 of 1        ║
╚═══════════════════════════╝
Query: classification:malicious tags:"Bluekeep Exploit"

┌───────────────────────────┐
│      Result 1 of 20       │
└───────────────────────────┘

          OVERVIEW
----------------------------
Actor: unknown
Classification: malicious
First seen: 2018-12-10
IP: 185.7.63.40
Last seen: 2019-09-06
Tags:
- Web Crawler
- Wordpress XML RPC Worm
- RDP Scanner
- Web Scanner
- Bluekeep Exploit

          METADATA
----------------------------
ASN: AS39783
Category: hosting
Location: Norway (NO)
Organization: Rent a Rack AS
OS: Windows XP
rDNS: cp.netthost.no
Tor: False

          RAW DATA
----------------------------
[Scan]
- Port/Proto: 80/TCP
- Port/Proto: 3389/TCP

[Paths]
- /zabbix/toptriggers.php
- /forum/xmlrpc.php
- /wordpress/xmlrpc.php
- /zabbix/jsrpc.php
- /user/register/
- /blog/xmlrpc.php
- /xmlrpc.php
- /wp/xmlrpc.php

Note

This is the default command, that is, you can save some typing by just writing greynoise <query> instead of greynoise query <query>.

Get statistics

It’s also possible to get statistics related to a GNQL query to better understand how results are distributed in terms of different information such as organization, country, operating system, etc.:

$ greynoise stats 'classification:malicious tags:"Bluekeep Exploit"'
╔═══════════════════════════╗
║       Query 1 of 1        ║
╚═══════════════════════════╝
Query: classification:malicious tags:"Bluekeep Exploit"

ASNs:
- AS16276  6
- AS17621  3
- AS14618  2
- AS12083  1
- AS14061  1
- AS206264 1
- AS206485 1
- AS38895  1
- AS39783  1
- AS4134   1
- AS45090  1
- AS63949  1

Categories:
- hosting  12
- isp       5
- business  3

Classifications:
- malicious 20

Countries:
- Canada        5
- China         5
- United States 4
- France        1
- Germany       1
- Lithuania     1
- Netherlands   1
- Norway        1
- Singapore     1

Operating systems:
- Linux 3.11+ 9
- Windows 7/8 3
- Mac OS X    2
- Windows XP  2

Organizations:
- OVH SAS                                           6
- China Unicom Shanghai network                     3
- Amazon.com, Inc.                                  2
- Amarutu Technology Ltd                            1
- Amazon.com Tech Telecom                           1
- CHINANET-BACKBONE                                 1
- DigitalOcean, LLC                                 1
- Linode, LLC                                       1
- Rent a Rack AS                                    1
- Shenzhen Tencent Computer Systems Company Limited 1
- UGB Hosting OU                                    1
- WideOpenWest Finance LLC                          1

Tags:
- Bluekeep Exploit             20
- RDP Scanner                  19
- Web Scanner                  10
- HTTP Alt Scanner              5
- Ping Scanner                  5
- SSH Scanner                   5
- TLS/SSL Crawler               5
- VNC Scanner                   5
- DNS Scanner                   3
- FTP Scanner                   3
- IPSec VPN Scanner             3
- SMB Scanner                   3
- Web Crawler                   3
- ZMap Client                   3
- CPanel Scanner                2
- CounterStrike Server Scanner  2
- Elasticsearch Scanner         2
- Ethereum Node Scanner         2
- IMAP Scanner                  2
- IOT MQTT Scanner              2
Showing results 1 - 20. Run again with -v for full output

Community API Users

The GreyNoise API and CLI components can both be used with the [GreyNoise Community API](https://developer.greynoise.io/reference/community-api).

The Community API only includes a single IP lookup endpoint, so only the IP lookup command in both the API and CLI components will work if enabled.

To enable Community API usage, do the following:

CLI Config File

$ greynoise setup --api-key "<api_key>" --offering community
Configuration saved to '/home/username/.config/greynoise/config'

$ greynoise ip 192.223.30.35

╔═══════════════════════════╗
║     Community 1 of 1      ║
╚═══════════════════════════╝

IP: 192.223.30.35
NOISE: True
RIOT: False
Name: unknown
Classification: unknown
Last seen: 2021-03-18
Link: https://viz.greynoise.io/ip/192.223.30.35

CLI IP Command

$ greynoise ip <ip_address> --api-key "<api_key>" --offering community

API Client

$ api_client = GreyNoise(api_key=<api_key>, offering="community")
$ api_client.ip('192.223.30.35')

{
    'ip': '192.223.30.35',
    'noise': True,
    'riot': False,
    'classification': 'unknown',
    'name': 'unknown',
    'link': 'https://viz.greynoise.io/ip/192.223.30.35',
    'last_seen': '2021-03-18',
    'message': 'Success'
}