获取最新的CVE信息

获取最新的CVE信息

GitHub - password123456/cve-collector: Simple Latest CVE Collector Written in Python

__author__ = 'https://github.com/password123456/'
__date__ = '2024.02.27'
__version__ = '1.0.4'
__status__ = 'Production'

import os
import sys
import re
import requests
import hashlib
from datetime import datetime
import time
from bs4 import BeautifulSoup


class Bcolors:
    Black = '\033[30m'
    Red = '\033[31m'
    Green = '\033[32m'
    Yellow = '\033[33m'
    Blue = '\033[34m'
    Magenta = '\033[35m'
    Cyan = '\033[36m'
    White = '\033[37m'
    Endc = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'


def sha1_hash(string):
    return hashlib.sha1(string.encode()).hexdigest()


def is_valid_cve_id_year(cve_id):
    cve_id_year = re.findall(r"\d{4}", cve_id)[0]
    current_year = datetime.today().strftime("%Y")

    # Throw away cve-feed that published more than 1 years ago before
    if int(current_year) - int(cve_id_year) >= 1:
        return False
    else:
        return True


def feeds_exists_in_db(feed_db, _hash_to_check, _id_to_check):
    try:
        if os.path.exists(feed_db):
            mode = 'r'
        else:
            mode = 'w'
        n = 0
        with open(feed_db, mode) as database:
            for line in database:
                if not len(line.strip()) == 0:
                    n += 1
                    hash_in_db = line.split('|')[2].replace('\n', '')
                    id_in_db = str(line.split('|')[3].replace('\n', ''))
                    if str(_id_to_check) == str(id_in_db):
                        return True
                    else:
                        if str(_hash_to_check) == str(hash_in_db):
                            return True
        return False
    except Exception as error:
        print(f'{Bcolors.Yellow}- ::Exception:: Func:[{feeds_exists_in_db.__name__}] '
              f'Line:[{sys.exc_info()[-1].tb_lineno}] [{type(error).__name__}] {error}{Bcolors.Endc}', flush=True)


def fetch_latest_cve_entries(feed_db, feed_url):
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                             '(KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'}

    r = requests.get(feed_url, headers=headers, verify=True)
    if r.status_code == 200:
        body = r.text
        soup = BeautifulSoup(body, 'html.parser')
        search_results_div = soup.find('div', {'id': 'searchresults'})
        if search_results_div:
            cve_info_divs = search_results_div.find_all('div', {'data-tsvfield': 'cveinfo'})
            if not cve_info_divs:
                message = (f'{os.path.realpath(__file__)}\n\n'
                           f'[{fetch_latest_cve_entries.__name__}]\n'
                           f'>> Failed to parse HTML elements cve_info_divs <<')
                print(f'{Bcolors.Yellow}- {message} {Bcolors.Endc}')
                ## Send the result to webhook. ##
                sys.exit(1)
        else:
            message = (f'{os.path.realpath(__file__)}\n\n'
                       f'[{fetch_latest_cve_entries.__name__}]\n'
                       f'>> Failed to parse HTML elements searchresults_divs <<')
            print(f'{Bcolors.Yellow}- {message} {Bcolors.Endc}')
            ## Send the result to webhook. ##
            sys.exit(1)

        newest_cve_entries = []
        for cve_info_div in cve_info_divs:
            try:
                cve_id = cve_info_div.find('h3', {'data-tsvfield': 'cveId'}).a.text.strip()
                cve_publish_date = cve_info_div.find('div', {'data-tsvfield': 'publishDate'}).text.strip()
                cve_link = f"https://www.cvedetails.com{cve_info_div.find('a', href=True)['href']}"
            except AttributeError as error:
                message = (f'{os.path.realpath(__file__)}\n\n'
                           f'[{fetch_latest_cve_entries.__name__}]\n{error}\n'
                           f'>> Failed to parse HTML elements cve_id, cve_publish_date, cve_link <<')
                print(f'{Bcolors.Yellow}- {message} {Bcolors.Endc}')
                ## Send the result to webhook. ##
                sys.exit(1)

            if not cve_id or not cve_publish_date or not cve_link:
                message = (f'{os.path.realpath(__file__)}\n\n'
                           f'[{fetch_latest_cve_entries.__name__}]\n'
                           f'>> Failed to parse One or more of cve_id, cve_publish_date, or cve_link is empty <<')
                print(f'{Bcolors.Yellow}- {message} {Bcolors.Endc}')
                ## Send the result to webhook. ##
                sys.exit(1)

            # Throw away more than 1 years ago before
            is_valid_cve_year = is_valid_cve_id_year(cve_id)
            if not is_valid_cve_year:
                continue

            if os.path.exists(feed_db):
                hashed_data = sha1_hash(f'{cve_id}_{str(cve_publish_date)}')
                if not feeds_exists_in_db(feed_db, hashed_data, cve_id):
                    newest_cve_entries.append(cve_link)
            else:
                newest_cve_entries.append(cve_link)

    else:
        message = (f'{os.path.realpath(__file__)}\n\n'
                   f'[{fetch_latest_cve_entries.__name__}]\n'
                   f'- {feed_url}\n- HTTP: {r.status_code}')
        print(f'{Bcolors.Yellow}[-] Error: {message} {Bcolors.Endc}')
        ## Send the result to webhook. ##
        sys.exit(1)

    return newest_cve_entries


