greynoise 2.2.0__tar.gz → 2.3.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-2.2.0 → greynoise-2.3.0}/CHANGELOG.rst +18 -1
- {greynoise-2.2.0/src/greynoise.egg-info → greynoise-2.3.0}/PKG-INFO +19 -2
- {greynoise-2.2.0 → greynoise-2.3.0}/setup.py +1 -1
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/__version__.py +1 -1
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/api/__init__.py +25 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/decorator.py +38 -2
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/formatter.py +9 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/subcommand.py +20 -0
- greynoise-2.3.0/src/greynoise/cli/templates/cvedetails.txt.j2 +53 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/util.py +19 -0
- {greynoise-2.2.0 → greynoise-2.3.0/src/greynoise.egg-info}/PKG-INFO +19 -2
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise.egg-info/SOURCES.txt +1 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/LICENSE +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/MANIFEST.in +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/README.rst +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/setup.cfg +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/__init__.py +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/api/filter.py +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/__init__.py +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/helper.py +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/parameter.py +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/analyze.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/gnql_query.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/gnql_stats.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/interesting.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/ip_community.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/ip_context.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/ip_context_result.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/ip_multi_context.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/ip_quick_check.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/macros.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/personadetails.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/riot.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/sensoractivity.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/sensorlist.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/similarity.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/stats.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/timeline.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/cli/templates/timelinehourly.txt.j2 +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise/exceptions.py +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise.egg-info/dependency_links.txt +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise.egg-info/entry_points.txt +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise.egg-info/not-zip-safe +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise.egg-info/requires.txt +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/src/greynoise.egg-info/top_level.txt +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/tests/test_api.py +0 -0
- {greynoise-2.2.0 → greynoise-2.3.0}/tests/test_util.py +0 -0
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
Changelog
|
|
3
3
|
=========
|
|
4
4
|
|
|
5
|
+
Version `2.3.0`_
|
|
6
|
+
================
|
|
7
|
+
**Date**: July 30, 2024
|
|
8
|
+
|
|
9
|
+
* API client:
|
|
10
|
+
|
|
11
|
+
* Add `cve` command to query the CVE lookup API
|
|
12
|
+
|
|
13
|
+
* CLI:
|
|
14
|
+
|
|
15
|
+
* Add `cve` command to display result from CVE lookup API
|
|
16
|
+
|
|
17
|
+
* Dependencies:
|
|
18
|
+
|
|
19
|
+
* Updated cachetools to version 5.4.0
|
|
20
|
+
|
|
5
21
|
Version `2.2.0`_
|
|
6
22
|
================
|
|
7
23
|
**Date**: June 11, 2024
|
|
@@ -412,4 +428,5 @@ Version `0.2.0`_
|
|
|
412
428
|
.. _`2.0.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v1.3.0...2.0.0
|
|
413
429
|
.. _`2.0.1`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.0.0...2.0.1
|
|
414
430
|
.. _`2.1.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.0.1...2.1.0
|
|
415
|
-
.. _`2.2.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.1.0...
|
|
431
|
+
.. _`2.2.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.1.0...2.2.0
|
|
432
|
+
.. _`2.3.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.2.0...HEAD
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: greynoise
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Abstraction to interact with GreyNoise API.
|
|
5
5
|
Home-page: https://greynoise.io/
|
|
6
6
|
Download-URL: https://github.com/GreyNoise-Intelligence/pygreynoise
|
|
@@ -124,6 +124,22 @@ Usage
|
|
|
124
124
|
Changelog
|
|
125
125
|
=========
|
|
126
126
|
|
|
127
|
+
Version `2.3.0`_
|
|
128
|
+
================
|
|
129
|
+
**Date**: July 30, 2024
|
|
130
|
+
|
|
131
|
+
* API client:
|
|
132
|
+
|
|
133
|
+
* Add `cve` command to query the CVE lookup API
|
|
134
|
+
|
|
135
|
+
* CLI:
|
|
136
|
+
|
|
137
|
+
* Add `cve` command to display result from CVE lookup API
|
|
138
|
+
|
|
139
|
+
* Dependencies:
|
|
140
|
+
|
|
141
|
+
* Updated cachetools to version 5.4.0
|
|
142
|
+
|
|
127
143
|
Version `2.2.0`_
|
|
128
144
|
================
|
|
129
145
|
**Date**: June 11, 2024
|
|
@@ -534,4 +550,5 @@ Version `0.2.0`_
|
|
|
534
550
|
.. _`2.0.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v1.3.0...2.0.0
|
|
535
551
|
.. _`2.0.1`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.0.0...2.0.1
|
|
536
552
|
.. _`2.1.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.0.1...2.1.0
|
|
537
|
-
.. _`2.2.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.1.0...
|
|
553
|
+
.. _`2.2.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.1.0...2.2.0
|
|
554
|
+
.. _`2.3.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.2.0...HEAD
|
|
@@ -15,6 +15,7 @@ from greynoise.api.filter import Filter
|
|
|
15
15
|
from greynoise.exceptions import RateLimitError, RequestFailure
|
|
16
16
|
from greynoise.util import (
|
|
17
17
|
load_config,
|
|
18
|
+
validate_cve_id,
|
|
18
19
|
validate_ip,
|
|
19
20
|
validate_similar_min_score,
|
|
20
21
|
validate_timeline_days,
|
|
@@ -61,6 +62,7 @@ class GreyNoise(object): # pylint: disable=R0205,R0902
|
|
|
61
62
|
EP_SENSOR_ACTIVITY = "v1/workspaces/{workspace_id}/sensors/activity"
|
|
62
63
|
EP_SENSOR_LIST = "v1/workspaces/{workspace_id}/sensors"
|
|
63
64
|
EP_PERSONA_DETAILS = "v1/personas/{persona_id}"
|
|
65
|
+
EP_CVE_LOOKUP = "v1/cve/{cve_id}"
|
|
64
66
|
EP_ANALYZE_UPLOAD = "v2/analyze/upload"
|
|
65
67
|
EP_ANALYZE = "v2/analyze/{id}"
|
|
66
68
|
EP_NOT_IMPLEMENTED = "v2/request/{subcommand}"
|
|
@@ -962,3 +964,26 @@ class GreyNoise(object): # pylint: disable=R0205,R0902
|
|
|
962
964
|
response = self._request(endpoint)
|
|
963
965
|
|
|
964
966
|
return response
|
|
967
|
+
|
|
968
|
+
def cve(self, cve_id=None):
|
|
969
|
+
"""Get CVE details by CVE ID
|
|
970
|
+
|
|
971
|
+
:param cve_id: ID of CVE
|
|
972
|
+
:type cve_id: str
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
"""
|
|
976
|
+
if self.offering == "community":
|
|
977
|
+
response = {
|
|
978
|
+
"message": "CVE lookup is not supported with Community offering"
|
|
979
|
+
}
|
|
980
|
+
else:
|
|
981
|
+
LOGGER.debug("Getting Details for CVE ID: %s...", cve_id)
|
|
982
|
+
|
|
983
|
+
# check if CVE submitted is in correct format
|
|
984
|
+
validate_cve_id(cve_id)
|
|
985
|
+
|
|
986
|
+
endpoint = self.EP_CVE_LOOKUP.format(cve_id=cve_id)
|
|
987
|
+
response = self._request(endpoint)
|
|
988
|
+
|
|
989
|
+
return response
|
|
@@ -240,7 +240,7 @@ def not_implemented_command(function):
|
|
|
240
240
|
|
|
241
241
|
|
|
242
242
|
def workspace_command(function):
|
|
243
|
-
"""Decorator that groups decorators common to
|
|
243
|
+
"""Decorator that groups decorators common to workspace subcommands."""
|
|
244
244
|
|
|
245
245
|
@click.command()
|
|
246
246
|
@click.argument("workspace_id", required=True)
|
|
@@ -323,7 +323,7 @@ def sensor_activity_command(function):
|
|
|
323
323
|
|
|
324
324
|
|
|
325
325
|
def persona_command(function):
|
|
326
|
-
"""Decorator that groups decorators common to
|
|
326
|
+
"""Decorator that groups decorators common to persona subcommands."""
|
|
327
327
|
|
|
328
328
|
@click.command()
|
|
329
329
|
@click.argument("persona_id", required=True)
|
|
@@ -356,3 +356,39 @@ def persona_command(function):
|
|
|
356
356
|
return function(*args, **kwargs)
|
|
357
357
|
|
|
358
358
|
return wrapper
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def cve_command(function):
|
|
362
|
+
"""Decorator that groups decorators common to cve subcommand."""
|
|
363
|
+
|
|
364
|
+
@click.command()
|
|
365
|
+
@click.argument("cve_id", required=True)
|
|
366
|
+
@click.option("-k", "--api-key", help="Key to include in API requests")
|
|
367
|
+
@click.option(
|
|
368
|
+
"-O",
|
|
369
|
+
"--offering",
|
|
370
|
+
help="Which API offering to use, enterprise or community, "
|
|
371
|
+
"defaults to enterprise",
|
|
372
|
+
)
|
|
373
|
+
@click.option("-i", "--input", "input_file", type=click.File(), help="Input file")
|
|
374
|
+
@click.option(
|
|
375
|
+
"-o", "--output", "output_file", type=click.File(mode="w"), help="Output file"
|
|
376
|
+
)
|
|
377
|
+
@click.option(
|
|
378
|
+
"-f",
|
|
379
|
+
"--format",
|
|
380
|
+
"output_format",
|
|
381
|
+
type=click.Choice(["json", "txt", "xml"]),
|
|
382
|
+
default="txt",
|
|
383
|
+
help="Output format",
|
|
384
|
+
)
|
|
385
|
+
@click.option("-v", "--verbose", count=True, help="Verbose output")
|
|
386
|
+
@pass_api_client
|
|
387
|
+
@click.pass_context
|
|
388
|
+
@echo_result
|
|
389
|
+
@handle_exceptions
|
|
390
|
+
@functools.wraps(function)
|
|
391
|
+
def wrapper(*args, **kwargs):
|
|
392
|
+
return function(*args, **kwargs)
|
|
393
|
+
|
|
394
|
+
return wrapper
|
|
@@ -218,6 +218,14 @@ def personadetails_formatter(results, verbose):
|
|
|
218
218
|
return template.render(results=results, verbose=verbose, max_width=max_width)
|
|
219
219
|
|
|
220
220
|
|
|
221
|
+
@colored_output
|
|
222
|
+
def cvedetails_formatter(results, verbose):
|
|
223
|
+
"""Convert CVE Details to human-readable text."""
|
|
224
|
+
template = JINJA2_ENV.get_template("cvedetails.txt.j2")
|
|
225
|
+
max_width, _ = shutil.get_terminal_size()
|
|
226
|
+
return template.render(results=results, verbose=verbose, max_width=max_width)
|
|
227
|
+
|
|
228
|
+
|
|
221
229
|
FORMATTERS = {
|
|
222
230
|
"json": json_formatter,
|
|
223
231
|
"xml": xml_formatter,
|
|
@@ -237,5 +245,6 @@ FORMATTERS = {
|
|
|
237
245
|
"sensor-activity": sensoractivity_formatter,
|
|
238
246
|
"sensor-list": sensorlist_formatter,
|
|
239
247
|
"persona-details": personadetails_formatter,
|
|
248
|
+
"cve": cvedetails_formatter,
|
|
240
249
|
},
|
|
241
250
|
}
|
|
@@ -7,6 +7,7 @@ import click
|
|
|
7
7
|
|
|
8
8
|
from greynoise.__version__ import __version__
|
|
9
9
|
from greynoise.cli.decorator import (
|
|
10
|
+
cve_command,
|
|
10
11
|
echo_result,
|
|
11
12
|
gnql_command,
|
|
12
13
|
handle_exceptions,
|
|
@@ -497,3 +498,22 @@ def persona_details(
|
|
|
497
498
|
persona_id=persona_id,
|
|
498
499
|
)
|
|
499
500
|
return result
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
@cve_command
|
|
504
|
+
def cve(
|
|
505
|
+
context,
|
|
506
|
+
api_client,
|
|
507
|
+
api_key,
|
|
508
|
+
input_file,
|
|
509
|
+
output_file,
|
|
510
|
+
output_format,
|
|
511
|
+
verbose,
|
|
512
|
+
cve_id,
|
|
513
|
+
offering,
|
|
514
|
+
):
|
|
515
|
+
"""Retrieve Details of a CVE."""
|
|
516
|
+
result = api_client.cve(
|
|
517
|
+
cve_id=cve_id,
|
|
518
|
+
)
|
|
519
|
+
return result
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{% import "macros.txt.j2" as macros with context %}
|
|
2
|
+
{%- if results.details %}
|
|
3
|
+
----------------------------
|
|
4
|
+
<header>CVE Details</header>
|
|
5
|
+
----------------------------
|
|
6
|
+
<key>CVE</key>: <value>{{ results.id }}</value>
|
|
7
|
+
<key>Vuln Name</key>: <value>{{ results.details.vulnerability_name }}</value>
|
|
8
|
+
<key>Vuln Description</key>: <value>{{ results.details.vulnerability_description }}</value>
|
|
9
|
+
<key>Vendor</key>: <value>{{ results.details.vendor }}</value>
|
|
10
|
+
<key>Product</key>: <value>{{ results.details.product }}</value>
|
|
11
|
+
<key>CVSS Score</key>: <value>{{ results.details.cve_cvss_score }}</value>
|
|
12
|
+
<key>Published to NIST NVD</key>: <value>{{ results.details.published_to_nist_nvd }}</value>
|
|
13
|
+
|
|
14
|
+
{% if results.timeline -%}
|
|
15
|
+
<header>Timeline Information</header>
|
|
16
|
+
--------------------
|
|
17
|
+
<key>Published Date</key>: <value>{{ results.timeline.cve_published_date.split("T")[0] }}</value>
|
|
18
|
+
<key>Last Updated Date</key>: <value>{{ results.timeline.cve_last_updated_date.split("T")[0] }}</value>
|
|
19
|
+
<key>First Known Date</key>: <value>{{ results.timeline.first_known_published_date.split("T")[0] }}</value>
|
|
20
|
+
<key>Added to CISA Kev Date</key>: <value>{{ results.timeline.cisa_kev_date_added.split("T")[0] }}</value>
|
|
21
|
+
{%- endif %}
|
|
22
|
+
|
|
23
|
+
{% if results.exploitation_details -%}
|
|
24
|
+
<header>Exploitation Details</header>
|
|
25
|
+
--------------------
|
|
26
|
+
<key>Attack Vector</key>: <value>{{ results.exploitation_details.attack_vector }}</value>
|
|
27
|
+
<key>Exploit Found</key>: <value>{{ results.exploitation_details.exploit_found }}</value>
|
|
28
|
+
<key>Exploit in KEV</key>: <value>{{ results.exploitation_details.exploitation_registered_in_kev }}</value>
|
|
29
|
+
<key>EPSS Score</key>: <value>{{ results.exploitation_details.epss_score }}</value>
|
|
30
|
+
{%- endif %}
|
|
31
|
+
|
|
32
|
+
{% if results.exploitation_stats -%}
|
|
33
|
+
<header>Exploitation Stats</header>
|
|
34
|
+
------------------
|
|
35
|
+
<key># of Exploits</key>: <value>{{ results.exploitation_stats.number_of_available_exploits }}</value>
|
|
36
|
+
<key># of Threat Actors</key>: <value>{{ results.exploitation_stats.number_of_threat_actors_exploiting_vulnerability }}</value>
|
|
37
|
+
<key># of Botnets </key>: <value>{{ results.exploitation_stats.number_of_botnets_exploiting_vulnerability }}</value>
|
|
38
|
+
{%- endif %}
|
|
39
|
+
|
|
40
|
+
{% if results.exploitation_activity -%}
|
|
41
|
+
<header>Exploitation Activity</header>
|
|
42
|
+
---------------------
|
|
43
|
+
<key>Activity Seen</key>: <value>{{ results.exploitation_activity.activity_seen }}</value>
|
|
44
|
+
<key># Benign Scanners - 1 Day</key>: <value>{{ results.exploitation_activity.benign_ip_count_1d }}</value>
|
|
45
|
+
<key># Benign Scanners - 10 Days</key>: <value>{{ results.exploitation_activity.benign_ip_count_10d }}</value>
|
|
46
|
+
<key># Benign Scanners - 30 Days</key>: <value>{{ results.exploitation_activity.benign_ip_count_30d }}</value>
|
|
47
|
+
<key># Suspicious Scanners - 1 Day</key>: <value>{{ results.exploitation_activity.threat_ip_count_1d }}</value>
|
|
48
|
+
<key># Suspicious Scanners - 10 Day</key>: <value>{{ results.exploitation_activity.threat_ip_count_10d }}</value>
|
|
49
|
+
<key># Suspicious Scanners - 30 Day</key>: <value>{{ results.exploitation_activity.threat_ip_count_30d }}</value>
|
|
50
|
+
{%- endif %}
|
|
51
|
+
{% else %}
|
|
52
|
+
Provided CVE was not found or valid.
|
|
53
|
+
{%- endif %}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Utility functions."""
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
|
+
import re
|
|
4
5
|
from ipaddress import IPv6Address, ip_address
|
|
5
6
|
|
|
6
7
|
from six.moves.configparser import ConfigParser
|
|
@@ -228,3 +229,21 @@ def validate_similar_min_score(min_score):
|
|
|
228
229
|
return True
|
|
229
230
|
else:
|
|
230
231
|
raise ValueError("Min Score must be a valid integer between 0 and 100.")
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def validate_cve_id(cve_id):
|
|
235
|
+
"""Check if provided value is a valid CVE ID
|
|
236
|
+
|
|
237
|
+
:param cve_id: field value to validate.
|
|
238
|
+
:type cve_id: str
|
|
239
|
+
|
|
240
|
+
"""
|
|
241
|
+
# CVE regular expression
|
|
242
|
+
cve_pattern = r"CVE-\d{4}-\d{4,7}"
|
|
243
|
+
|
|
244
|
+
pattern = re.compile(cve_pattern)
|
|
245
|
+
|
|
246
|
+
if not pattern.match(cve_id):
|
|
247
|
+
raise ValueError("The provided ID does not match the format: CVE-XXXX-YYYYY")
|
|
248
|
+
else:
|
|
249
|
+
return True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: greynoise
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Abstraction to interact with GreyNoise API.
|
|
5
5
|
Home-page: https://greynoise.io/
|
|
6
6
|
Download-URL: https://github.com/GreyNoise-Intelligence/pygreynoise
|
|
@@ -124,6 +124,22 @@ Usage
|
|
|
124
124
|
Changelog
|
|
125
125
|
=========
|
|
126
126
|
|
|
127
|
+
Version `2.3.0`_
|
|
128
|
+
================
|
|
129
|
+
**Date**: July 30, 2024
|
|
130
|
+
|
|
131
|
+
* API client:
|
|
132
|
+
|
|
133
|
+
* Add `cve` command to query the CVE lookup API
|
|
134
|
+
|
|
135
|
+
* CLI:
|
|
136
|
+
|
|
137
|
+
* Add `cve` command to display result from CVE lookup API
|
|
138
|
+
|
|
139
|
+
* Dependencies:
|
|
140
|
+
|
|
141
|
+
* Updated cachetools to version 5.4.0
|
|
142
|
+
|
|
127
143
|
Version `2.2.0`_
|
|
128
144
|
================
|
|
129
145
|
**Date**: June 11, 2024
|
|
@@ -534,4 +550,5 @@ Version `0.2.0`_
|
|
|
534
550
|
.. _`2.0.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v1.3.0...2.0.0
|
|
535
551
|
.. _`2.0.1`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.0.0...2.0.1
|
|
536
552
|
.. _`2.1.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.0.1...2.1.0
|
|
537
|
-
.. _`2.2.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.1.0...
|
|
553
|
+
.. _`2.2.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.1.0...2.2.0
|
|
554
|
+
.. _`2.3.0`: https://github.com/GreyNoise-Intelligence/pygreynoise/compare/v2.2.0...HEAD
|
|
@@ -24,6 +24,7 @@ src/greynoise/cli/helper.py
|
|
|
24
24
|
src/greynoise/cli/parameter.py
|
|
25
25
|
src/greynoise/cli/subcommand.py
|
|
26
26
|
src/greynoise/cli/templates/analyze.txt.j2
|
|
27
|
+
src/greynoise/cli/templates/cvedetails.txt.j2
|
|
27
28
|
src/greynoise/cli/templates/gnql_query.txt.j2
|
|
28
29
|
src/greynoise/cli/templates/gnql_stats.txt.j2
|
|
29
30
|
src/greynoise/cli/templates/interesting.txt.j2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|