diff --git a/.gitignore b/.gitignore index 8478f7a..dde3895 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ .DS_Store *.pyc -*.sqlite diff --git a/README.md b/README.md index 15df2d5..c3defe0 100644 --- a/README.md +++ b/README.md @@ -3,57 +3,226 @@ [![PyPi Version](http://img.shields.io/pypi/v/ares.svg)](https://pypi.python.org/pypi/ares/) **ares** is an APACHE licensed library written in Python providing an easy to use wrapper around https://cve.circl.lu. -This library has been tested with Python 2.7.x and Python 3.6.x. +This library has been tested with Python 2.7.x and Python 3.6+. ## Installation: From source use - $ python setup.py install +```bash +$ python setup.py install +``` or install from PyPi - $ pip install ares +```bash +$ pip install ares +``` ## Documentation: -- **`GET /api/browse/`** -- **`GET /api/browse/vendor`** +#### **`GET /api/browse`** +#### **`GET /api/browse/`** + +##### Description + +Returns a list of vendors or products of a specific vendor. +This API call can be used in two ways; With or without the vendor. +When the link is called without a vendor, it will return a list of possible vendors. +When the link is called with a vendor, it enumerates the products for said vendor. + +| Argument | Description | Example | +| :-------------------| :------------------ | :------------------- | +| vendor | Vendor name | `microsoft` | ```python >>> from ares import CVESearch >>> cve = CVESearch() ->>> cve.browse() +>>> cve.browse('microsoft') +``` + +
+ +#### **`GET /api/capec/ `** + +##### Description + +Outputs a list of CAPEC related to a CWE. +CAPEC (Common Attack Pattern Enumeration and Classification) are a list of attack types commonly used by attackers. + +| Argument | Description | Example | +| :-------------------| :------------------ | :------------------- | +| cweid | CWE ID | `200` | + + +```python +>>> cve.capec('200') ``` -- **`GET /api/search/vendor/product`** +
+ +#### **`GET /api/cpe2.2/ `** + +##### Description + +**DISABLED ON cve.circl.lu** + +Converts a CPE code to the CPE2.2 standard, stripped of appendices. +CPE2.2 is the old standard, and is a lot less uniform than the CPE2.3 standard. + +| Argument | Description | Example | +| :-------------------| :---------------------------------- | :--------------------------------------------------------------------- | +| cpe | CPE code in cpe2.2 or cpe2.3 format | `cpe:2.3:o:microsoft:windows_vista:6.0:sp1:-:-:home_premium:-:-:x64:-` | ```python ->>> cve.search('microsoft/office') +>>> cve.cpe22('cpe:2.3:a:microsoft:office:2011:-:mac') ``` -- **`GET /api/cveid/cveid`** +
+ +#### **`GET /api/cpe2.3/ `** + +##### Description + +**DISABLED ON cve.circl.lu** + +Converts a CPE code to the CPE2.3 standard, stripped of appendices. +CPE2.3 is the newer standard, and is a lot more uniform and easier to read than the CPE2.2 standard. + +| Argument | Description | Example | +| :-------------------| :---------------------------------- | :--------------------------------------------------------------- | +| cpe | CPE code in cpe2.2 or cpe2.3 format | `cpe:/o:microsoft:windows_vista:6.0:sp1:~-~home_premium~-~x64~-` | + +```python +>>> cve.cpe23('cpe:/a:microsoft:office:2011::mac') +``` + +
+ +#### **`GET /api/cve/`** + +##### Description + +Outputs all available information for the specified CVE (Common Vulnerability and Exposure), in JSON format. +This information includes basic CVE information like CVSS (Common Vulnerability Scoring System), related CPE (Common Product Enumeration), +CWE (Common Weakness Enumeration), ... as well as additional information (RedHat Advisories etc). + +| Argument | Description | Example | +| :-------------------| :-------------------- | :----------------------- | +| cveid | CVE number | `CVE-2014-0160` | + +```python +>>> cve.cve('CVE-2014-0160') +``` + +
+ +#### **`GET /api/cvefor/ `** + +##### Description + +**DISABLED ON cve.circl.lu** + +Outputs a list of CVEs related to the product. + +| Argument | Description | Example | +| :-------------------| :---------------------------------- | :--------------------------------------------------------------- | +| cpe | CPE code in cpe2.2 or cpe2.3 format | `cpe:/o:microsoft:windows_vista:6.0:sp1:~-~home_premium~-~x64~-` | + ```python ->>> cve.id('CVE-2014-0160') +>>> cve.cvefor('cpe:/o:microsoft:windows_vista:6.0:sp1:~-~home_premium~-~x64~-') ``` -- **`GET /api/last`** +
+ +#### **`GET /api/cwe `** + +##### Description + +Outputs a list of all CWEs (Common Weakness Enumeration). ```python ->>> cve.last() +>>> cve.cwe() ``` -- **`GET /api/dbInfo`** +
+ +#### **`GET /api/dbInfo`** + +##### Description + +Returns the stats of the database. When the user authenticates, more information is returned. This information includes: + + Amount of whitelist and blacklist records + Some server settings like the database name + Some database information like disk usage + +Unauthenticated queries return only collection information. + +**Note: as of April 2020, authentication is disabled on cve.circl.lu.** ```python >>> cve.dbinfo() ``` +
+ +#### **`GET /api/last`** +#### **`GET /api/last/`** + +##### Description + +Outputs the last `n` amount of vulnerabilities. If the limit is not specified, the default of 30 is used. + +| Argument | Description | Example | +| :-------------------| :---------------------------------- | :--------------------- | +| limit | The amount of CVEs to display | `10` | + +```python +>>> cve.last('10') +``` + +
+ +#### **`GET /api/search/link//`** + +##### Description + +Returns all CVEs that are linked by a given key/value pair. + +| Argument | Description | Example | +| :-------------------| :---------------------------------- | :-------------------------- | +| key | The key to link CVEs on | `msbulletin.bulletin_id` | +| value | The value for the given key | `MS16-098` | + +```python +>>> cve.link('msbulletin.bulletin_id/MS16-098') +``` + +
+ +#### **`GET /api/search//`** + +##### Description + +**DISABLED ON cve.circl.lu** + +When vendor and product are specified, this API call returns a list of CVEs related to the product. The output of the browse call can be used for this. + +| Argument | Description | Example | +| :-------------------| :---------------------------------- | :-------------------------- | +| vendor | Vendor name | `microsoft` | +| product | Product name | `office` | + +```python +>>> cve.search('microsoft/office') +``` + ## License: ``` -Copyright 2014-2018 Martin Simon +Copyright 2014-2020 Martin Simon Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/ares/__init__.py b/ares/__init__.py index 5a4e757..98da63a 100644 --- a/ares/__init__.py +++ b/ares/__init__.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- __title__ = 'ares' -__version__ = '0.5' +__version__ = '0.6.0' __author__ = 'Martin Simon ' __repo__ = 'https://github.com/barnumbirr/ares' __license__ = 'Apache v2.0 License' diff --git a/ares/core.py b/ares/core.py index 41528f1..d19133f 100644 --- a/ares/core.py +++ b/ares/core.py @@ -3,12 +3,11 @@ import json import requests -from requests.compat import urljoin class CVESearch(object): _session = None - __DEFAULT_BASE_URL = 'https://cve.circl.lu/api/' + __DEFAULT_BASE_URL = "https://cve.circl.lu/api/" __DEFAULT_TIMEOUT = 120 def __init__(self, base_url = __DEFAULT_BASE_URL, request_timeout = __DEFAULT_TIMEOUT): @@ -21,11 +20,16 @@ def session(self): self._session = requests.Session() self._session.headers.update({'Content-Type': 'application/json'}) self._session.headers.update({'User-agent': 'ares - python wrapper \ - around cve.circl.lu (github.com/mrsmn/ares)'}) + around cve.circl.lu (github.com/barnumbirr/ares)'}) return self._session def __request(self, endpoint, query): - response_object = self.session.get(requests.compat.urljoin(self.base_url + endpoint, query), + # There is probably a more elegant way to do this ¯\_(ツ)_/¯ + if query: + response_object = self.session.get(requests.compat.urljoin(self.base_url, endpoint + query), + timeout = self.request_timeout) + else: + response_object = self.session.get(requests.compat.urljoin(self.base_url, endpoint), timeout = self.request_timeout) try: @@ -36,35 +40,47 @@ def __request(self, endpoint, query): return response def browse(self, param=None): - """ browse() returns a dict containing all the vendors - browse(vendor) returns a dict containing all the products - associated to a vendor - """ response = self.__request('browse/', query=param) return response - def search(self, param): - """ search() returns a dict containing all the vulnerabilities per - vendor and a specific product - """ - response = self.__request('search/', query=param) + def capec(self, param): + response = self.__request('capec/', query=param) return response - def id(self, param): - """ id() returns a dict containing a specific CVE ID """ + # def cpe22(self, param): + # response = self.__request('cpe2.2/', query=param) + # return response + + + # def cpe23(self, param): + # response = self.__request('cpe2.3/', query=param) + # return response + + def cve(self, param): response = self.__request('cve/', query=param) return response - def last(self): - """ last() returns a dict containing the last 30 CVEs including CAPEC, - CWE and CPE expansions - """ - response = self.__request('last/', query=None) + # def cvefor(self, param): + # response = self.__request('cvefor/', query=param) + # return response + + def cwe(self): + """ Outputs a list of all CWEs (Common Weakness Enumeration). """ + response = self.__request('cwe', query=None) return response def dbinfo(self): - """ dbinfo() returns a dict containing more information about - the current databases in use and when it was updated - """ response = self.__request('dbInfo', query=None) return response + + def last(self, param): + response = self.__request('last/', query=param) + return response + + def link(self, param): + response = self.__request('link/', query=param) + return response + + # def search(self, param): + # response = self.__request('search/', query=param) + # return response diff --git a/requirements.txt b/requirements.txt index c20f36f..b450057 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1 @@ -requests==2.20.0 +requests==2.23.0 diff --git a/setup.py b/setup.py index 5cc53b3..4d761eb 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ setup( name='ares', packages = ['ares'], - version = '0.5', + version = '0.6.0', description = 'Python wrapper around https://cve.circl.lu.', author = 'Martin Simon', author_email = 'me@martinsimon.me', @@ -29,9 +29,6 @@ 'Buy me a coffee': 'https://github.com/barnumbirr/ares#buy-me-a-coffee', }, license = 'Apache v2.0 License', - install_requires=[ - 'requests>=2.18.4' - ], keywords=['CVE', 'cybersecurity', 'vulnerability', 'circl.lu'], classifiers=[ 'License :: OSI Approved :: Apache Software License', @@ -39,7 +36,7 @@ 'Intended Audience :: Developers', 'Programming Language :: Python', 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Topic :: Software Development :: Libraries :: Python Modules', ], long_description = long_description,