Skip to content

Instantly share code, notes, and snippets.

@infosecn1nja
Last active January 9, 2025 12:06
Show Gist options
  • Save infosecn1nja/a58e5bad56dbd6b488c601bcf5a09786 to your computer and use it in GitHub Desktop.
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.
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