-
Notifications
You must be signed in to change notification settings - Fork 47
/
setup.py
248 lines (245 loc) · 13.4 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# -*- coding: utf-8 -*-
"""
SECMON - Source code of the SECMON setup script.
"""
__author__ = "Aubin Custodio"
__copyright__ = "Copyright 2021, SECMON"
__credits__ = ["Aubin Custodio","Guezone"]
__license__ = "CC BY-NC-SA 4.0"
__version__ = "2.1"
__maintainer__ = "Aubin Custodio"
__email__ = "[email protected]"
import sys, base64, time, os, smtplib,argparse, re, sqlite3, feedparser, requests
from werkzeug.security import generate_password_hash, check_password_hash
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from secmon_lib import pollCveIdFromCpe, registerNewCve, getCpeList, getKeywordsList
from datetime import datetime, timedelta
from getpass import getpass
from traceback_with_variables import print_exc
rss_feeds = [
'https://cyware.com/allnews/feed',
'https://www.cshub.com/rss/categories/attacks',
'https://www.schneier.com/feed/atom/',
'https://www.cshub.com/rss/categories/cloud' ,
'https://www.cshub.com/rss/categories/iot',
'https://www.cshub.com/rss/categories/data',
'https://www.cshub.com/rss/categories/executive-decisions',
'https://www.cshub.com/rss/categories/network',
'https://krebsonsecurity.com/feed/',
'https://www.cshub.com/rss/categories/threat-defense',
'https://www.fortiguard.com/rss/ir.xml',
'https://nakedsecurity.sophos.com/feed/',
'https://www.techrepublic.com/rssfeeds/topic/security/?feedType=rssfeeds',
'http://feeds.feedburner.com/TheHackersNews?format=xml',
'https://www.cert.ssi.gouv.fr/feed/',
'https://us-cert.cisa.gov/ncas/all.xml',
'https://www.zataz.com/feed/'
]
def handleException(error):
now = datetime.now()
now = now.strftime("%d/%m/%Y, %H:%M:%S")
print(f"################## NEW SETUP ERROR AT {now} ##################")
print(print_exc())
print("################## PLEASE REPORT THIS ON GITHUB ##################")
def mailTester(smtp_login, smtp_passwd, server, port, tls, sender, receivers, language,github_username,github_api_key,username,password):
print()
configBuilder(smtp_login, smtp_passwd, server, port, tls, sender, receivers, language,github_username,github_api_key,username,password)
buildRSSList(rss_feeds)
script_path = os.path.abspath(__file__)
dir_path = script_path.replace("setup.py","")
body = ""
receivers_email = receivers.split(";")
with open(dir_path+'rss_template.html', 'r') as template:
html_code = template.read()
html_code = html_code.replace("Notification","SECMON")
html_code = html_code.replace("<strong>Title : </strong> $TITLE <br><br>","")
html_code = html_code.replace("<strong>Source : </strong> $SOURCE <br><br>","")
if language =="en" or language == "EN":
html_code = html_code.replace("RSS module","Test email")
html_code = html_code.replace("<strong>Summary :</strong> $SUMMARY <br>","SECMON is an active security watch program that alerts you to the latest vulnerabilities and threats.")
html_code = html_code.replace("Responsive HTML email templates","SECMON - Test email.")
html_code = html_code.replace("See more details","Follow me on Github")
body = html_code.replace("URL OF THE NEWS","https://github.com/Guezone/SECMON")
elif language =="fr" or language == "FR":
html_code = html_code.replace("RSS module","Mail de test")
html_code = html_code.replace("<strong>Summary :</strong> $SUMMARY <br>","SECMON est un programme de veille sécurité active\net vous averti des dernières vulnérabilités et menaces.")
html_code = html_code.replace("Responsive HTML email templates","SECMON - Mail de test.")
html_code = html_code.replace("See more details","Suivez-moi sur Github")
html_code = html_code.replace("This email was sent by", "Cet email a été envoyé par")
body = html_code.replace("URL OF THE NEWS","https://github.com/Guezone/SECMON")
else:
print("Incorrect language set. Please retry. Exiting...")
for receiver in receivers_email:
try:
print("\nPlease wait. A test message to {} will be sent to test your configuration.\n".format(receiver))
smtpserver = smtplib.SMTP(server,port)
msg = MIMEMultipart()
if language =="en" or language == "EN":
msg['Subject'] = 'SECMON - Test email.'
elif language =="fr" or language == "FR":
msg['Subject'] = 'SECMON - Mail de test.'
else:
print("Incorrect language set. Please retry. Exiting...")
msg['From'] = sender
msg['To'] = receiver
msg.attach(MIMEText(body, 'html'))
except Exception as e:
handleException(e)
print("Incorrect configuration. Exit")
exit()
try:
if tls == "yes":
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.login(smtp_login, smtp_passwd)
smtpserver.sendmail(sender, receiver, msg.as_string())
elif tls == "no":
smtpserver.login(smtp_login, smtp_passwd)
smtpserver.sendmail(sender, receiver, msg.as_string())
else:
print("You must specify if you want to use TLS(-tls yes|no). Exit.")
exit()
except Exception as e:
handleException(e)
print("An error occurred during authentication with the SMTP server. Check the configuration and try again.")
exit()
print("SECMON is now ready. Execute secmon.py now and automate it.")
def buildRSSList(rss_feeds):
script_path = os.path.abspath(__file__)
dir_path = script_path.replace("setup.py","")
print("\nRSS news database recording in progress...\n")
con = sqlite3.connect(dir_path+'secmon.db')
con.execute('''CREATE TABLE RSS_DATA ([key] INTEGER PRIMARY KEY,[RSS_URL] text,[title] text,[rss_f] text,[summary] text)''')
cur = con.cursor()
con.commit()
con.execute('''CREATE TABLE CVE_DATA ([key] INTEGER PRIMARY KEY,[CVE_ID] text,[KEYWORD] text,[STATUS] text,[CVE_SCORE] text,[CVE_DATE] text,[CVE_DESCRIPTION] text,[CVE_EVAL] text,[CVE_CPE] text,[CVE_SOURCES] text,[EXPLOIT_FIND] text,[INDEXING_DATE] text)''')
con.execute('''CREATE TABLE high_risk_products ([key] INTEGER PRIMARY KEY,[cpe] text,[hname] text)''')
con.execute('''CREATE TABLE tasks ([key] INTEGER PRIMARY KEY,[task_id] text,[status] text,[comment] text)''')
con.commit()
for rss_feed in rss_feeds:
current_feed = feedparser.parse(rss_feed)
for entries in current_feed.entries:
url = str(entries.link)
title = entries.title
summary = entries.summary
cur.execute("INSERT INTO RSS_DATA (RSS_URL, title, rss_f, summary) VALUES (?,?,?,?);", (url,title,rss_feed,summary))
con.commit()
print("Successful build database.\n")
def configBuilder(smtp_login, smtp_passwd, smtpsrv, port, tls, sender, receiver, language,github_username,github_api_key,username,password):
script_path = os.path.abspath(__file__)
dir_path = script_path.replace("setup.py","")
try:
os.system(f"touch {dir_path}logs.txt")
os.system(f"chmod 777 {dir_path}logs.txt")
except:
pass
enc_pass = (str(base64.b64encode(smtp_passwd.encode("UTF-8"))).replace("b'","")).replace("'","")
if os.path.isfile(dir_path+"secmon.db"):
os.remove(dir_path+"secmon.db")
con = sqlite3.connect(dir_path+'secmon.db')
con.execute('''CREATE TABLE config ([key] INTEGER PRIMARY KEY,[sender] text,[smtp_login] text,[smtp_password] text,[smtpsrv] text,[port] text,[receiver] text,[tls] text,[language] text,[github_api_key] text,[github_username] text,[cvss_alert_limit] text,[no_score_cve_alert] text)''')
con.execute('''CREATE TABLE keyword_list ([key] INTEGER PRIMARY KEY,[keyword] text)''')
con.execute('''CREATE TABLE cpe_list ([key] INTEGER PRIMARY KEY,[cpe] text)''')
con.commit()
con.execute("INSERT INTO config (smtp_login,smtp_password,smtpsrv,port,sender, receiver,tls,language) VALUES (?,?,?,?,?,?,?,?);", (smtp_login,enc_pass,smtpsrv,str(port),sender, receiver,tls,language))
con.commit()
if not github_username or not github_api_key or github_api_key=="" or github_username=="":
github_username = input("Please enter your Github username : ")
github_api_key = getpass("Please enter your Github API Token : ")
try:
login_attempt = requests.get('https://api.github.com/search/repositories?q=github+api', auth=(github_username,github_api_key))
if login_attempt.status_code != 200:
raise
else:
con.execute("INSERT INTO config (github_api_key,github_username,cvss_alert_limit,no_score_cve_alert) VALUES (?,?,?,?);", (github_username,github_api_key,"no_limit","True"))
con.commit()
except Exception as e:
handleException(e)
print("Github API authentication failed. You can add this config on the web UI after installation...")
else:
con.execute("INSERT INTO config (github_api_key,github_username,cvss_alert_limit,no_score_cve_alert) VALUES (?,?,?,?);", ("None","None","no_limit","True"))
con.commit()
if not username or not password or username=="" or password=="":
while username == "" or password == "" or password != password2:
username = input("Enter the username that can be used on the Web UI : ")
password = getpass("Enter the password (please choose a strong password !) : ")
password2 = getpass("Confirm the password : ")
if password != password2:
print("Both passwords must be the same.")
if username == "":
print("A username must be filled in.")
if password == "":
print("A password must be entered.")
con.execute('''CREATE TABLE users ([uid] INTEGER PRIMARY KEY,[username] text,[pass_hash] text)''')
con.execute('''CREATE TABLE secret_key ([uid] INTEGER PRIMARY KEY,[app_secret_key] text)''')
con.commit()
hashed_pwd = generate_password_hash(password, 'sha512')
cur = con.cursor()
cur.execute("INSERT INTO users (username, pass_hash) VALUES (?,?);", (username, hashed_pwd))
con.commit()
secret_key = os.urandom(2048).hex()
cur.execute("INSERT INTO secret_key (app_secret_key) VALUES (?);", (secret_key,))
con.commit()
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-sender",nargs=1,required=True,metavar="email-addr",help="set sender email address")
parser.add_argument("-login",nargs=1,required=True,metavar="smtp_login",help="set SMTP login")
parser.add_argument("-p",nargs=1,required=True,metavar="smtp_password",help="set sender SMTP password")
parser.add_argument("-server",nargs=1,required=True,metavar="smtp_server",help="set SMTP server name")
parser.add_argument("-port",nargs=1,required=True,metavar="port",help="set SMTP port used by the server", type=int)
parser.add_argument("-tls",nargs=1,required=True,metavar="yes|no",help="use TLS for SMTP authentication")
parser.add_argument("-r",nargs=1,required=True,metavar="email-addr1;email-addr2",help="set receivers email address")
parser.add_argument("-lang",nargs=1,required=True,metavar="en|fr",help="set the language of the emails")
parser.add_argument("-accept",nargs=1,required=False,metavar="true|false",help="accept CC BY-NC-SA 4.0 SECMON license")
parser.add_argument("-github_username",nargs=1,required=False,metavar="github username",help="set github api username")
parser.add_argument("-github_api_key",nargs=1,required=False,metavar="github api key",help="set github api token")
parser.add_argument("-username",nargs=1,required=False,metavar="username",help="set web ui username")
parser.add_argument("-password",nargs=1,required=False,metavar="password",help="set web ui password")
args = parser.parse_args()
sender = ''.join(args.sender)
smtp_login = ''.join(args.login)
smtp_passwd = ''.join(args.p)
server = ''.join(args.server)
port = args.port[0]
tls = ''.join(args.tls)
receivers = ''.join(args.r)
language = ''.join(args.lang)
try:
accept = ''.join(args.accept)
except:
accept = ""
pass
try:
github_username = ''.join(args.github_username)
except:
github_username = ""
pass
try:
github_api_key = ''.join(args.github_api_key)
except:
github_api_key = ""
pass
try:
username = ''.join(args.username)
except:
username = ""
pass
try:
password = ''.join(args.password)
except:
password = ""
pass
print("------------------------------------")
print(f"SECMON setup script - Version {__version__}")
print("------------------------------------")
if not accept or accept!="true":
license_validation = input("SECMON is licensed by CC BY-NC-SA 4.0 license. Do you accept the terms of the license? (y/Y;n/N) : ")
if license_validation == "y" or license_validation == "Y":
mailTester(smtp_login, smtp_passwd, server, port, tls, sender, receivers, language,github_username,github_api_key,username,password)
else:
print("\nYou must accept the terms of the license to install and use SECMON.")
exit()
else:
mailTester(smtp_login, smtp_passwd, server, port, tls, sender, receivers, language,github_username,github_api_key,username,password)
main()