Package: inntinn
inntinnOSINT composite vulnerability database.Inntinn - Scotts Gaelic for "Intelligence"Inntinn has one primary objective: simplify the process of communicating risk to stakeholders and measuring risk over time in a concise manner.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 ScoresThere are 2 forms of scoring, Per Device and Per Organization.ThePer Devicescore 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)ThePer Organizationscore only needs the summation of all organizational InntinnPer Devicescores. This can be used as a “Per Department”, “Per Datacenter” or any other organizational unit including the company as a whole.Per DeviceThe “Per Device” score represents the cumulative risk posed by a single device within an organization.The guiding principles behind this score are:Rather than using a complex metric, we boil-down the score into a simple 1-100 percentage. (100% = highest risk)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.As new PoCs (Proof of Concept code) are added to the ExploitDB, scores are dynamically adjusted to account for greater likelihood of exploitation.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.Per OrganizationA cumulative risk score is calculated by simply adding each Inntinn device score up. Just that simple.One final note on scoresDeviceandOrgscores 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)OS X, Linux & Windows:pipinstallinntinnEnsure that a working MongoDB database is accessible and utilize theExample configuration fileto enable read/write on the given MongoDB database.Example Config:{"inntinn":{"instance":"thedb","user":"audrey","pass":"asdfghjjkl12345","uri":"mongodb://4.2.2.2:27017/"}}Import Inntinn within your Python code, instance the database, provide it the config file and perform an update to populate the database:importinntinndb=inntinn.Database("/path/to/your/config.json")db.update()a)Lookup the SEC CIK for your chosen company:importinntinndb=inntinn.Database("/path/to/your/config.json")companies=db.cik_lookup("apple")forkey,valueincompanies.items():print(f"CIK:{key}={value}")b)Or if you are feeling lucky, just use the company name:importinntinndb=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")If you didn't opt for option "b" above, you may now perform scoring:importinntinndb=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)After performing scoring on aPer Devicelevel for each device in the org, you may calculate thePer Orgscore:importinntinndb=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 heredevice_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])APIOptionally, Inntinn has an accompanyingSanicbased API which does not require a proxy like most Python frameworks.
To view the documentation for the API visitbhax.net/apiAdditionally, once the API is running, you can visit:https ://your_host/swaggerfor a dynamically updated Swagger spec page that is accessible even without internet access.The API is functional and fast, but wedo notrecommend running it on Windows as multi-threading is not available at this time. Running on Windows will result in dramatically slower response processing.Getting startedTheAPI itself is located under inntinn/api.pyand must be launched with appropriate permissions to open sockets on Port 80 & Port 443.Use theexample_config.jsonand be pay close attention to the "inntinn_api" section.
Generate your certs and set the config to point to the files.Important Note:Currently, the config.json must be called "config.json" and placed in the same directory as the api.py application.(This behavior is likely to change in a future update allowing one to pass the config as a command line argument at launch)AuthenticationThe database is read-only in all cases but one, database updates.
For this reason, all endpoints do not require authentication of any kind...except the /server endpoint.Authentication is done usingJWTs (JSON Web Tokens)which areRFC 7519compliant.ExampleFor the admin user defined in the config.json, the default password is "change_me" the following example shows how to authenticate with JWTs to update the server:importrequestsserver_uri="https://127.0.0.1"# Obtain a JWTpayload={"username":"admin","password":"change_me"}auth_response=requests.post(f"{server_uri}/auth",json=payload,verify=False)auth_response_json=auth_response.json()# Now use the JWTresponse=requests.post(f"{server_uri}/server",json=payload,headers={"Authorization":f"Bearer{auth_response_json['access_token']}"},verify=False,)MetaBrandon Blackburn –PGP Encrypted Chat @ KeybaseDistributed under the Apache 2.0 license. SeeLICENSEfor more information.TL;DR:For a human-readable & fast explanation of the Apache 2.0 license visit:http://www.tldrlegal.com/l/apache2https://github.com/BlackburnHax/inntinn