您的位置:首页 > 编程语言 > Python开发

利用Python爬虫每天获取最新的CVE安全漏洞,存放至mysql数据库中

2018-01-23 09:57 1121 查看
一名黑客除了喜欢黑他人网站外,往往还需要关注天下间每天都爆发了什么安全漏洞,所以最近兴起,想写个爬虫把每天新增的CVE漏洞爬下来,放到数据库中,于是开始分析网页源码了。

爬虫的基本方式使用的是beautifulsoup解析网页(部分内容使用了正则),操作数据库使用了pymysql。

数据库表设计如下。



首先CVE每天更新有个固定链接:https://cassandra.cerias.purdue.edu/CVE_changes/today.html,源码如下:



每天新增的CVE漏洞在上面一截的<a>标签中,包括CVE编号和链接。所以需要提取链接,然后分别访问链接,从新链接中提取漏洞信息。打开链接后有时候会出现如下情况,比如漏洞描述中会出现有单引号,引号之类的,小编刚写代码时候也没注意这点,后面发现SQL语句报错,提示语句被截断,因为只是一个小脚本,这就是SQL注入产生的原因,插入的数据被当成代码执行了。所以理论上应该需要采用预编译或者参数化进行SQL操作。还需要注意的是参考链接有时候有多个,都写进去的时候,使用了函数截取了参考链接模块的源码,再正则匹配。



使用Python3操作的,代码如下:

#coding=utf8
# author:曝光黑客的那些小伎俩
# mail:sqlsec@foxmail.com
from bs4 import BeautifulSoup
import requests
import re
import pymysql

headers = {}
headers["User-Agent"] = "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30"
headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
headers["Accept-Language"] = "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"
headers["Accept-Encoding"] = "gzip, deflate"
headers["Upgrade-Insecure-Requests"] = "1"

def getMiddleStr(content, startStr, endStr):#写一个函数获取网页某个范围的源码
startIndex = content.index(startStr)
if startIndex >= 0:
startIndex += len(startStr)
endIndex = content.index(endStr)
#print(endIndex)
#print(content[startIndex:endIndex])
return content[startIndex:endIndex]

def getCVES():# 获取最新到CVE链接,返回链接的列表
try:
url = 'https://cassandra.cerias.purdue.edu/CVE_changes/today.html'
res = requests.get(url, headers=headers, timeout=60)
CVEList_html = getMiddleStr(res.text, 'New entries:', 'Graduations')
soup = BeautifulSoup(CVEList_html, 'html.parser')
list = []
for a in soup.find_all('a'):
uri = a["href"]
list.append(uri)
#print(a['href'])
#print(a.string)
return list
except Exception as e:
print(e)

def getCVEDetail(list):
try:
db = pymysql.connect("192.168.1.1","test","******","db_name")
print("连接数据库成功!")
cursor = db.cursor()
print("开始采集漏洞信息入库!")
for uri in list:
print(uri)
res = requests.get(uri,headers=headers,timeout=60)
soup = BeautifulSoup(res.text,"html.parser")
CVE_ID = str(soup.find(nowrap="nowrap").find("h2").string)
table = soup.find(id = "GeneratedTable").find("table")
Description = table.find_all("tr")[3].find("td").string
Assigning_CNA = table.find_all("tr")[8].find("td").string
Data_Entry_Created = table.find_all("tr")[10].find("b").string
s = res.text
ss = getMiddleStr(s,"References","Assigning CNA")
urls=re.findall(r"<a.*?href=.*?<\/a>",ss,re.I)
Reference = []
for i in urls[1:]:
Reference.append(i.split(">")[1].split("<")[0])
Reference_url = ",".join(Reference)
args = (CVE_ID,Description,Assigning_CNA,Data_Entry_Created,Reference_url)
sql = '''INSERT INTO spider_infos(cve_id,vul_detail,Assigning_CNA,vul_date,ref_url) VALUES ("%s","%s","%s","%s","%s")''' % (CVE_ID,Description,Assigning_CNA,Data_Entry_Created,Reference_url)
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
db.close()
print("漏洞数据采集成功!")
except Exception as e:
print(str(e))

if __name__ == "__main__":
getCVEDetail(getCVES())


输出效果如下:

存放至数据库的内容:





测试完成,然后再建立一个定时任务,每天跑一次就能获取最新CVE漏洞信息啦,大功告成!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: