Skip to content

Commit

Permalink
Version 1 Release!
Browse files Browse the repository at this point in the history
Added: Notoriety metric
Added: Descriptions, documentation, and other info to README.md
Added: examples.py
Fixed: Scoring algorithm
Fixed: More consistent method naming
Fixed: Better data validation at all levels
  • Loading branch information
Heretyc committed Jul 23, 2021
1 parent 825e7e9 commit 5ae28ad
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 41 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
# before PyInstaller builds the exe, so as to inject date/other infos into db.
*.manifest
*.spec

Expand Down Expand Up @@ -85,7 +85,7 @@ ipython_config.py
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# According to pypa/pipenv#598, db is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
Expand Down
97 changes: 94 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,107 @@
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
> OSINT composite vulnerability database.
Inntinn - Scotts Gaelic for "Intelligence"
_Inntinn - Scotts Gaelic for "Intelligence"_

## Installation
**Inntinn has one primary objective: simplify the process of communicating risk to stakeholders and measuring risk over time in a concise manner.**

OS X, Linux & Windows:
Acknowledging that threat-actors perform reconnaissance and go for “low hanging fruit”, Inntinn aims to model this behavior in order to generate a single number that can be used as a consistent benchmark even among dissimilar organizations.


Scores are based on metrics that more threat-actors are using to date: target company valuation, vulnerabilities they are actually aware of, and vulnerabilities that are most likely to work.

**To put it another way**: Gross Company Assets, Vulnerability Notoriety, and the damage or ease of use on a vulnerability.

## Inntinn Scores
There are 2 forms of scoring, Per Device and Per Organization.

- The **Per Device** score is calculated using a list of all CVE’s (vulnerabilities) that a device is vulnerable to, and the company which owns it. (If the company is not publicly traded, the lowest score metric is used to communicate that the organization is not a primary target of attackers globally)
- The **Per Organization** score only needs the summation of all organizational Inntinn **Per Device** scores. This can be used as a “Per Department”, “Per Datacenter” or any other organizational unit including the company as a whole.


### Per Device
The “Per Device” score represents the cumulative risk posed by a single device within an organization.

The guiding principles behind this score are:

1) Rather than using a complex metric, we boil-down the score into a simple 1-100 percentage. (_100% = highest risk_)

2) Risk is updated as threats evolve over time. Inntinn pulls directly from the NIST National Vulnerability Database, updating as CVE’s change in scope over time. As a vulnerability grows in notoriety, so does the score.

3) As new PoCs (Proof of Concept code) are added to the ExploitDB, scores are dynamically adjusted to account for greater likelihood of exploitation.

4) Finally, scoring is based on public financial fillings with the Securities and Exchange Commission (SEC). Base scores for companies curve sharply upward as we look at the most profitable companies.


[![Score Distribution](https://github.com/BlackburnHax/inntinn/raw/main/docs/score-dist.png)]

### Per Organization
- A cumulative risk score is calculated by simply adding each Inntinn device score up. Just that simple.

### One final note on scores
**Device** and **Org** scores will change over time as threats evolve and new information becomes available. While the underlying data sets outlined in the "Per Device" section above will not necessarily change, scores will fluctuate between database updates nonetheless.

Database updates are performed at an interval of your choosing, however we recommend at least once weekly.

## Installation and Usage _(Technical)_

1) OS X, Linux & Windows:

```sh
pip install inntinn
```
2) Ensure that a working MongoDB database is accessible and utilize the [Example configuration file](https://github.com/BlackburnHax/inntinn/blob/main/example_config.json) to enable read/write on the given MongoDB database.

Example Config:
```json
{"inntinn":{"instance":"thedb",
"user": "audrey",
"pass": "asdfghjjkl12345",
"uri": "mongodb://4.2.2.2:27017/"}}
```
3) Import Inntinn within your Python code, instance the database, provide it the config file and perform an update to populate the database:
```python
import inntinn
db = inntinn.Database("/path/to/your/config.json")

db.update()
```
4) **a)** Lookup the SEC CIK for your chosen company:
```python
import inntinn
db = inntinn.Database("/path/to/your/config.json")

companies = db.cik_lookup("apple")
for key, value in companies.items():
print(f"CIK: {key} = {value}")
```

