Last active
January 9, 2025 12:06
-
-
Save infosecn1nja/a58e5bad56dbd6b488c601bcf5a09786 to your computer and use it in GitHub Desktop.
The cisa_kev_poc_analysis.py script is designed to facilitate the analysis of Common Vulnerabilities and Exposures (CVEs) listed in the CISA Known Exploited Vulnerabilities (KEV) Catalog by correlating them with Proof-of-Concept (PoC) data from the PoC-in-GitHub repository.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import json | |
import zipfile | |
import urllib.request | |
import argparse | |
from collections import Counter | |
from datetime import datetime | |
# Argument parser for dynamic filtering and settings | |
parser = argparse.ArgumentParser(description="Filter and analyze CVEs based on CISA KEV and GitHub PoC data.") | |
parser.add_argument("-y", "--year", type=str, default="all", help="Filter CVEs by year (e.g., 2024 or 'all' for all years)") | |
parser.add_argument("-o", "--output", type=str, default="cve_match_summary.json", help="Output file name for the summary") | |
args = parser.parse_args() | |
filter_year = args.year | |
# Load CISA KEV data using urllib.request | |
cisa_kev_url = "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json" | |
cisa_kev_file = "cisa_kev.json" | |
print("[*] Downloading CISA KEV data...") | |
urllib.request.urlretrieve(cisa_kev_url, cisa_kev_file) | |
print("[*] Download completed.") | |
with open(cisa_kev_file, "r") as file: | |
kev_data = json.load(file) | |
# Check if PoC-in-GitHub-master folder exists, if not download and unzip | |
poc_dir = "PoC-in-GitHub-master" | |
if not os.path.exists(poc_dir): | |
print("[*] PoC-in-GitHub-master folder not found. Downloading...") | |
poc_zip_url = "https://github.com/nomi-sec/PoC-in-GitHub/archive/refs/heads/master.zip" | |
zip_file_name = "PoC-in-GitHub-master.zip" | |
# Download the zip file | |
urllib.request.urlretrieve(poc_zip_url, zip_file_name) | |
# Unzip the file | |
with zipfile.ZipFile(zip_file_name, "r") as zip_ref: | |
zip_ref.extractall() | |
# Rename the extracted folder to match expected directory name | |
extracted_folder = "PoC-in-GitHub-master-master" | |
if os.path.exists(extracted_folder): | |
os.rename(extracted_folder, poc_dir) | |
# Clean up zip file | |
os.remove(zip_file_name) | |
print("[*] Download and extraction completed.") | |
# Extract CVE IDs from KEV catalog filtered by dateAdded year | |
kev_cves = set( | |
vul["cveID"] | |
for vul in kev_data["vulnerabilities"] | |
if filter_year == "all" or datetime.strptime(vul["dateAdded"], "%Y-%m-%d").year == int(filter_year) | |
) | |
# Collect PoC CVEs from GitHub directory | |
poc_cves = set() | |
for root, _, files in os.walk(poc_dir): | |
for file_name in files: | |
if file_name.endswith(".json") and "CVE" in file_name: | |
poc_cves.add(file_name.replace(".json", "")) | |
# Calculate matches and non-matches | |
matched_cves = kev_cves.intersection(poc_cves) | |
unmatched_cves = kev_cves - poc_cves | |
# Identify ransomware campaign usage and CWEs | |
ransomware_known_in_poc = [] | |
ransomware_known_not_in_poc = [] | |
cwes = [] | |
for vul in kev_data["vulnerabilities"]: | |
if vul["cveID"] in kev_cves: | |
cwes.extend(vul.get("cwes", [])) | |
if vul["cveID"] in matched_cves: | |
if vul.get("knownRansomwareCampaignUse") == "Known": | |
ransomware_known_in_poc.append(vul["cveID"]) | |
elif vul.get("knownRansomwareCampaignUse") == "Known": | |
ransomware_known_not_in_poc.append(vul["cveID"]) | |
# Count top CWEs from total CVEs in KEV | |
top_cwes = Counter(cwes).most_common(5) | |
# Create summary | |
summary = { | |
"filterYear": filter_year, | |
"totalCVEinKEV": len(kev_cves), | |
"totalPoCFound": len(matched_cves), | |
"totalPoCNotFound": len(unmatched_cves), | |
"ransomwareKnownInPoC": len(ransomware_known_in_poc), | |
"ransomwareKnownNotInPoC": len(ransomware_known_not_in_poc), | |
"listPoCMatches": list(matched_cves), | |
"listRansomwareKnownInPoC": ransomware_known_in_poc, | |
"listRansomwareKnownNotInPoC": ransomware_known_not_in_poc, | |
"topCWEs": top_cwes, | |
} | |
# Output results to a JSON file | |
with open(args.output, "w") as output_file: | |
json.dump(summary, output_file, indent=4) | |
print(f"[*] Summary for CVEs added in {filter_year} saved to {args.output}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment