greynoise 3.1.0__tar.gz → 3.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {greynoise-3.1.0 → greynoise-3.2.0}/.bumpversion.cfg +3 -3
- {greynoise-3.1.0 → greynoise-3.2.0}/CHANGELOG.rst +37 -2
- {greynoise-3.1.0 → greynoise-3.2.0}/PKG-INFO +25 -23
- {greynoise-3.1.0 → greynoise-3.2.0}/docs/source/conf.py +2 -2
- {greynoise-3.1.0 → greynoise-3.2.0}/docs/source/tutorial.rst +125 -3
- {greynoise-3.1.0 → greynoise-3.2.0}/pyproject.toml +24 -22
- {greynoise-3.1.0 → greynoise-3.2.0}/requirements/common.txt +9 -7
- {greynoise-3.1.0 → greynoise-3.2.0}/requirements/dev.txt +5 -5
- {greynoise-3.1.0 → greynoise-3.2.0}/requirements/docs.txt +2 -1
- {greynoise-3.1.0 → greynoise-3.2.0}/requirements/test.txt +8 -6
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/__version__.py +1 -1
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/api/__init__.py +580 -54
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/decorator.py +7 -2
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/formatter.py +23 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/subcommand.py +197 -11
- greynoise-3.2.0/src/greynoise/cli/templates/feeds_consumers.txt.j2 +40 -0
- greynoise-3.2.0/src/greynoise/cli/templates/feeds_events.txt.j2 +78 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/ip_context_result.txt.j2 +13 -3
- greynoise-3.2.0/src/greynoise/exceptions.py +53 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/greynoise_timeline.py +20 -3
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/psychic.py +145 -77
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/util.py +22 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/tests/cli/test_formatter.py +128 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/tests/cli/test_subcommand.py +220 -11
- {greynoise-3.1.0 → greynoise-3.2.0}/tests/test_api.py +738 -22
- greynoise-3.2.0/tests/test_exceptions.py +63 -0
- greynoise-3.2.0/tests/test_greynoise_timeline.py +75 -0
- greynoise-3.2.0/tests/test_psychic.py +589 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/tests/test_util.py +21 -0
- greynoise-3.1.0/src/greynoise/exceptions.py +0 -13
- greynoise-3.1.0/tests/test_psychic.py +0 -272
- {greynoise-3.1.0 → greynoise-3.2.0}/.circleci/config.yml +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.dockerignore +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.editorconfig +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.github/CODEOWNERS +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.github/dependabot.yml +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.github/workflows/slack_release_notice.yml +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.gitignore +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.pre-commit-config.yaml +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.readthedocs.yml +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/.yamllint +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/Dockerfile +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/LICENSE +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/MANIFEST.in +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/Makefile +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/README.rst +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/docs/Makefile +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/docs/source/changelog.rst +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/docs/source/index.rst +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/docs/source/introduction.rst +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/docs/source/reference.rst +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/docs/source/sample.py +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/pytest.ini +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/release.md +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/reset_changelog.py +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/setup.cfg +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/sonar-project.properties +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/__init__.py +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/api/filter.py +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/__init__.py +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/helper.py +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/parameter.py +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/analyze.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/callback_ip.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/cvedetails.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/gnql_query.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/gnql_stats.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/ip_context.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/ip_multi_context.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/ip_quick_check.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/macros.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/personadetails.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/recall_stats.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/recall_timeseries.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/sensorlist.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/stats.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/timeline.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/src/greynoise/cli/templates/timelinedaily.txt.j2 +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/tests/cli/test_init.py +0 -0
- {greynoise-3.1.0 → greynoise-3.2.0}/tox.ini +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[bumpversion]
|
|
2
|
-
current_version = 3.
|
|
2
|
+
current_version = 3.2.0
|
|
3
3
|
tag = False
|
|
4
4
|
commit = False
|
|
5
5
|
|
|
6
6
|
[bumpversion:file:pyproject.toml]
|
|
7
|
-
search = version="{current_version}"
|
|
8
|
-
replace = version="{new_version}"
|
|
7
|
+
search = version = "{current_version}"
|
|
8
|
+
replace = version = "{new_version}"
|
|
9
9
|
|
|
10
10
|
[bumpversion:file:src/greynoise/__version__.py]
|
|
11
11
|
search = __version__ = "{current_version}"
|
|
@@ -2,9 +2,43 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version `3.2.0`_
|
|
6
|
+
================
|
|
7
|
+
**Date**: November 4, 2026
|
|
8
|
+
|
|
9
|
+
* API client:
|
|
10
|
+
|
|
11
|
+
* Corrected proxy settings for Psychic downloads/generation and IP Timeline
|
|
12
|
+
* Psychic downloads and daily timeline lookups use the configured API server
|
|
13
|
+
* `RateLimitError` now includes the API's 429 explanation, and the CLI prints it
|
|
14
|
+
* Added Event Feed search, pull (fetch and optional acknowledge), and consumer management
|
|
15
|
+
* `ip`, `quick`, and `ip_multi` send `workspace_labels`, defaulting to `greynoise,community`
|
|
16
|
+
* Added `callback_file` and `gnql_file` functions to download the pre-built callback and GNQL SIEM files
|
|
17
|
+
* Added `callback_file_metadata` and `gnql_file_metadata` functions to describe the pre-built files without downloading them
|
|
18
|
+
|
|
19
|
+
* CLI:
|
|
20
|
+
|
|
21
|
+
* `feeds search` searches retained feed history without moving a consumer checkpoint
|
|
22
|
+
* `feeds pull` fetches the next batch for a feed consumer and can acknowledge that batch
|
|
23
|
+
* `feeds consumers` lists consumers, or creates, resets, or deletes one checkpoint
|
|
24
|
+
* `ip`, `quick`, and `ip-multi` accept `--workspace-labels` and pass the value through to the API
|
|
25
|
+
* IP text output lists the `source_workspaces` returned for the scopes that were queried
|
|
26
|
+
* `ip --psychic --days` looks up an IP in a Psychic bitmap covering the last N days
|
|
27
|
+
* Psychic text output shows the bitmap date, and says when the IP was not in that file
|
|
28
|
+
* `psychic-download` and `psychic-generate` accept any model number and warn when it is not 1, 2, or 3
|
|
29
|
+
|
|
30
|
+
* Dependencies:
|
|
31
|
+
|
|
32
|
+
* Runtime dependencies now declare a minimum version instead of an exact pin, so applications can install a newer compatible release
|
|
33
|
+
* Updated `Click` to 8.5.0 on Python 3.10 and newer
|
|
34
|
+
* Updated `click-repl` to 0.4.1 on Python 3.9 and newer
|
|
35
|
+
* Updated `cachetools` to 7.2.8 on Python 3.10 and newer
|
|
36
|
+
* Updated `maxminddb` to 3.2.0 on Python 3.10 and newer
|
|
37
|
+
* Updated `more-itertools` to 11.2.1 on Python 3.11 and newer
|
|
38
|
+
|
|
5
39
|
Version `3.1.0`_
|
|
6
40
|
================
|
|
7
|
-
**Date**:
|
|
41
|
+
**Date**: July 9, 2026
|
|
8
42
|
|
|
9
43
|
* API client:
|
|
10
44
|
|
|
@@ -529,4 +563,5 @@ Version `0.2.0`_
|
|
|
529
563
|
.. _`3.0.1`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.0...v3.0.1
|
|
530
564
|
.. _`3.0.2`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.1...v3.0.2
|
|
531
565
|
.. _`3.0.3`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.2...v3.0.3
|
|
532
|
-
.. _`3.1.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.3...
|
|
566
|
+
.. _`3.1.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.0.3...v3.1.0
|
|
567
|
+
.. _`3.2.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v3.1.0...3.2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: greynoise
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Abstraction to interact with GreyNoise API.
|
|
5
5
|
Project-URL: Homepage, https://greynoise.io/
|
|
6
6
|
Project-URL: Repository, https://github.com/GreyNoise-Intelligence/pygreynoise
|
|
@@ -22,27 +22,29 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
23
|
Classifier: Topic :: Software Development :: Libraries
|
|
24
24
|
Requires-Python: >=3.8
|
|
25
|
-
Requires-Dist: ansimarkup
|
|
26
|
-
Requires-Dist: cachetools
|
|
27
|
-
Requires-Dist: cachetools
|
|
28
|
-
Requires-Dist: cachetools
|
|
29
|
-
Requires-Dist: click-default-group
|
|
30
|
-
Requires-Dist: click-repl
|
|
31
|
-
Requires-Dist: click
|
|
32
|
-
Requires-Dist: click
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
36
|
-
Requires-Dist:
|
|
37
|
-
Requires-Dist: maxminddb
|
|
38
|
-
Requires-Dist: maxminddb
|
|
39
|
-
Requires-Dist:
|
|
40
|
-
Requires-Dist: more-itertools
|
|
41
|
-
Requires-Dist: more-itertools
|
|
42
|
-
Requires-Dist:
|
|
43
|
-
Requires-Dist:
|
|
44
|
-
Requires-Dist: requests
|
|
45
|
-
Requires-Dist:
|
|
25
|
+
Requires-Dist: ansimarkup>=2.2.0
|
|
26
|
+
Requires-Dist: cachetools>=5.5.2; python_version == '3.8'
|
|
27
|
+
Requires-Dist: cachetools>=6.2.6; python_version == '3.9'
|
|
28
|
+
Requires-Dist: cachetools>=7.2.8; python_version >= '3.10'
|
|
29
|
+
Requires-Dist: click-default-group>=1.2.4
|
|
30
|
+
Requires-Dist: click-repl>=0.3.0; python_version == '3.8'
|
|
31
|
+
Requires-Dist: click-repl>=0.4.1; python_version >= '3.9'
|
|
32
|
+
Requires-Dist: click<8.2,>=8.1.8; python_version < '3.10'
|
|
33
|
+
Requires-Dist: click>=8.5.0; python_version >= '3.10'
|
|
34
|
+
Requires-Dist: colorama>=0.4.6
|
|
35
|
+
Requires-Dist: dict2xml>=1.7.8
|
|
36
|
+
Requires-Dist: jinja2>=3.1.6
|
|
37
|
+
Requires-Dist: maxminddb>=2.6.3; python_version == '3.8'
|
|
38
|
+
Requires-Dist: maxminddb>=2.8.2; python_version == '3.9'
|
|
39
|
+
Requires-Dist: maxminddb>=3.2.0; python_version >= '3.10'
|
|
40
|
+
Requires-Dist: more-itertools>=10.5.0; python_version == '3.8'
|
|
41
|
+
Requires-Dist: more-itertools>=10.8.0; python_version == '3.9'
|
|
42
|
+
Requires-Dist: more-itertools>=11.1.0; python_version == '3.10'
|
|
43
|
+
Requires-Dist: more-itertools>=11.2.1; python_version >= '3.11'
|
|
44
|
+
Requires-Dist: requests>=2.32.4; python_version == '3.8'
|
|
45
|
+
Requires-Dist: requests>=2.32.5; python_version == '3.9'
|
|
46
|
+
Requires-Dist: requests>=2.34.2; python_version >= '3.10'
|
|
47
|
+
Requires-Dist: six>=1.17.0
|
|
46
48
|
Description-Content-Type: text/x-rst
|
|
47
49
|
|
|
48
50
|
================
|
|
@@ -21,11 +21,11 @@ sys.path.insert(0, os.path.abspath("."))
|
|
|
21
21
|
# -- Project information -----------------------------------------------------
|
|
22
22
|
|
|
23
23
|
project = "greynoise"
|
|
24
|
-
copyright = "2018-
|
|
24
|
+
copyright = "2018-2026, GreyNoise Intelligence"
|
|
25
25
|
author = "GreyNoise Intelligence"
|
|
26
26
|
|
|
27
27
|
# The full version, including alpha/beta/rc tags
|
|
28
|
-
release = "3.
|
|
28
|
+
release = "3.2.0"
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
# -- General configuration ---------------------------------------------------
|
|
@@ -408,6 +408,21 @@ this (this method also supports the include_invalid flag::
|
|
|
408
408
|
}
|
|
409
409
|
]
|
|
410
410
|
|
|
411
|
+
Dataset scopes
|
|
412
|
+
--------------
|
|
413
|
+
|
|
414
|
+
``ip``, ``quick``, and ``ip_multi`` send a ``workspace_labels`` query parameter.
|
|
415
|
+
When the argument is omitted, the client sends ``greynoise,community``. Pass a
|
|
416
|
+
comma-separated string to choose a different set. The values are forwarded as
|
|
417
|
+
given; the API accepts ``greynoise``, ``community``, and ``personal``::
|
|
418
|
+
|
|
419
|
+
>>> api_client.ip('8.8.8.8', workspace_labels='greynoise')
|
|
420
|
+
|
|
421
|
+
``quick`` and ``ip_multi`` take the same argument. A response includes
|
|
422
|
+
``internet_scanner_intelligence.source_workspaces`` for the scopes that contained
|
|
423
|
+
the IP. Successful lookups are cached by IP address and label set, so a later
|
|
424
|
+
call with a different set is not served from the earlier result.
|
|
425
|
+
|
|
411
426
|
Any IP can also be checked to see if there are any Similar IPs in the Noise Dataset::
|
|
412
427
|
|
|
413
428
|
>>> api_client.similar('45.83.66.65')
|
|
@@ -469,8 +484,10 @@ Run a query
|
|
|
469
484
|
~~~~~~~~~~~
|
|
470
485
|
|
|
471
486
|
A GNQL (GreyNoise Query Language) query can be executed to dig deeper into the GreyNoise
|
|
472
|
-
dataset.
|
|
473
|
-
|
|
487
|
+
dataset. Pass ``exclude_fields`` as a comma-separated string or a list of field names
|
|
488
|
+
to omit those fields from the response (the API ``exclude`` parameter). For example, to
|
|
489
|
+
get context information related to activity that has been classified as malicious and
|
|
490
|
+
tagged as a Bluekeep Exploit::
|
|
474
491
|
|
|
475
492
|
>>> api_client.query('last_seen:1d classification:"suspicious" actor:"NiceCrawler"')
|
|
476
493
|
{
|
|
@@ -741,6 +758,60 @@ operating system, etc.::
|
|
|
741
758
|
}
|
|
742
759
|
}
|
|
743
760
|
|
|
761
|
+
Event feeds
|
|
762
|
+
-----------
|
|
763
|
+
|
|
764
|
+
Retained feed events can be searched without moving a consumer checkpoint. Feeds are
|
|
765
|
+
created in the GreyNoise Visualizer. An empty search covers enabled non-session feeds
|
|
766
|
+
over the previous hour. ``event_types`` is limited to ``ip-classification-change``,
|
|
767
|
+
``cve-status-change``, ``cve-activity-spike``, ``vendor-cve-spike``, ``tag-spike``,
|
|
768
|
+
``new-callback-ip``, ``new-callback-file``, and ``credential-observed``::
|
|
769
|
+
|
|
770
|
+
>>> api_client.feed_search(event_types=['tag-spike'], ip='8.8.8.8', from_time='24h', limit=100)
|
|
771
|
+
|
|
772
|
+
Pass the returned ``cursor`` by itself, with an optional ``limit``, to read the next page.
|
|
773
|
+
``feed_pull`` reads the next batch for one consumer and does not advance that checkpoint
|
|
774
|
+
unless ``ack=True``. ``cursor`` acknowledges a batch that was already fetched::
|
|
775
|
+
|
|
776
|
+
>>> api_client.feed_pull('<feed_uuid>', consumer='worker-1', limit=100, ack=True)
|
|
777
|
+
|
|
778
|
+
``feed_consumers`` lists checkpoints, or creates, resets, or deletes one. A new consumer
|
|
779
|
+
starts at the beginning of retained history. Reset replays that history. Delete removes
|
|
780
|
+
only that checkpoint::
|
|
781
|
+
|
|
782
|
+
>>> api_client.feed_consumers('<feed_uuid>', action='create', consumer='worker-1')
|
|
783
|
+
|
|
784
|
+
These methods are not available with the community offering.
|
|
785
|
+
|
|
786
|
+
Pre-built files
|
|
787
|
+
---------------
|
|
788
|
+
|
|
789
|
+
GreyNoise builds SIEM lookup files server-side and refreshes them hourly. Both downloads
|
|
790
|
+
request the only file the API serves (CSV, NG-SIEM profile), stream the body to a path or
|
|
791
|
+
a binary file object, and return a ``FileResult``. A path is written to a temporary file
|
|
792
|
+
and moved into place only when the status is ``ok``, so a failed download leaves an
|
|
793
|
+
existing file in place.
|
|
794
|
+
|
|
795
|
+
``callback_file`` downloads the callback IP file. ``days`` is the lookback window, from
|
|
796
|
+
1 to 7, and defaults to 7. Callback files do not report ``truncated``::
|
|
797
|
+
|
|
798
|
+
>>> api_client.callback_file('callback.csv', days=7)
|
|
799
|
+
FileResult(status='ok', generated_at='2026-10-29T10:00:00Z', row_count=100000, total_count=None, truncated=None, feed_status=None, retry_after=None)
|
|
800
|
+
|
|
801
|
+
``gnql_file`` downloads the file for a GNQL query::
|
|
802
|
+
|
|
803
|
+
>>> api_client.gnql_file('last_seen:1d -classification:unknown', 'feed.csv', limit=100000)
|
|
804
|
+
FileResult(status='ok', generated_at='2026-10-29T10:00:00Z', row_count=100000, total_count=250000, truncated=True, feed_status='enabled', retry_after=None)
|
|
805
|
+
|
|
806
|
+
The first request for a new query subscribes to it and returns status ``provisioning``
|
|
807
|
+
until the file is built. Nothing is written in that case; retry after
|
|
808
|
+
``result.retry_after`` seconds. Integrations should identify themselves with
|
|
809
|
+
``integration='name/version'``, which is sent as ``X-GreyNoise-Integration``.
|
|
810
|
+
``callback_file_metadata`` and ``gnql_file_metadata`` take the same arguments as the
|
|
811
|
+
download functions (without ``output``) and return the same fields without downloading
|
|
812
|
+
the file. Error responses raise ``RequestFailure`` (``RateLimitError`` for HTTP 429)
|
|
813
|
+
with the status code and the API's explanation.
|
|
814
|
+
|
|
744
815
|
|
|
745
816
|
Command line interface
|
|
746
817
|
======================
|
|
@@ -761,12 +832,14 @@ subcommands, use the *--help* option::
|
|
|
761
832
|
analyze Analyze the IP addresses in a log file, stdin, etc.
|
|
762
833
|
callback GreyNoise Callback — scanner callback intelligence...
|
|
763
834
|
cve Retrieve Details of a CVE.
|
|
835
|
+
feeds Search retained feed events, pull a batch, or manage...
|
|
764
836
|
filter Filter the noise from a log file, stdin, etc.
|
|
765
837
|
help Show this message and exit.
|
|
766
838
|
ip Query GreyNoise for all information on a given IP.
|
|
767
839
|
ip-multi Perform Context lookup for multiple IPs at once.
|
|
768
840
|
persona-details Retrieve Details of a Sensor Persona.
|
|
769
841
|
psychic-download Download a Psychic bitmap (.bin), MMDB, or CSV file...
|
|
842
|
+
psychic-generate Generate a Psychic bitmap (.bin) for a date range...
|
|
770
843
|
query Run a GNQL (GreyNoise Query Language) query.
|
|
771
844
|
quick Quickly check whether or not one or many IPs are...
|
|
772
845
|
recall GreyNoise Recall — GNQL activity over time.
|
|
@@ -937,6 +1010,19 @@ this (a comma separated list is also supported::
|
|
|
937
1010
|
Last Updated: 2025-05-23T13:11:02Z
|
|
938
1011
|
Reference: https://developers.google.com/speed/public-dns/docs/isp#alternative
|
|
939
1012
|
|
|
1013
|
+
``ip``, ``quick``, and ``ip-multi`` accept ``--workspace-labels``. The default is
|
|
1014
|
+
``greynoise,community``. The value is sent unchanged, and text output lists the
|
|
1015
|
+
``source_workspaces`` the API returned::
|
|
1016
|
+
|
|
1017
|
+
$ greynoise ip 8.8.8.8 --workspace-labels greynoise
|
|
1018
|
+
|
|
1019
|
+
``ip --psychic`` looks the address up in a Psychic bitmap instead of calling the IP
|
|
1020
|
+
lookup API. ``--days`` builds that bitmap for the last N days through today and
|
|
1021
|
+
requires ``--psychic``. Text output shows the bitmap date, and says when the IP was
|
|
1022
|
+
not in that file. ``--workspace-labels`` is not applied to a Psychic lookup::
|
|
1023
|
+
|
|
1024
|
+
$ greynoise ip 1.2.3.4 --psychic --days 7
|
|
1025
|
+
|
|
940
1026
|
Check for Similar IPs to a given IP::
|
|
941
1027
|
|
|
942
1028
|
$ greynoise similar 69.160.160.55
|
|
@@ -1003,6 +1089,40 @@ Check the Timeline of a given IP::
|
|
|
1003
1089
|
2025-05-11 1 suspicious
|
|
1004
1090
|
2025-04-27 1 suspicious
|
|
1005
1091
|
|
|
1092
|
+
Event feeds
|
|
1093
|
+
-----------
|
|
1094
|
+
|
|
1095
|
+
``feeds search`` reads retained history and does not move a consumer checkpoint.
|
|
1096
|
+
Repeat ``--feed-id`` and ``--event-type`` to pass more than one value. ``--from``
|
|
1097
|
+
accepts a relative window such as ``24h`` or ``7d``, a UTC date, or an RFC3339
|
|
1098
|
+
timestamp. ``--cursor`` continues a previous page and cannot be combined with
|
|
1099
|
+
other filters::
|
|
1100
|
+
|
|
1101
|
+
$ greynoise feeds search --event-type tag-spike --ip 8.8.8.8 --from 24h --limit 100
|
|
1102
|
+
|
|
1103
|
+
``feeds pull`` fetches the next batch for one consumer. The checkpoint stays put
|
|
1104
|
+
unless ``--ack`` is set. Text output for a pull without ``--ack`` shows the first
|
|
1105
|
+
25 events (100 with ``-v``). An acknowledged pull prints the full batch and states
|
|
1106
|
+
that the checkpoint advanced past every event in it. ``--cursor`` acknowledges a
|
|
1107
|
+
previously fetched batch without fetching again::
|
|
1108
|
+
|
|
1109
|
+
$ greynoise feeds pull <feed_uuid> --consumer worker-1 --limit 100 --ack
|
|
1110
|
+
|
|
1111
|
+
``feeds consumers`` lists checkpoints for a feed. ``--action create`` starts a
|
|
1112
|
+
consumer at the beginning of retained history, ``reset`` replays that history,
|
|
1113
|
+
and ``delete`` removes one checkpoint::
|
|
1114
|
+
|
|
1115
|
+
$ greynoise feeds consumers <feed_uuid> --action create --consumer worker-1
|
|
1116
|
+
|
|
1117
|
+
Psychic files
|
|
1118
|
+
-------------
|
|
1119
|
+
|
|
1120
|
+
``psychic-download`` writes a bitmap (``.bin``), MMDB, or CSV for one date into
|
|
1121
|
+
the current directory. ``psychic-generate`` builds a bitmap for a date range::
|
|
1122
|
+
|
|
1123
|
+
$ greynoise psychic-download --format mmdb --date 2026-10-26
|
|
1124
|
+
$ greynoise psychic-generate --start-date 2026-10-20 --end-date 2026-10-26
|
|
1125
|
+
|
|
1006
1126
|
GNQL
|
|
1007
1127
|
----
|
|
1008
1128
|
|
|
@@ -1010,7 +1130,7 @@ Run a query
|
|
|
1010
1130
|
~~~~~~~~~~~
|
|
1011
1131
|
|
|
1012
1132
|
A GNQL (GreyNoise Query Language) query can be executed to dig deeper into the GreyNoise
|
|
1013
|
-
dataset. For example, to get context information related to activity has been classified
|
|
1133
|
+
dataset. For example, to get context information related to activity that has been classified
|
|
1014
1134
|
as malicious and tagged as a Bluekeep Exploit::
|
|
1015
1135
|
|
|
1016
1136
|
$ greynoise query "classification:malicious tags:Bluekeep Exploit"
|
|
@@ -1068,6 +1188,8 @@ as malicious and tagged as a Bluekeep Exploit::
|
|
|
1068
1188
|
This is the default command, that is, you can save some typing by just
|
|
1069
1189
|
writing ``greynoise <query>`` instead of ``greynoise query <query>``.
|
|
1070
1190
|
|
|
1191
|
+
``--exclude`` is a comma-separated list of fields to omit from the results.
|
|
1192
|
+
|
|
1071
1193
|
|
|
1072
1194
|
Get statistics
|
|
1073
1195
|
~~~~~~~~~~~~~~
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "greynoise"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.2.0"
|
|
8
8
|
description = "Abstraction to interact with GreyNoise API."
|
|
9
9
|
readme = {file = "README.rst", content-type = "text/x-rst"}
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -28,27 +28,29 @@ classifiers = [
|
|
|
28
28
|
]
|
|
29
29
|
keywords = ["internet", "scanning", "threat intelligence", "security"]
|
|
30
30
|
dependencies = [
|
|
31
|
-
"Click
|
|
32
|
-
"Click
|
|
33
|
-
"ansimarkup
|
|
34
|
-
"cachetools
|
|
35
|
-
"cachetools
|
|
36
|
-
"cachetools
|
|
37
|
-
"colorama
|
|
38
|
-
"click-default-group
|
|
39
|
-
"click-repl
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"maxminddb
|
|
44
|
-
"maxminddb
|
|
45
|
-
"
|
|
46
|
-
"more-itertools
|
|
47
|
-
"more-itertools
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"requests
|
|
51
|
-
"
|
|
31
|
+
"Click>=8.1.8,<8.2; python_version < '3.10'",
|
|
32
|
+
"Click>=8.5.0; python_version >= '3.10'",
|
|
33
|
+
"ansimarkup>=2.2.0",
|
|
34
|
+
"cachetools>=5.5.2; python_version == '3.8'",
|
|
35
|
+
"cachetools>=6.2.6; python_version == '3.9'",
|
|
36
|
+
"cachetools>=7.2.8; python_version >= '3.10'",
|
|
37
|
+
"colorama>=0.4.6",
|
|
38
|
+
"click-default-group>=1.2.4",
|
|
39
|
+
"click-repl>=0.3.0; python_version == '3.8'",
|
|
40
|
+
"click-repl>=0.4.1; python_version >= '3.9'",
|
|
41
|
+
"dict2xml>=1.7.8",
|
|
42
|
+
"jinja2>=3.1.6",
|
|
43
|
+
"maxminddb>=2.6.3; python_version == '3.8'",
|
|
44
|
+
"maxminddb>=2.8.2; python_version == '3.9'",
|
|
45
|
+
"maxminddb>=3.2.0; python_version >= '3.10'",
|
|
46
|
+
"more-itertools>=10.5.0; python_version == '3.8'",
|
|
47
|
+
"more-itertools>=10.8.0; python_version == '3.9'",
|
|
48
|
+
"more-itertools>=11.1.0; python_version == '3.10'",
|
|
49
|
+
"more-itertools>=11.2.1; python_version >= '3.11'",
|
|
50
|
+
"requests>=2.32.4; python_version == '3.8'",
|
|
51
|
+
"requests>=2.32.5; python_version == '3.9'",
|
|
52
|
+
"requests>=2.34.2; python_version >= '3.10'",
|
|
53
|
+
"six>=1.17.0",
|
|
52
54
|
]
|
|
53
55
|
|
|
54
56
|
[project.urls]
|
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
Click<=8.1.8;python_version=="3.8"
|
|
2
2
|
Click<=8.1.8;python_version=="3.9"
|
|
3
|
-
Click==8.
|
|
3
|
+
Click==8.5.0;python_version>="3.10"
|
|
4
4
|
ansimarkup==2.2.0
|
|
5
5
|
cachetools==5.5.2;python_version=="3.8"
|
|
6
6
|
cachetools==6.2.6;python_version=="3.9"
|
|
7
|
-
cachetools==7.
|
|
7
|
+
cachetools==7.2.8;python_version>="3.10"
|
|
8
8
|
colorama==0.4.6
|
|
9
9
|
click-default-group==1.2.4
|
|
10
|
-
click-repl==0.3.0
|
|
11
|
-
|
|
10
|
+
click-repl==0.3.0;python_version=="3.8"
|
|
11
|
+
click-repl==0.4.1;python_version>="3.9"
|
|
12
|
+
dict2xml==1.7.8
|
|
12
13
|
jinja2==3.1.6
|
|
13
14
|
maxminddb==2.6.3;python_version=="3.8"
|
|
14
15
|
maxminddb==2.8.2;python_version=="3.9"
|
|
15
|
-
maxminddb==3.
|
|
16
|
+
maxminddb==3.2.0;python_version>="3.10"
|
|
16
17
|
more-itertools==10.5.0;python_version=="3.8"
|
|
17
18
|
more-itertools==10.8.0;python_version=="3.9"
|
|
18
|
-
more-itertools==11.1.0;python_version
|
|
19
|
+
more-itertools==11.1.0;python_version=="3.10"
|
|
20
|
+
more-itertools==11.2.1;python_version>="3.11"
|
|
19
21
|
requests==2.32.4;python_version=="3.8"
|
|
20
22
|
requests==2.32.5;python_version=="3.9"
|
|
21
23
|
requests==2.34.2;python_version>="3.10"
|
|
22
|
-
six==1.17.0
|
|
24
|
+
six==1.17.0
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Requirements needed to develop the application
|
|
2
2
|
-r test.txt
|
|
3
3
|
advbumpversion==1.2.0
|
|
4
|
-
ipython==8.
|
|
4
|
+
ipython==8.12.3;python_version=="3.8"
|
|
5
5
|
ipython==8.18.1;python_version=="3.9"
|
|
6
|
-
ipython==8.
|
|
7
|
-
ipython==9.
|
|
8
|
-
ipython==9.12.0;python_version>="3.12"
|
|
6
|
+
ipython==8.39.0;python_version=="3.10"
|
|
7
|
+
ipython==9.17.1;python_version>="3.11"
|
|
9
8
|
tox==4.25.0;python_version=="3.8"
|
|
10
9
|
tox==4.30.3;python_version=="3.9"
|
|
11
|
-
tox==4.
|
|
10
|
+
tox==4.65.0;python_version=="3.10"
|
|
11
|
+
tox==4.67.1;python_version>="3.11"
|
|
@@ -4,7 +4,8 @@ Sphinx==7.1.2;python_version=="3.8"
|
|
|
4
4
|
Sphinx==7.4.7;python_version=="3.9"
|
|
5
5
|
Sphinx==8.1.3;python_version=="3.10"
|
|
6
6
|
Sphinx==9.0.4;python_version=="3.11"
|
|
7
|
-
Sphinx==9.1.
|
|
7
|
+
Sphinx==9.1.1;python_version=="3.12"
|
|
8
|
+
Sphinx==9.2.0;python_version>="3.13"
|
|
8
9
|
sphinx-click==6.0.0;python_version=="3.8"
|
|
9
10
|
sphinx-click==6.0.0;python_version=="3.9"
|
|
10
11
|
sphinx-click==6.2.0;python_version>="3.10"
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
black==24.8.0;python_version=="3.8"
|
|
2
2
|
black==25.11.0;python_version=="3.9"
|
|
3
|
-
black==26.
|
|
3
|
+
black==26.10.1;python_version>="3.10"
|
|
4
4
|
flake8==7.1.2;python_version=="3.8"
|
|
5
|
-
flake8==7.3.0;python_version
|
|
5
|
+
flake8==7.3.0;python_version=="3.9"
|
|
6
|
+
flake8==7.4.1;python_version>="3.10"
|
|
6
7
|
isort==5.13.2;python_version=="3.8"
|
|
7
8
|
isort==6.1.0;python_version=="3.9"
|
|
8
|
-
isort==
|
|
9
|
+
isort==9.0.2;python_version>="3.10"
|
|
9
10
|
mock==5.2.0
|
|
10
11
|
pylint==3.2.7;python_version=="3.8"
|
|
11
12
|
pylint==3.3.9;python_version=="3.9"
|
|
12
|
-
pylint==4.
|
|
13
|
+
pylint==4.1.3;python_version>="3.10"
|
|
13
14
|
pytest-cov==5.0.0;python_version=="3.8"
|
|
14
15
|
pytest-cov==7.1.0;python_version>="3.9"
|
|
15
16
|
pytest==8.3.5;python_version=="3.8"
|
|
16
17
|
pytest==8.4.2;python_version=="3.9"
|
|
17
|
-
pytest==9.
|
|
18
|
+
pytest==9.1.1;python_version>="3.10"
|
|
18
19
|
restructuredtext-lint==2.0.2
|
|
19
20
|
twine==6.1.0;python_version=="3.8"
|
|
20
|
-
twine==6.2.0;python_version
|
|
21
|
+
twine==6.2.0;python_version=="3.9"
|
|
22
|
+
twine==7.0.0;python_version>="3.10"
|
|
21
23
|
yamllint==1.35.1;python_version=="3.8"
|
|
22
24
|
yamllint==1.37.1;python_version=="3.9"
|
|
23
25
|
yamllint==1.38.0;python_version>="3.10"
|