def retrieve_cve_details(feed_db, cve_entries):
    if os.path.exists(feed_db):
        mode = 'a'
    else:
        mode = 'w'

    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
                             '(KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'}

    n = 0
    cve_content_result = ''
    with open(feed_db, mode) as fa:
        for cve_link in cve_entries:
            time.sleep(5)
            r = requests.get(cve_link, headers=headers, verify=True)
            if r.status_code == 200:
                body = r.text
                soup = BeautifulSoup(body, 'html.parser')
                cve_content_div = soup.find('div', attrs={'id': 'contentdiv'})
                if not cve_content_div:
                    message = (f'{os.path.realpath(__file__)}\n\n'
                               f'[{fetch_latest_cve_entries.__name__}]\n\n'
                               f'>> Failed to parse HTML elements cve_content_div <<')
                    print(f'{Bcolors.Yellow}- {message} {Bcolors.Endc}')
                    ## Send the result to webhook. ##
                    sys.exit(1)

                try:
                    cve_id = cve_content_div.find('h1').find('a').text.strip()
                    description = cve_content_div.find('div', class_='cvedetailssummary-text').text.strip()

                    published_updated_elements = cve_content_div.find_all('div', class_='d-inline-block')
                    published_date = published_updated_elements[0].text.strip().replace("Published", "").strip()
                    updated_date = published_updated_elements[1].text.strip().replace("Updated", "").strip()

                    base_score_elements = cve_content_div.find_all('td', class_='ps-2')
                    base_score = base_score_elements[0].find('div', class_='cvssbox').text.strip()
                    base_severity = base_score_elements[1].text.strip()

                    cwe_heading = cve_content_div.find('h2', string='CWE ids for ' + cve_id)
                    if cwe_heading:
                        cwe_item = cwe_heading.find_next('a')
                        if cwe_item:
                            cwe_id = cwe_item.text.strip()
                    else:
                        cwe_id = f'Not found CWE ids for {cve_id}'

                    references_heading = cve_content_div.find('h2', string='References for ' + cve_id)
                    if references_heading:
                        references_list = references_heading.find_next('ul', class_='list-group')
                        if references_list:
                            reference_links = references_list.find_all('a', class_='ssc-ext-link')
                            references = [link['href'] for link in reference_links]
                    else:
                        references = f'Not found references for {cve_id}'

                except AttributeError as error:
                    message = (f'{os.path.realpath(__file__)}\n\n'
                               f'[{retrieve_cve_details.__name__}]\n{error}\n\n'
                               f'>> Failed to parse HTML elements. One or more of the data fields parse error <<')
                    print(f'{Bcolors.Yellow}- {message} {Bcolors.Endc}')
                    ## Send the result to webhook. ##
                    sys.exit(1)

                if not cve_id or not description or not published_date \
                        or not updated_date or not base_score or not base_severity:
                    message = (f'{os.path.realpath(__file__)}\n\n'
                               f'[{retrieve_cve_details.__name__}]\n\n'
                               f'>> Failed to parse HTML. One or more of the data fields is empty <<')
                    print(f'{Bcolors.Yellow}- {message} {Bcolors.Endc}')
                    ## Send the result to webhook. ##
                    sys.exit(1)

                # cut size of the description to 135 bytes
                if int(len(str(description))) >= 138:
                    description = f"{description[:135]}..."

                # formatted references list
                if references:
                    i = 0
                    if isinstance(references, list):
                        formatted_references = '\n'.join([f'({i + 1}) {ref}' for i, ref in enumerate(references)])
                    else:
                        formatted_references = f'({i + 1}) {references}'

                # formatted published_date
                date_obj = datetime.strptime(published_date, "%Y-%m-%d %H:%M:%S")
                formatted_date = date_obj.strftime("%Y-%m-%d")

                hashed_data = sha1_hash(f'{cve_id}_{str(formatted_date)}')
                if not feeds_exists_in_db(feed_db, hashed_data, cve_id):
                    n += 1
                    fa.write(f'{n}|{datetime.now()}|{hashed_data}|{cve_id}|{published_date}'
                             f'|{base_score}|{base_severity}|{cwe_id}\n')

                    contents = f'{n}. {cve_id} / CVSS: {base_score} ({base_severity})\n' \
                               f'- Published: {published_date}\n' \
                               f'- Updated: {updated_date}\n' \
                               f'- CWE: {cwe_id}\n\n' \
                               f'{description}\n' \
                               f'>> https://www.cve.org/CVERecord?id={cve_id}\n\n' \
                               f'- Ref.\n{formatted_references}\n\n\n'
                    cve_content_result += contents
            else:
                message = (f'{os.path.realpath(__file__)}\n\n'
                           f'[{retrieve_cve_details.__name__}]\n'
                           f'- {cve_link}\n- HTTP: {r.status_code}')
                print(f'{Bcolors.Yellow}[-] Error: {message} {Bcolors.Endc}')
                ## Send the result to webhook. ##
                sys.exit(1)

    return cve_content_result


