2021-02-25 09:24:45 +08:00
|
|
|
|
#!/usr/bin/python3
|
|
|
|
|
# -*- coding:utf-8 -*-
|
2021-07-30 14:39:00 +08:00
|
|
|
|
# @Author : yhy&ddm&w4ter
|
2021-02-25 09:24:45 +08:00
|
|
|
|
|
|
|
|
|
# 每3分钟检测一次github是否有新的cve漏洞提交记录,若有则通过server酱和钉钉机器人推送(二者配置一个即可)
|
|
|
|
|
# 建议使用screen命令运行在自己的linux vps后台上,就可以愉快的接收各种cve了
|
|
|
|
|
|
|
|
|
|
# https://my.oschina.net/u/4581868/blog/4380482
|
|
|
|
|
# https://github.com/kiang70/Github-Monitor
|
2021-07-30 16:35:12 +08:00
|
|
|
|
import json
|
2021-02-25 09:24:45 +08:00
|
|
|
|
|
2021-07-30 10:29:21 +08:00
|
|
|
|
import requests, time, re
|
2021-02-25 09:24:45 +08:00
|
|
|
|
import dingtalkchatbot.chatbot as cb
|
|
|
|
|
import datetime
|
2021-07-29 15:11:15 +08:00
|
|
|
|
import hashlib
|
|
|
|
|
from lxml import etree
|
2021-07-29 17:54:17 +08:00
|
|
|
|
import traceback
|
2021-07-29 15:11:15 +08:00
|
|
|
|
|
2021-07-29 17:54:17 +08:00
|
|
|
|
github_headers = {
|
2021-07-30 16:35:12 +08:00
|
|
|
|
'Authorization': "token xxxxxx" # 替换自己的github token https://github.com/settings/tokens/new
|
2021-07-29 17:54:17 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-07-30 16:35:12 +08:00
|
|
|
|
|
2021-07-29 16:58:48 +08:00
|
|
|
|
# 抓取本年cve
|
|
|
|
|
def getNews():
|
|
|
|
|
try:
|
|
|
|
|
# 抓取本年的
|
|
|
|
|
year = datetime.datetime.now().year
|
|
|
|
|
api = "https://api.github.com/search/repositories?q=CVE-{}&sort=updated".format(year)
|
2021-07-30 16:35:12 +08:00
|
|
|
|
json_str = requests.get(api, headers=github_headers, timeout=10).json()
|
2021-07-29 16:58:48 +08:00
|
|
|
|
cve_total_count = json_str['total_count']
|
2021-07-30 16:35:12 +08:00
|
|
|
|
cve_description = json_str['items'][0]['description']
|
2021-07-29 16:58:48 +08:00
|
|
|
|
cve_url = json_str['items'][0]['html_url']
|
2021-08-02 09:42:30 +08:00
|
|
|
|
cve_name = json_str['items'][0]['name']
|
|
|
|
|
return cve_total_count, cve_description, cve_url,cve_name
|
2021-07-29 16:58:48 +08:00
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(e, "github链接不通")
|
|
|
|
|
return '', '', ''
|
|
|
|
|
|
2021-07-30 16:35:12 +08:00
|
|
|
|
|
2021-07-29 16:58:48 +08:00
|
|
|
|
# 通过 pushed_at 检查工具是否更新
|
|
|
|
|
def get_pushed_at_time(tools_list):
|
|
|
|
|
total_list = []
|
|
|
|
|
for url in tools_list:
|
2021-07-30 16:35:12 +08:00
|
|
|
|
pushed_at = requests.get(url, headers=github_headers, timeout=10).json()['pushed_at']
|
2021-07-29 16:58:48 +08:00
|
|
|
|
total_list.append(pushed_at)
|
|
|
|
|
|
|
|
|
|
return total_list
|
|
|
|
|
|
2021-07-30 16:35:12 +08:00
|
|
|
|
|
2021-07-29 16:58:48 +08:00
|
|
|
|
def get_update_log(url):
|
|
|
|
|
# 考虑到有的工具没有 releases, 则通过 commits 记录获取更新描述
|
2021-07-30 16:35:12 +08:00
|
|
|
|
|
2021-07-29 16:58:48 +08:00
|
|
|
|
# 判断是否有 releases 记录
|
2021-07-30 16:35:12 +08:00
|
|
|
|
json_str = requests.get(url + '/releases', headers=github_headers, timeout=10).json()
|
2021-07-29 16:58:48 +08:00
|
|
|
|
if len(json_str) != 0:
|
2021-07-30 16:35:12 +08:00
|
|
|
|
try:
|
|
|
|
|
update_log = json_str[0]['body']
|
|
|
|
|
except Exception as e:
|
|
|
|
|
update_log = "作者未写更新内容"
|
2021-07-29 16:58:48 +08:00
|
|
|
|
download_url = json_str[0]['html_url']
|
2021-07-30 16:35:12 +08:00
|
|
|
|
tools_version = json_str[0]['name']
|
|
|
|
|
return update_log, download_url,len(json_str),tools_version
|
2021-07-29 16:58:48 +08:00
|
|
|
|
else:
|
2021-07-30 16:35:12 +08:00
|
|
|
|
json_str = requests.get(url + '/commits', headers=github_headers, timeout=10).json()
|
2021-07-29 16:58:48 +08:00
|
|
|
|
update_log = json_str[0]['commit']['message']
|
2021-07-29 18:08:54 +08:00
|
|
|
|
download_url = json_str[0]['html_url']
|
|
|
|
|
return update_log, download_url
|
2021-07-29 16:58:48 +08:00
|
|
|
|
|
|
|
|
|
|
2021-07-29 15:11:15 +08:00
|
|
|
|
# 创建md5对象
|
|
|
|
|
def nmd5(str):
|
|
|
|
|
m = hashlib.md5()
|
|
|
|
|
b = str.encode(encoding='utf-8')
|
|
|
|
|
m.update(b)
|
|
|
|
|
str_md5 = m.hexdigest()
|
2021-07-30 16:35:12 +08:00
|
|
|
|
return str_md5
|
|
|
|
|
|
2021-07-29 15:11:15 +08:00
|
|
|
|
|
|
|
|
|
# 有道翻译
|
|
|
|
|
def translate(word):
|
|
|
|
|
headerstr = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36'
|
|
|
|
|
bv = nmd5(headerstr)
|
2021-07-30 16:35:12 +08:00
|
|
|
|
lts = str(round(time.time() * 1000))
|
2021-07-29 15:11:15 +08:00
|
|
|
|
salt = lts + '90'
|
|
|
|
|
|
|
|
|
|
# 如果翻译失败,{'errorCode': 50} 请查看 fanyi.min.js: https://shared.ydstatic.com/fanyi/newweb/v1.1.7/scripts/newweb/fanyi.min.js
|
|
|
|
|
# 搜索 fanyideskweb sign: n.md5("fanyideskweb" + e + i + "Y2FYu%TNSbMCxc3t2u^XT") ,Y2FYu%TNSbMCxc3t2u^XT是否改变,替换即可
|
2021-07-30 16:35:12 +08:00
|
|
|
|
strexample = 'fanyideskweb' + word + salt + 'Y2FYu%TNSbMCxc3t2u^XT'
|
2021-07-29 15:11:15 +08:00
|
|
|
|
sign = nmd5(strexample)
|
|
|
|
|
|
|
|
|
|
data = {
|
|
|
|
|
'i': word,
|
|
|
|
|
'from': 'AUTO',
|
|
|
|
|
'to': 'AUTO',
|
|
|
|
|
'smartresult': 'dict',
|
|
|
|
|
'client': 'fanyideskweb',
|
2021-07-30 16:35:12 +08:00
|
|
|
|
'salt': salt,
|
|
|
|
|
'sign': sign,
|
2021-07-29 15:11:15 +08:00
|
|
|
|
'lts': lts,
|
|
|
|
|
'bv': bv,
|
|
|
|
|
'doctype': 'json',
|
|
|
|
|
'version': '2.1',
|
|
|
|
|
'keyfrom': 'fanyi.web',
|
|
|
|
|
'action': 'FY_BY_CLICKBUTTION',
|
|
|
|
|
}
|
2021-07-30 16:35:12 +08:00
|
|
|
|
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
|
2021-07-29 15:11:15 +08:00
|
|
|
|
|
2021-07-30 16:35:12 +08:00
|
|
|
|
header = {
|
|
|
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
|
|
|
|
|
'Referer': 'http://fanyi.youdao.com/',
|
2021-07-29 15:11:15 +08:00
|
|
|
|
'Origin': 'http://fanyi.youdao.com',
|
2021-07-30 16:35:12 +08:00
|
|
|
|
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
|
|
|
'X-Requested-With': 'XMLHttpRequest',
|
|
|
|
|
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
|
|
|
|
'Accept-Encoding': 'gzip, deflate',
|
|
|
|
|
'Accept-Language': 'zh-CN,zh;q=0.9',
|
2021-07-29 15:11:15 +08:00
|
|
|
|
'Connection': 'keep-alive',
|
|
|
|
|
'Host': 'fanyi.youdao.com',
|
2021-07-30 16:35:12 +08:00
|
|
|
|
'cookie': '_ntes_nnid=937f1c788f1e087cf91d616319dc536a,1564395185984; OUTFOX_SEARCH_USER_ID_NCOO=; OUTFOX_SEARCH_USER_ID=-10218418@11.136.67.24; JSESSIONID=; ___rl__test__cookies=1'
|
2021-07-29 15:11:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = requests.post(url=url, data=data, headers=header)
|
2021-07-29 16:58:48 +08:00
|
|
|
|
result_dict = res.json()
|
2021-07-29 15:11:15 +08:00
|
|
|
|
|
|
|
|
|
result = ""
|
|
|
|
|
for json_str in result_dict['translateResult'][0]:
|
|
|
|
|
tgt = json_str['tgt']
|
|
|
|
|
result += tgt
|
|
|
|
|
return result
|
2021-02-25 09:24:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 钉钉
|
|
|
|
|
def dingding(text, msg):
|
|
|
|
|
# 将此处换为钉钉机器人的api
|
2021-07-29 17:54:17 +08:00
|
|
|
|
webhook = 'xxxxxxxx'
|
2021-07-30 16:35:12 +08:00
|
|
|
|
secretKey = 'xxxxxxxx' # 替换自己的加签, 钉钉中机器人管理 - 加签 双击,右键复制
|
|
|
|
|
ding = cb.DingtalkChatbot(webhook, secret=secretKey)
|
|
|
|
|
ding.send_text(msg='{}\r\n{}'.format(text, msg), is_at_all=False)
|
|
|
|
|
|
2021-02-25 09:24:45 +08:00
|
|
|
|
|
|
|
|
|
# server酱 http://sc.ftqq.com/?c=code
|
|
|
|
|
def server(text, msg):
|
|
|
|
|
# 将 xxxx 换成自己的server SCKEY
|
|
|
|
|
uri = 'https://sc.ftqq.com/xxxx.send?text={}&desp={}'.format(text, msg)
|
2021-07-30 16:35:12 +08:00
|
|
|
|
requests.get(uri, headers=github_headers, timeout=10)
|
|
|
|
|
|
2021-02-25 09:24:45 +08:00
|
|
|
|
|
2021-07-03 18:27:24 +08:00
|
|
|
|
# 添加Telegram Bot推送支持
|
2021-07-30 16:35:12 +08:00
|
|
|
|
def tgbot(text, msg):
|
2021-07-03 18:27:24 +08:00
|
|
|
|
import telegram
|
|
|
|
|
# Your Telegram Bot Token
|
|
|
|
|
bot = telegram.Bot(token='123456:aaa-sdasdsa')
|
2021-07-30 16:35:12 +08:00
|
|
|
|
group_id = 'Your Group ID'
|
|
|
|
|
bot.send_message(chat_id=group_id, text='{}\r\n{}'.format(text, msg))
|
2021-07-03 18:27:24 +08:00
|
|
|
|
|
|
|
|
|
|
2021-04-15 23:29:20 +08:00
|
|
|
|
# 通过检查name 和 description 中是否存在test字样,排除test
|
|
|
|
|
def regular(req):
|
2021-07-29 16:58:48 +08:00
|
|
|
|
cve_name = req['items'][0]['name']
|
2021-07-30 16:35:12 +08:00
|
|
|
|
cve_description = req['items'][0]['description']
|
2021-04-16 15:54:24 +08:00
|
|
|
|
if cve_name.lower().find('test') == -1 and cve_description.lower().find('test') == -1:
|
2021-04-15 23:29:20 +08:00
|
|
|
|
return True
|
|
|
|
|
return False
|
|
|
|
|
|
2021-07-29 16:58:48 +08:00
|
|
|
|
|
2021-07-29 15:11:15 +08:00
|
|
|
|
# 根据cve 名字,获取描述,并翻译
|
|
|
|
|
def get_cve_des_zh(cve):
|
|
|
|
|
query_cve_url = "https://cve.mitre.org/cgi-bin/cvename.cgi?name=" + cve
|
2021-07-30 16:35:12 +08:00
|
|
|
|
response = requests.get(query_cve_url, headers=github_headers, timeout=10)
|
2021-07-29 15:11:15 +08:00
|
|
|
|
html = etree.HTML(response.text)
|
|
|
|
|
des = html.xpath('//*[@id="GeneratedTable"]/table//tr[4]/td/text()')[0].strip()
|
|
|
|
|
return translate(des)
|
|
|
|
|
|
2021-07-30 16:35:12 +08:00
|
|
|
|
|
2021-07-29 16:58:48 +08:00
|
|
|
|
def sendNews(tools_list):
|
2021-04-15 23:29:20 +08:00
|
|
|
|
while True:
|
|
|
|
|
try:
|
2021-07-29 16:58:48 +08:00
|
|
|
|
print("cve 和 github 发布工具 监控中 ...")
|
2021-07-30 16:35:12 +08:00
|
|
|
|
# 抓取本年的cve
|
2021-02-25 09:24:45 +08:00
|
|
|
|
year = datetime.datetime.now().year
|
|
|
|
|
api = "https://api.github.com/search/repositories?q=CVE-{}&sort=updated".format(year)
|
2021-04-15 23:29:20 +08:00
|
|
|
|
# 请求API
|
2021-07-30 16:35:12 +08:00
|
|
|
|
req = requests.get(api, headers=github_headers, timeout=10).json()
|
2021-07-29 16:58:48 +08:00
|
|
|
|
total_count = req['total_count']
|
|
|
|
|
|
|
|
|
|
# 通过 pushed_at 检查工具是否更新
|
|
|
|
|
time_list1 = get_pushed_at_time(tools_list)
|
2021-04-15 23:29:20 +08:00
|
|
|
|
|
|
|
|
|
# 监控时间间隔3分钟
|
2021-02-25 09:24:45 +08:00
|
|
|
|
time.sleep(180)
|
2021-07-29 16:58:48 +08:00
|
|
|
|
|
2021-07-29 17:54:17 +08:00
|
|
|
|
# 检查name 和 description 中是否存在test字样 和 是否更新
|
|
|
|
|
if regular(req) and total_count != getNews()[0]:
|
|
|
|
|
# 推送正文内容
|
|
|
|
|
# 推送标题
|
|
|
|
|
text = r'有新的CVE送达!'
|
|
|
|
|
# 获取 cve 名字 ,根据cve 名字,获取描述,并翻译
|
2021-08-02 09:42:30 +08:00
|
|
|
|
cve_name = re.findall('(CVE\-\d+\-\d+)', getNews()[3])[0].upper()
|
2021-07-30 16:35:12 +08:00
|
|
|
|
cve_zh = get_cve_des_zh(cve_name)
|
|
|
|
|
msg = "CVE编号:" + cve_name + "\r\n" + "Github地址:" + str(getNews()[2]) + "\r\n" + "CVE描述:" +"\r\n"+ cve_zh
|
|
|
|
|
|
2021-07-29 17:54:17 +08:00
|
|
|
|
# 三选一即可,没配置的 注释或者删掉
|
|
|
|
|
# server(text, msg)
|
|
|
|
|
dingding(text, msg)
|
|
|
|
|
# tgbot(text,msg)
|
|
|
|
|
print(msg)
|
|
|
|
|
|
2021-07-29 16:58:48 +08:00
|
|
|
|
time_list2 = get_pushed_at_time(tools_list)
|
|
|
|
|
|
|
|
|
|
for i in range(len(tools_list)):
|
|
|
|
|
# 两次时间不相等,则代表工具更新
|
|
|
|
|
if time_list1[i] != time_list2[i]:
|
2021-07-30 16:35:12 +08:00
|
|
|
|
# get_update_log_info = get_update_log(tools_list[i])
|
|
|
|
|
if len(get_update_log(tools_list[i])) == 2:
|
|
|
|
|
update_log = get_update_log(tools_list[i])[0]
|
|
|
|
|
download_url = get_update_log(tools_list[i])[1]
|
|
|
|
|
tools_name = tools_list[i].split('/')[-1]
|
|
|
|
|
text = r'** ' + tools_name + r' ** 工具更新啦!'
|
|
|
|
|
body = "工具名称:" + tools_name + "\r\n" + "工具地址:" + download_url + "\r\n" + "工具更新日志:" + "\r\n" + update_log
|
|
|
|
|
# 三选一即可,没配置的 注释或者删掉
|
|
|
|
|
# server(text, body)
|
|
|
|
|
dingding(text, body)
|
|
|
|
|
# tgbot(text,body)
|
|
|
|
|
print(body)
|
|
|
|
|
elif len(get_update_log(tools_list[i])) == 4:
|
|
|
|
|
one_all_info = get_update_log(tools_list[i])
|
|
|
|
|
release_len_one = one_all_info[2]
|
|
|
|
|
time.sleep(120)
|
|
|
|
|
two_all_info = get_update_log(tools_list[i])
|
|
|
|
|
release_len_two = two_all_info[2]
|
|
|
|
|
if release_len_one != release_len_two:
|
|
|
|
|
update_log = two_all_info[0]
|
|
|
|
|
download_url = two_all_info[1]
|
|
|
|
|
tools_version = two_all_info[3]
|
|
|
|
|
tools_name = tools_list[i].split('/')[-1]
|
|
|
|
|
text = r'** ' + tools_name + r' ** 工具版本更新啦!'
|
|
|
|
|
body = "工具名称:" + tools_name + "\r\n"+"当前最新版本:"+tools_version+"\r\n"+ "工具下载地址:" + download_url + "\r\n" + "工具更新日志:" + "\r\n" + update_log
|
|
|
|
|
# 三选一即可,没配置的 注释或者删掉
|
|
|
|
|
# server(text, body)
|
|
|
|
|
dingding(text, body)
|
|
|
|
|
# tgbot(text,body)
|
|
|
|
|
else:
|
|
|
|
|
commits_url = tools_list[i]+"/commits"
|
|
|
|
|
commits_url_response_json = requests.get(commits_url).text
|
|
|
|
|
commits_json = json.loads(commits_url_response_json)
|
|
|
|
|
tools_name = tools_list[i].split('/')[-1]
|
|
|
|
|
download_url = commits_json[0]['html_url']
|
|
|
|
|
try:
|
|
|
|
|
update_log = commits_json[0]['commit']['message']
|
|
|
|
|
except Exception as e:
|
|
|
|
|
update_log = "作者未写更新内容,具体点击更新详情地址的URL进行查看"
|
|
|
|
|
text = r'** ' + tools_name + r' ** 工具小更新了一波!'
|
|
|
|
|
body = "工具名称:" + tools_name + "\r\n" + "更新详情地址:" + download_url + "\r\n" + "工具更新日志:" + "\r\n" + update_log
|
|
|
|
|
# 三选一即可,没配置的 注释或者删掉
|
|
|
|
|
# server(text, body)
|
|
|
|
|
dingding(text, body)
|
|
|
|
|
# tgbot(text,body)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-07-29 15:11:15 +08:00
|
|
|
|
|
2021-04-15 23:29:20 +08:00
|
|
|
|
except Exception as e:
|
2021-07-29 17:54:17 +08:00
|
|
|
|
print("Program runing error:{}".format(traceback.print_exc()))
|
2021-02-25 09:24:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2021-07-29 16:58:48 +08:00
|
|
|
|
tools_list = [
|
|
|
|
|
"https://api.github.com/repos/BeichenDream/Godzilla",
|
|
|
|
|
"https://api.github.com/repos/rebeyond/Behinder",
|
|
|
|
|
"https://api.github.com/repos/AntSwordProject/antSword",
|
|
|
|
|
"https://api.github.com/repos/j1anFen/shiro_attack",
|
|
|
|
|
"https://api.github.com/repos/yhy0/ExpDemo-JavaFX",
|
|
|
|
|
"https://api.github.com/repos/yhy0/github-cve-monitor",
|
|
|
|
|
"https://api.github.com/repos/gentilkiwi/mimikatz",
|
|
|
|
|
"https://api.github.com/repos/ehang-io/nps",
|
|
|
|
|
"https://api.github.com/repos/chaitin/xray",
|
|
|
|
|
"https://api.github.com/repos/FunnyWolf/pystinger",
|
|
|
|
|
"https://api.github.com/repos/L-codes/Neo-reGeorg",
|
2021-07-30 16:35:12 +08:00
|
|
|
|
"https://api.github.com/repos/shadow1ng/fscan",
|
2021-07-29 16:58:48 +08:00
|
|
|
|
]
|
2021-07-30 14:39:00 +08:00
|
|
|
|
sendNews(tools_list)
|