LoginSignup
3
3

NVD公開のREST APIを用いて脆弱性情報を取得する 2024

Posted at

背景

今の世の中、情報セキュリティ対策が重要になっております。そんな状況もあり、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 がまだまだあるので、今後も情報を共有していきたいと思います。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3