def main():
    home_path = f'{os.getcwd()}'
    feed_db = f'{home_path}/feeds.db'

    cvss_min_score = 6
    feed_url = f'https://www.cvedetails.com/vulnerability-search.php?f=1&cvssscoremin={cvss_min_score}&page=1'

    latest_cve_entries = fetch_latest_cve_entries(feed_db, feed_url)
    if latest_cve_entries:
        cve_details = retrieve_cve_details(feed_db, latest_cve_entries)
        if cve_details:
            cve_details = f'*{datetime.now()}*\n\n{cve_details}'
            print(f'{cve_details}')
            ## Send the result to webhook. ##
        else:
            print(f'{Bcolors.Blue}>>> [OK] ({datetime.now()}) No NEW CVE{Bcolors.Endc}')


if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        sys.exit(0)
    except Exception as e:
        print(f'{Bcolors.Yellow}- (Exception) Func:[{__name__.__name__}] '
              f'Line:[{sys.exc_info()[-1].tb_lineno}] [{type(e).__name__}] {e}{Bcolors.Endc}')
      
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/610307.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Boost库的使用

1 下载与安装 1.1 下载 网址&#xff1a;Boost C Libraries 进入后选择自己需要的版本安装即可 1.2 安装 1.2.1 解压 1.2.2 编译安装 双击bootstrap.bat 这一步完成后会生成一个b2.exe文件 双击b2.exe文件运行&#xff08;此步需要花费较长的时间&#xff09; 之后再stag…

新增分类——后端

实现功能&#xff1a; 代码开发逻辑&#xff1a; 页面发送ajax请求&#xff0c;将新增分类窗口输入的数据以json形式提交到服务端服务端Controller接收页面提交的数据并调用Service将数据进行保存Service调用Mapper操作数据库&#xff0c;保存数据 代码实现&#xff1a; Con…

遇到如此反复的外贸客户,你可以这样做~

来源&#xff1a;宜选网&#xff0c;侵删 当你们遇到爽快的买家的时候&#xff0c;你是否有把握一定能把她拿下呢&#xff1f; 还是说即使客户很爽快&#xff0c;你也会耐心认真的沟通呢&#xff1f; 今天要和大家分享的这个买家&#xff0c;我本以为他是一个很爽快的买家&am…

前端使用Compressor.js实现图片压缩上传

前端使用Compressor.js实现图片压缩上传 Compressor.js官方文档 安装 npm install compressorjs使用 在使用ElementUI或者其他UI框架的上传组件时&#xff0c;都会有上传之前的钩子函数&#xff0c;在这个函数中可以拿到原始file&#xff0c;这里我用VantUI的上传做演示 a…

基于TRIZ理论的锂电池生产工艺优化思路

在能源科技迅猛发展的今天&#xff0c;锂电池作为重要的储能元件&#xff0c;其生产工艺的优化与革新显得尤为关键。本文将基于TRIZ理论&#xff0c;探讨锂电池生产工艺的优化路径&#xff0c;以期提升能源产业的效率与环保性。 TRIZ&#xff0c;即发明问题解决理论&#xff0…

三级综合医院微信预约挂号系统源码,PC后台管理端+微信公众号+支付宝小程序全套源码

智慧医院预约挂号系统&#xff0c;微信医疗预约挂号小程序源码&#xff0c;实体医院预约挂号支付系统源码 本系统主要面向中大型的医疗机构&#xff0c;适用于各级公立和民营医院&#xff0c;可对接院内his、lis、pacs系统。 PC后台管理端微信公众号支付宝小程序 系统支持当日…

Apinto下载安装以及集群部署总结

下载 下载官方提供的安装包安装&#xff08;推荐&#xff09; wget https://github.com/eolinker/apinto/releases/download/v0.13.3/apinto_v0.13.3_linux_amd64.tar.gz && tar -zxvf apinto_v0.13.3_linux_amd64.tar.gz && cd apinto 安装 先确保已经入解…