**b)** Or if you are feeling lucky, just use the company name:
```python
import inntinn
db = inntinn.Database("/path/to/your/config.json")

device_score = db.score_device_list_fuzzy(["CVE-2019-0708", "CVE-1999-0019", "CVE-2018-0840", "CVE-2021-22721", "CVE-2021-3619"], "Apple Inc")
```

5) If you didn't opt for option "b" above, you may now perform scoring:
```python
import inntinn
db = inntinn.Database("/path/to/your/config.json")

device_score = db.score_device_list(["CVE-2019-0708", "CVE-1999-0019", "CVE-2018-0840", "CVE-2021-22721", "CVE-2021-3619"], 320193)
```

6) After performing scoring on a **Per Device** level for each device in the org, you may calculate the **Per Org** score:
```python
import inntinn
db = inntinn.Database("/path/to/your/config.json")

device_a_score = db.score_device_list(["CVE-2019-0708", "CVE-1999-0019", "CVE-2018-0840", "CVE-2021-22721", "CVE-2021-3619"], 320193)
# any number of device calculations here
device_z_score = db.score_device_list(["CVE-2021-2336", "CVE-2021-2390", "CVE-2018-0840", "CVE-2019-0708"], 320193)
org_score = db.score_org([device_a_score, device_z_score])
```
## Meta

Brandon Blackburn – [PGP Encrypted Chat @ Keybase](https://keybase.io/blackburnhax/chat)
Expand Down
Binary file added docs/score-dist.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import inntinn
import pathlib # Needed only for this example, we use db to obtain the configuration file location

db = inntinn.Database(
pathlib.Path.cwd() / "config.json", tls=False
) # tls=False only used for testing... we hope you are not running a production MongoDB without TLS!

db.update() # This should be performed at least once per week to maintain the most current data, but can be done as much as daily

blue_keep = db.cve_lookup("CVE-2019-0708")
print(blue_keep)
apples = db.cik_lookup("apple") # When the CIK is unknown for a company
for key, value in apples.items():
print(f"CIK: {key} = {value}")

apple = db.score_device("CVE-2019-0708", 320193)
noname = db.score_device_fuzzy("cve-2019-0708", "some non-existent company")
a = db.score_device_fuzzy("CVE-2019-0708", "American Airlines")
b = db.score_device("CVE-2019-0708", 4515)
c = db.score_device("CVE-1999-0019", 1810019)
d = db.score_device("CVE-2018-0880", 6176)
e = db.score_device("CVE-2019-0708", "4515")
f = db.score_device_list(
["CVE-2019-0708", "CVE-1999-0019", "CVE-2018-0880", "CVE-2021-22721"], 4515
) # The preferred method to score devices, this function creates an intelligent score based on standard deviation
# PLEASE NOTE: This function is not merely adding up individual vuln scores, so be sure to use db when evaluating a devices total risk
g = db.score_device_list_fuzzy(
[
"CVE-2019-0708",
"CVE-1999-0019",
"CVE-2018-0840",
"CVE-2021-22721",
"CVE-2021-3619",
],
"Ampco Pittsburgh",
) # This is the fallback method for score_device_list() when the company CIK is unknown or unavailable
org_a_metrics = [
a[
0
], # Slicing is needed here as "fuzzy" matches return tuples in the form (score,confidence)
b,
e,
f, # Ideally, every score in here should be calculated using score_device_list() or its _fuzzy() equivalent
# but, we will assume a,b,e just have a single vulnerability
]

org_b_metrics = [d, g[0]]

org_a_score = db.score_org(org_a_metrics)
org_b_score = db.score_org(org_b_metrics)
print(f"Org A score = {org_a_score} , Org B score = {org_b_score}")
Loading

0 comments on commit 5ae28ad

Please sign in to comment.