Skip to content

Commit

Permalink
Add example of how to generate spreadsheets of EPSS scores
Browse files Browse the repository at this point in the history
  • Loading branch information
whitfieldsdad committed Feb 5, 2024
1 parent ad58637 commit 85872df
Show file tree
Hide file tree
Showing 6 changed files with 445 additions and 10 deletions.
80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,83 @@ poetry run epss scores -a 2024-01-01 --download
```

<sub>1. Unchanged scores will still be saved to disk regardless of the value of the `--drop-unchanged/--no-drop-unchanged` flags.</sub>

### Python

Additional examples are available in the [examples](examples) folder.

#### Load unique EPSS scores into Polars

To load EPSS scores into Polars:

```python
from epss.client import PolarsClient

import polars as pl
import tempfile
import os

cfg = pl.Config()
cfg.set_tbl_rows(-1) # Unlimited output length

WORKDIR = os.path.join(tempfile.gettempdir(), 'epss')

client = PolarsClient(
include_v1_scores=False,
include_v2_scores=False,
include_v3_scores=True,
)
df = client.get_scores(workdir=WORKDIR, drop_unchanged_scores=True)
print(df)
```

#### Generating a spreadsheet of changed EPSS scores

To generate a [spreadsheet](examples/data/epss.xlsx) containing the EPSS scores of all [CVEs](https://github.com/mandiant/red_team_tool_countermeasures/blob/master/CVEs_red_team_tools.md) known to be exploitable using [FireEye's leaked red team tools](https://www.mandiant.com/resources/blog/unauthorized-access-of-fireeye-red-team-tools):

```python
from xlsxwriter import Workbook
from epss.client import PolarsClient, Query

import tempfile
import os

WORKDIR = os.path.join(tempfile.gettempdir(), 'epss')

client = PolarsClient(
include_v1_scores=False,
include_v2_scores=False,
include_v3_scores=True,
)
query = Query(
cve_ids=[
'CVE-2019-11510',
'CVE-2020-1472',
'CVE-2018-13379',
'CVE-2018-15961',
'CVE-2019-0604',
'CVE-2019-0708',
'CVE-2019-11580',
'CVE-2019-19781',
'CVE-2020-10189',
'CVE-2014-1812',
'CVE-2019-3398',
'CVE-2020-0688',
'CVE-2016-0167',
'CVE-2017-11774',
'CVE-2018-8581',
'CVE-2019-8394',
]
)
df = client.get_scores(
workdir=WORKDIR,
query=query,
drop_unchanged_scores=True
)

with Workbook('epss.xlsx') as wb:
df.write_excel(
workbook=wb,
worksheet='Mandiant red team tools'
)
```
6 changes: 5 additions & 1 deletion epss/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def get_scores_by_date(
)
if not os.path.exists(path):
self.download_scores_by_date(workdir=workdir, date=date)
assert os.path.exists(path), "Scores unexpectedly not downloaded"
assert os.path.exists(path), f"Scores unexpectedly not downloaded for {date.isoformat()}"

df = read_dataframe(path)
if query:
Expand All @@ -260,6 +260,9 @@ def get_scores_by_date(
if 'cve' not in df.columns:
raise ValueError(f'The dataframe for {date.isoformat()} does not contain a `cve` column (columns: {df.columns})')

# Use the following column order: date, cve, epss, percentile
df = df.select(['date', 'cve', 'epss', 'percentile'])

df = df.sort(by=['cve'], descending=True)
df = df.sort(by=['date'], descending=False)
return df
Expand Down Expand Up @@ -305,6 +308,7 @@ def get_file_path(workdir: str, file_format: str, key: Union[datetime.date, str]
- If partitioning by `date`: `/tmp/epss/2024-01-01.parquet`
- If partitioning by `cve`: `/tmp/epss/CVE-2024-01-01.parquet`
"""
workdir = util.realpath(workdir)
if isinstance(key, datetime.date):
key = key.isoformat()
return os.path.join(workdir, f'{key}.{file_format}')
Expand Down
Binary file added examples/data/epss.xlsx
Binary file not shown.
47 changes: 47 additions & 0 deletions examples/get-excel-workbook-of-changed-epss-scores.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from xlsxwriter import Workbook
from epss.client import PolarsClient, Query

import logging
import tempfile
import os

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(name)s %(message)s')

WORKDIR = os.path.join(tempfile.gettempdir(), 'epss')

client = PolarsClient(
include_v1_scores=False,
include_v2_scores=False,
include_v3_scores=True,
)
query = Query(
cve_ids=[
'CVE-2019-11510', # pre-auth arbitrary file reading from Pulse Secure SSL VPNs - CVSS 10.0
'CVE-2020-1472', # Microsoft Active Directory escalation of privileges - CVSS 10.0
'CVE-2018-13379', # pre-auth arbitrary file reading from Fortinet Fortigate SSL VPN - CVSS 9.8
'CVE-2018-15961', # RCE via Adobe ColdFusion (arbitrary file upload that can be used to upload a JSP web shell) - CVSS 9.8
'CVE-2019-0604', # RCE for Microsoft Sharepoint - CVSS 9.8
'CVE-2019-0708', # RCE of Windows Remote Desktop Services (RDS) - CVSS 9.8
'CVE-2019-11580', # Atlassian Crowd Remote Code Execution - CVSS 9.8
'CVE-2019-19781', # RCE of Citrix Application Delivery Controller and Citrix Gateway - CVSS 9.8
'CVE-2020-10189', # RCE for ZoHo ManageEngine Desktop Central - CVSS 9.8
'CVE-2014-1812', # Windows Local Privilege Escalation - CVSS 9.0
'CVE-2019-3398', # Confluence Authenticated Remote Code Execution - CVSS 8.8
'CVE-2020-0688', # Remote Command Execution in Microsoft Exchange - CVSS 8.8
'CVE-2016-0167', # local privilege escalation on older versions of Microsoft Windows - CVSS 7.8
'CVE-2017-11774', # RCE in Microsoft Outlook via crafted document execution (phishing) - CVSS 7.8
'CVE-2018-8581', # Microsoft Exchange Server escalation of privileges - CVSS 7.4
'CVE-2019-8394', # arbitrary pre-auth file upload to ZoHo ManageEngine ServiceDesk Plus - CVSS 6.5
]
)
df = client.get_scores(
workdir=WORKDIR,
query=query,
drop_unchanged_scores=True
)

with Workbook('epss.xlsx') as wb:
df.write_excel(
workbook=wb,
worksheet='Mandiant red team tools'
)
Loading

0 comments on commit 85872df

Please sign in to comment.