浅谈postman设置token依赖步骤

前言&#xff1a; postman做接口测试时&#xff0c;大多数的接口必须在有token的情况下才能运行&#xff0c;我们可以获取token后设置一个环境变量供所在同一个集合中的所有接口使用。 一般是通过调用登录接口&#xff0c;获取到token的值 实战项目&#xff1a;jeecg boot项…

InfluxDB学习之linux上安装InfluxDB

InfluxDB学习之linux上安装InfluxDB 什么是InfluxDB特点使用场景 如何安装windows如何安装linux安装教程&#xff08;不用登录&#xff0c;&#xff09; 界面展示特别说明 什么是InfluxDB InfluxDB 是一个用于存储和分析时间序列数据的开源数据库。由 Golang 语言编写&#xff…

什么是HTTP/2?

HTTP/2&#xff08;原名HTTP 2.0&#xff09;即超文本传输协议第二版&#xff0c;使用于万维网。HTTP/2主要基于SPDY协议&#xff0c;通过对HTTP头字段进行数据压缩、对数据传输采用多路复用和增加服务端推送等举措&#xff0c;来减少网络延迟&#xff0c;提高客户端的页面加载…

分布式锁讲解

概括 分布式锁是一种用于在分布式系统中实现同步机制的锁。在单机系统中&#xff0c;我们可以使用如Java中的synchronized关键字或者 ReentrantLock来实现线程间的同步&#xff0c;但在分布式系统中&#xff0c;由于多个节点&#xff08;服务器&#xff09;之间的并发操作&am…

【探索Java编程:从入门到入狱】Day5

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

CSS基础(盒子模型、浮动、定位)

盒子模型 所有HTML元素可以看作盒子&#xff0c;这个盒子包含了内容、内边距、边框和外边距。 Margin(外边距) -边框外的区域&#xff0c;也就是盒子与其他元素之间的空间&#xff0c;外边距是透明的。Border(边框) - 围绕在内边距和内容外的边框。就是边框大小Padding(内边距…

好题总结汇总

好题总结汇总 总结一些做完很有收获的题。 一、经典问题 DP的结合 1、题意&#xff1a; 给定 n n n 种颜色的球的数量 a 1 , a 2 , . . . , a n a_1, a_2, ..., a_n a1​,a2​,...,an​&#xff0c;选出一些不同种类的球(也就是在n种球中选球的任意情况)&#xff0c;将球…

中国工程院院陈纯一行调研实在智能,助推企业科技创新

2024年5月8日&#xff0c;浙江大学计算机科学与技术学院教授、中国工程院院士陈纯院士一行访问了实在智能公司&#xff0c;针对AI Agent智能体进行了专项调研。实在智能创始人、CEO孙林君&#xff0c;以及公司管理层和研发、市场、产品等部门负责人共同出席了座谈会。 陈纯院士…

DDD面试题:DDD聚合和表的对应关系是什么 ?(来自蚂蚁面试)

尼恩说在前面&#xff1a; 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如字节、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; DDD 的外部接口调用&#xff0c;应该放在…

【JAVA】JAVA的垃圾回收机制详解

对于Java的垃圾回收机制&#xff0c;它是Java虚拟机&#xff08;JVM&#xff09;提供的一种自动内存管理机制&#xff0c;主要负责回收不再使用的对象以释放内存空间。垃圾回收机制主要包括以下几个方面的内容&#xff1a; 垃圾对象的识别&#xff1a;Java虚拟机通过一些算法&…

element ui的table多选

使用el-table的selection-change事件来获取选中的值&#xff1b; 例&#xff1a; html代码&#xff1a; <el-button type"primary" click"openTableSet">列表设置</el-button><!-- 列表设置弹框 --> <el-dialog :close-on-click-mo…

替代UCC21550隔离式双通道栅极驱动器

描述 PC86320是一个隔离的双通道栅极驱动器具有可编程死区时间和宽温度范围。它设计有5A峰值源和6A峰值吸收电流来驱动电源高达2MHz的MOSFET、SiC、GaN和IGBT晶体管开关频率。PC86320可以配置为两个低端驱动器&#xff0c;两个高边驱动器&#xff0c;或具有可编程功能的半桥驱…

二叉树的广度优先遍历 - 华为OD统一考试(D卷)

OD统一考试(D卷) 分值: 200分 题解: Java / Python / C++ 题目描述 有一棵二叉树,每个节点由一个大写字母标识(最多26个节点)。 现有两组字母,分别表示后序遍历(左孩子->右孩子->父节点)和中序遍历(左孩子->父节点->右孩子)的结果,请输出层次遍历的结…
最新文章