背景
今の世の中、情報セキュリティ対策が重要になっております。そんな状況もあり、NIST管理の脆弱性情報データベースが公開されております。その情報を有効に活用すべく2021年1月9日に @riikunn_ryo (Ryo) さんが「NVD公開のREST APIを用いて脆弱性情報を取得する」を投稿してしてくださいました。
すごく良い情報だったのですが、現在 REST API の仕様、レスポンスとなるJSONの仕様などが変更されておりせっかくRyoさんに公開していただいたPyhonスクリプトを使うことができません。
そのため、Ryoさんのスクリプトをオマージュし最新化しました。
実行環境
- Ubuntu22.04.4 LTS ( Windows Subsystem for Linux (WSL) )
- Python 3.10.12
CPEの条件を満たすCVEの情報を取得
本Pythonコードのコンセプトや構成等はRyoさんの記事を参照してください。すごく参考になります。
以下に、あるCPEに合致するCVE情報を取得し、出力するPyhonコードを掲載します。
get_software_vuln2.py
#!/usr/bin/env python
import requests
import json
import argparse
import textwrap
def main():
# コマンドライン引数Parse
parser = argparse.ArgumentParser()
parser.add_argument('cpe_name', help='CPE Name')
args = parser.parse_args()
# CPEに対応した脆弱性情報をNVDからJSON形式で取得
cpe_name = args.cpe_name
api = 'https://services.nvd.nist.gov/rest/json/cves/2.0?cpeName={cpe_name}'
uri = api.format(cpe_name=cpe_name)
response = requests.get(uri)
json_data = json.loads(response.text)
vulnerabilities = json_data['vulnerabilities']
for vuln in vulnerabilities:
cve_id = vuln['cve']['id'] # CVE-IDを取得
current_description = vuln['cve']['descriptions'][0]['value'] # Current Descriptionを取得
cwe_id = vuln['cve']['weaknesses'][0]['description'][0]['value'] # CWE-IDを取得
# CVSS v3の情報があればBaseScoreとVectorStringを取得
if 'cvssMetricV30' in vuln['cve']['metrics']:
cvssv3_base_score = vuln['cve']['metrics']['cvssMetricV30'][0]['cvssData']['baseScore']
cvssv3_vector_string = vuln['cve']['metrics']['cvssMetricV30'][0]['cvssData']['vectorString']
else:
cvssv3_base_score = None
cvssv3_vector_string = None
# CVSS v2のBaseScoreとVectorStringを取得
cvssv2_base_score = vuln['cve']['metrics']['cvssMetricV2'][0]['cvssData']['baseScore']
cvssv2_vector_string = vuln['cve']['metrics']['cvssMetricV2'][0]['cvssData']['vectorString']
# 出力
print('---------')
text = textwrap.dedent('''
CVE-ID:{cve_id}
CWE-ID:{cwe_id}
CVSSv3 BaseScore:{cvssv3_base_score} CVSSv3 VectorString:{cvssv3_vector_string}
CVSSv2 BaseScore:{cvssv2_base_score} CVSSv2 VectorString: {cvssv2_vector_string}
Current Description:
{current_description}
''')
print(text.format(cve_id=cve_id, cwe_id=cwe_id, cvssv3_base_score=cvssv3_base_score, cvssv3_vector_string=cvssv3_vector_string,
cvssv2_base_score=cvssv2_base_score, cvssv2_vector_string=cvssv2_vector_string, current_description=current_description))
print('---------')
main()
使い方は以下です。
python get_software_vulns2.py <CPE>
例1:openssl 1.1.1cの脆弱性情報
python get_software_vulns2.py cpe:2.3:a:openssl:openssl:1.1.1c:*:*:*:*:*:*:*
例2:windows_10 バージョン1607の脆弱性情報
python3 ./get_software_vuln.py cpe:2.3:o:microsoft:windows_10:1607:*:*:*:*:*:*:*
まとめ
今回は@riikunn_ryo (Ryo) さんの考え方、Pythonコードをオマージュさせていただきました。さらなる脆弱性情報を取得できる REST API がまだまだあるので、今後も情報を共有していきたいと思います。