Created
September 23, 2023 19:19
-
-
Save ibitebyt3s/8338f4aa49f6fddf59d3c68a8ec94646 to your computer and use it in GitHub Desktop.
Get CVE details right in your terminal. Check the images below
This file contains 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
#! /bin/zsh | |
# cve_info | |
# Docs: https://nvd.nist.gov/developers/start-here | |
# Get your api key here: https://nvd.nist.gov/developers/request-an-api-key | |
# Get CVE details right in your terminal. Sometimes I'm in the need of looking up some CVE information and copy and | |
# pasting each individual CVE into the web browser is too slow. Specially when dealing with nmap output or nuclei recently | |
# added CVE templates. This script aims to speed up the CVE details extraction. It accepts input from stidn, a file or | |
# as arguments. It's still a very informal script that gets the job done and a lot of optimizations can be made. Also | |
# worth saying that some rate limiting checks were made but aren't fully tested. Use at your own risk. | |
# Get an API_KEY to increase your rate limit from 5 to 50 in a rolling time window of 30 seconds | |
api_key="API_KEY" | |
NC='\033[0m' # Text Reset | |
BRED='\033[1;31m' # Red | |
BGREEN='\033[1;32m' # Green | |
BYELLOW='\033[1;33m' # Yellow | |
ON_RED='\033[41m' # Red background | |
BBLUE='\033[1;34m' # Blue bold | |
BGREEN='\033[1;32m' # Green | |
INFO="${BBLUE}[*]${NC}" | |
TASK="${BGREEN}[+]${NC}" | |
CVE_regex="CVE-\d{4}-\d{4,7}" | |
alias xcat="sed 's/\x1b\[[0-9;]*m//g'" # deletes garbage bytes from a text strem such as color codes /r | |
alias tr2uppercase="tr '[:lower:]' '[:upper:]'" | |
alias sed_delete_empty_lines='sed '\''/^\s*$/d'\' | |
alias sed_delete_trailing_whitespace='sed -e '\''s/^[[:space:]]*//g'\'' -e '\''s/[[:space:]]*$//g'\' | |
alias grep_CVEs='grep -P "$CVE_regex"' | |
alias unix_date="date +%s" | |
echo_info() { | |
>&2 echo "${INFO} ${1}${NC}" | |
} | |
echo_task() { | |
>&2 echo "${TASK} ${1}${NC}" | |
} | |
# Get the input from a file | |
if test -n "$1"; then | |
if [ -f $1 ];then | |
if ! [ -s $1 ]; then | |
echo_error "The file ${BYELLOW}$1${NC} is empty" && \ | |
exit 1 | |
else | |
input=$(cat $1 | sed_delete_empty_lines) | |
fi | |
# get the input from command arguemnts | |
elif (( $(sd '\s' '\n' <<< $@ | sed_delete_empty_lines | wc -l) >= 1 )) && grep_CVEs -q <<< $@; then | |
input=$(sd '\s' '\n' <<< $@ | sed_delete_empty_lines ) | |
else | |
echo_error "The input ${BYELLOW}$1${NC} isn't a CVE" && \ | |
exit 1 | |
fi | |
# elif get the infput from stdin | |
elif test ! -t 0; then | |
input=$(cat < /dev/stdin) && \ | |
[ -z $input ] && \ | |
echo_error "Input from ${BYELLOW}stdin${NC} is empty" && \ | |
exit 1 | |
else | |
# input=$(cat .asns.txt | sed_delete_empty_lines | sv) &> /dev/null | |
[[ -z $input ]] && \ | |
echo_error "No ${BYELLOW}input${NC} was provided" && \ | |
exit 1 | |
fi | |
IFS=$'\n' | |
i=1 | |
total=$(wc -l <<< $input| sed_delete_trailing_whitespace ) # delete trailing whitespace for Mac users | |
rate_limit_filename=/tmp/cve_info_rate_limit.tmp | |
saved_time=0 | |
request_counter=0 | |
if [[ $api_key == "API_KEY" ]]; then | |
RATE_LIMIT=4 | |
else | |
RATE_LIMIT=45 | |
fi | |
for cve in $(echo $input); do | |
id=$cve | |
# rate limit functionality of 50 request in a 30 seconds window | |
# https://nvd.nist.gov/developers/start-here | |
# Check the time:counter values stored in a file if found | |
unix_date=$(unix_date) | |
if [ -f $rate_limit_filename ]; then | |
rate_limit_data=$(cat $rate_limit_filename) | |
saved_time=$(cut -d : -f1 <<< $rate_limit_data) | |
request_counter=$(cut -d : -f2 <<< $rate_limit_data) | |
else | |
saved_time=$unix_date | |
fi | |
elapsed_time=$((unix_date-saved_time)) | |
remeaning_time=$((30-elapsed_time)) | |
# Compare the values with the actual time and check if rate limit is not being exceeded | |
# if it is, sleep for the remeaning time | |
if [ -f $rate_limit_filename ] && [[ $request_counter -ge $RATE_LIMIT ]]; then | |
echo_task "sleeping for $remeaning_time seconds..." | |
sleep $remeaning_time | |
fi | |
# continue normal operations when done... | |
# request CVE information | |
if [[ $api_key == "API_KEY" ]]; then | |
json_data=$(curl "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=$id" | xcat | head -n1) | |
else | |
json_data=$(curl -H "apiKey:$api_key" "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=$id" | xcat | head -n1) | |
fi | |
# create or update the rate limit time:counter values | |
# if elapsed_time is less or equal to zero, update the time to current time and counter to 1 | |
# else just update the counter | |
if [[ $remeaning_time -le 0 ]]; then | |
echo "$unix_date:1" > $rate_limit_filename | |
else | |
((request_counter++)) | |
echo "$saved_time:$request_counter" > $rate_limit_filename | |
fi | |
# parse the data depending its CVSS version | |
description=$(jq -r '.vulnerabilities[0].cve.descriptions[0].value' <<< $json_data) | |
webpage="https://nvd.nist.gov/vuln/detail/$id" | |
score=$(jq '.vulnerabilities[0].cve.metrics.cvssMetricV31[0].cvssData.baseScore' <<< $json_data) | |
[[ $score == "null" ]] && \ | |
score=$(jq '.vulnerabilities[0].cve.metrics.cvssMetricV2[0].cvssData.baseScore' <<< $json_data ) | |
severity=$(jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV31[0].cvssData.baseSeverity' <<< $json_data) | |
[[ $severity == "null" ]] && \ | |
severity=$(jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV2[0].baseSeverity' <<< $json_data) | |
# cvss=$(jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV31[0].cvssData.vectorString' <<< $json_data | ) | |
cvss=$(jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV31[0].cvssData.vectorString' <<< $json_data | cut -d ':' -f2-) | |
[[ $cvss == "null" ]] && \ | |
cvss=$(jq -r '.vulnerabilities[0].cve.metrics.cvssMetricV2[0].cvssData.vectorString' <<< $json_data ) | |
creation_date=$(jq -r '.vulnerabilities[0].cve.published' <<< $json_data) | |
last_update_date=$(jq -r '.vulnerabilities[0].cve.lastModified' <<< $json_data) | |
# # network=$( jq '.vulnerabilities[].cve.metrics.cvssMetricV31[0].cvssData.attackVector' ) | |
# Prettify the Score | |
# detect CVSS version | |
# version 3.0 | |
# none 0.0 | |
# low 0.1-3.9 | |
# medium 4.0-6.9 | |
# High 7.0-8.9 | |
# Critical 9.0-10.0 | |
# version 2.0 | |
# low 0.0 - 3.9 | |
# medium 4.0-6.9 | |
# High 7.0-10.0 | |
# if CVSS version 3 | |
# else CVSS version 2 | |
if grep -qE "^3" <<< $cvss; then | |
if grep -qE '(^0\.[1-9]$)|(^1(\.[0-9])?$)|(^2(\.[0-9])?$)|(^3(\.[0-8])?$)'<<< $score; then | |
score="${BGREEN}$score${NC}" | |
elif grep -qE '^([4-6](\.[0-9])?|6\.[0-8])$'<<< $score; then | |
score="${BYELLOW}$score${NC}" | |
elif grep -qE '^(7(\.[0-9])?|8(\.[0-8])?)$'<<< $score; then | |
score="${BRED}$score${NC}" | |
elif grep -qE '^(9(\.0)?|10(\.0)?)$' <<< $score; then | |
score="${ON_RED} $score ${NC}" | |
fi | |
else | |
if grep -qE '^(0(\.[0-9])?|[1-3](\.[0-9])?|3\.9)$' <<< $score; then | |
score="${BGREEN}$score${NC}" | |
elif grep -qE '^(4(\.[0-9])?|5(\.[0-9])?|6(\.[0-8])?)$' <<< $score; then | |
score="${BYELLOW}$score${NC}" | |
elif grep -qE '^(7(\.0)?|8(\.0)?|9(\.0)?|10(\.0)?)$' <<< $score; then | |
score="${BRED}$score${NC}" | |
fi | |
fi | |
# print the data | |
echo_task "CVE [$i/$total]" | |
echo_task "$webpage" | |
echo "========================================" | |
echo_info "ID: $id" | |
echo_info "Score: $score" | |
# echo_info "Severity: $severity" | |
echo_info "CVSS: $cvss" | |
echo_info "Creation: $creation_date" | |
echo_info "Last Update: $last_update_date" | |
echo_info "Description: $description" | |
echo | |
((i++)) | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
input as arguments:
![image](https://user-images.githubusercontent.com/20409221/270129161-8be158ff-9905-43aa-96fc-c4a727bb6552.png)
Input from stdin:
![image](https://user-images.githubusercontent.com/20409221/270129174-c30d8f9d-3bde-48bd-a709-91a91f899fb1.png)
Input from a file:
![image](https://user-images.githubusercontent.com/20409221/270129191-15d1547d-4019-4b89-8c6e-495c5cb8afa3.png)