Compare commits
10 Commits
9843ca26b9
...
876bb7e8e0
Author | SHA1 | Date | |
---|---|---|---|
![]() |
876bb7e8e0 | ||
e56d161dc2 | |||
c290ec6e18 | |||
![]() |
274b361a63 | ||
c21cdf3c57 | |||
![]() |
725fe43786 | ||
20d15fa8ec | |||
![]() |
5757ec94ca | ||
![]() |
2758b47f5b | ||
1f49ab84e6 |
@ -1,10 +1,40 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
def apache() -> list:
|
def apache_protocols() -> dict:
|
||||||
ssl = list()
|
ssl = dict()
|
||||||
|
|
||||||
# Check if apaches has disabled the bad SSL/TLS version
|
# Check if apaches has disabled the bad SSL/TLS version
|
||||||
|
ssl["description"] = "Disable deprecated SSL/TLS versions"
|
||||||
|
ssl["level"] = "high"
|
||||||
|
ssl["protocols"] = list()
|
||||||
|
# https://httpd.apache.org/docs/trunk/ssl/ssl_howto.html
|
||||||
|
ssl["protocols"].append("TLSv1")
|
||||||
|
ssl["protocols"].append("TLSv1.1")
|
||||||
|
ssl["protocols"].append("SSLv3")
|
||||||
|
ssl["recommand_value"] = "SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1"
|
||||||
|
|
||||||
return ssl
|
return ssl
|
||||||
|
|
||||||
|
def apache_signature() -> dict:
|
||||||
|
signature = dict()
|
||||||
|
|
||||||
|
signature["description"] = "Disable Apache signature"
|
||||||
|
signature["level"] = "high"
|
||||||
|
signature['signature'] = list()
|
||||||
|
signature['signature'].append('ServerSignature On')
|
||||||
|
signature['signature'].append('ServerTokens Prod')
|
||||||
|
|
||||||
|
return signature
|
||||||
|
|
||||||
|
def apache_indexes() -> dict:
|
||||||
|
indexes = dict()
|
||||||
|
|
||||||
|
indexes['description'] = 'Disable files and directory indexes'
|
||||||
|
indexes['level'] = 'medium'
|
||||||
|
indexes['flag'] = 'Options'
|
||||||
|
indexes['options'] = list()
|
||||||
|
indexes['options'].append('Indexes')
|
||||||
|
indexes['options'].append('FollowSymLinks')
|
||||||
|
indexes['recommand_value'] = 'Options -Indexes -FollowSymLinks'
|
||||||
|
|
||||||
|
return indexes
|
||||||
|
@ -5,4 +5,6 @@ def grub() -> dict:
|
|||||||
grub['description'] = 'Change boot permission'
|
grub['description'] = 'Change boot permission'
|
||||||
grub['filename'] = '/boot/grub/grub.cfg'
|
grub['filename'] = '/boot/grub/grub.cfg'
|
||||||
grub['value'] = 0o600
|
grub['value'] = 0o600
|
||||||
|
grub['resolve'] = 'chmod 600 /boot/grub/grub.cfg'
|
||||||
|
grub['level'] = 'medium'
|
||||||
return grub
|
return grub
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
def kernel_va_space() -> list:
|
|
||||||
va = list()
|
|
||||||
sysctl.append({
|
|
||||||
"from": "cis",
|
|
||||||
"id": "",
|
|
||||||
"description": "",
|
|
||||||
"flag": "kernel.randomize_va_space",
|
|
||||||
"value": 2,
|
|
||||||
"level": "medium",
|
|
||||||
})
|
|
||||||
return va
|
|
@ -6,6 +6,7 @@ def profile() -> dict:
|
|||||||
profile['flag'] = 'TMOUT'
|
profile['flag'] = 'TMOUT'
|
||||||
profile['value'] = 600
|
profile['value'] = 600
|
||||||
profile['filename'] = '/etc/profile'
|
profile['filename'] = '/etc/profile'
|
||||||
|
profile['level'] = 'low'
|
||||||
return profile
|
return profile
|
||||||
|
|
||||||
def password_quality() -> list:
|
def password_quality() -> list:
|
||||||
|
@ -214,6 +214,16 @@ def sysctl() -> list:
|
|||||||
"value": 0,
|
"value": 0,
|
||||||
"level": "medium",
|
"level": "medium",
|
||||||
})
|
})
|
||||||
|
# Random VirtualAddress
|
||||||
|
sysctl.append({
|
||||||
|
"from": "cis",
|
||||||
|
"id": "",
|
||||||
|
"description": "Enable random VirtualAddress space for avoiding buffer overflow attacks",
|
||||||
|
"flag": "kernel.randomize_va_space",
|
||||||
|
"value": 2,
|
||||||
|
"level": "medium",
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return sysctl
|
return sysctl
|
||||||
|
@ -30,7 +30,7 @@ def getAllPlugins(audit):
|
|||||||
elif audit == "application":
|
elif audit == "application":
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def main():
|
def main(path):
|
||||||
args = checkArguments()
|
args = checkArguments()
|
||||||
|
|
||||||
if args.plugins is not None:
|
if args.plugins is not None:
|
||||||
@ -56,7 +56,7 @@ def main():
|
|||||||
|
|
||||||
# Get system informations
|
# Get system informations
|
||||||
report['kernel'] = getKernelVersion()
|
report['kernel'] = getKernelVersion()
|
||||||
report['release'] = f"{identifySystem()} {getRelease()} ({getCodeName()}) "
|
report['release'] = f"{identifySystem()} {getRelease()} {getCodeName().strip()}"
|
||||||
|
|
||||||
# Create our dispatcher
|
# Create our dispatcher
|
||||||
dispatcher = Dispatcher()
|
dispatcher = Dispatcher()
|
||||||
@ -76,7 +76,7 @@ def main():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
print("End of the audit. Generating the report")
|
print("End of the audit. Generating the report")
|
||||||
generateHtmlReport(report)
|
generateHtmlReport(path, report)
|
||||||
|
|
||||||
@Dispatcher.register_plugins
|
@Dispatcher.register_plugins
|
||||||
def sysctl(*args) -> dict:
|
def sysctl(*args) -> dict:
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from os import listdir
|
from os import listdir
|
||||||
from os.path import isdir
|
from os.path import isdir, isfile
|
||||||
from audit.system.plugins.apache import apache
|
from audit.system.plugins.apache import apache_protocols, apache_signature, apache_indexes
|
||||||
|
|
||||||
|
|
||||||
class Apache:
|
class Apache:
|
||||||
def __init__(self, arguments):
|
def __init__(self, arguments):
|
||||||
self._objects = apache()
|
self._ssl_versions = apache_protocols()
|
||||||
|
self._signatures = apache_signature()
|
||||||
|
self._indexes = apache_indexes()
|
||||||
self._reports = dict()
|
self._reports = dict()
|
||||||
self._apache_directory = arguments["apache_directory"]
|
self._apache_directory = arguments["apache_directory"]
|
||||||
|
|
||||||
@ -20,22 +22,46 @@ class Apache:
|
|||||||
|
|
||||||
def runAudit(self):
|
def runAudit(self):
|
||||||
print("Running test for Apache")
|
print("Running test for Apache")
|
||||||
self._runParsing()
|
|
||||||
|
# Check if the directory exist
|
||||||
|
path = f"{self._apache_directory}"
|
||||||
|
if isdir(path):
|
||||||
|
self._reports['audit'] = True
|
||||||
|
self._analyzingSslVersion()
|
||||||
|
self._analyzingSignature()
|
||||||
|
self._analyzingIndexes()
|
||||||
|
else:
|
||||||
|
self._reports['audit'] = False
|
||||||
|
self._reports["msg"] = "No directory found"
|
||||||
|
|
||||||
def getReports(self) -> dict:
|
def getReports(self) -> dict:
|
||||||
return self._reports
|
return self._reports
|
||||||
|
|
||||||
def _runParsing(self):
|
################################################
|
||||||
|
# Analyzing SSL
|
||||||
|
################################################
|
||||||
|
def _analyzingSslVersion(self):
|
||||||
# Check if the file exist
|
# Check if the file exist
|
||||||
path = f"{self._apache_directory}/sites-available"
|
path = f"{self._apache_directory}/sites-available"
|
||||||
#if isdir(self._apache_directory):
|
if isdir(path):
|
||||||
# for site in listdir(path):
|
self._reports['ssl']['audit'] = True
|
||||||
# with open(f"{path}/{site}", 'rb') as f:
|
count = 0
|
||||||
# self._parseFile(f)
|
self._reports["ssl"]["virtualhost"] = dict()
|
||||||
#else:
|
for site in listdir(path):
|
||||||
# self._reports["apache"]["test"] = "No directory found"
|
vh = f"{path}/{site}"
|
||||||
|
with open(vh, 'rb') as f:
|
||||||
|
self._parseFileFindingSsl(f, site)
|
||||||
|
count += 1
|
||||||
|
|
||||||
def _parseFile(self, fdata):
|
if count == 0:
|
||||||
|
self._reports['ssl']['audit'] = False
|
||||||
|
self._reports['ssl']['msg'] = \
|
||||||
|
f'No virtual host found in the directory {path}'
|
||||||
|
else:
|
||||||
|
self._reports['ssl']['audit'] = False
|
||||||
|
self._reports['ssl']["msg"] = f"No directory {path} found"
|
||||||
|
|
||||||
|
def _parseFileFindingSsl(self, fdata, virtualhost):
|
||||||
data = fdata.read()
|
data = fdata.read()
|
||||||
lines = data.splitlines()
|
lines = data.splitlines()
|
||||||
|
|
||||||
@ -43,25 +69,220 @@ class Apache:
|
|||||||
line = line.decode('utf-8')
|
line = line.decode('utf-8')
|
||||||
|
|
||||||
# check if SSL is enable for the VirtualHost
|
# check if SSL is enable for the VirtualHost
|
||||||
grSSLEngine = re.search("SSLEngine on", line)
|
# (?#) -> remove commentary
|
||||||
|
# (\s) -> remove space and tabulation
|
||||||
|
grSSLEngine = re.search(
|
||||||
|
"(?#)(\s)SSLEngine on",
|
||||||
|
line,
|
||||||
|
re.IGNORECASE
|
||||||
|
)
|
||||||
if grSSLEngine:
|
if grSSLEngine:
|
||||||
print(line)
|
report = self._check_ssl_version(lines)
|
||||||
|
|
||||||
def _check_value_exist(self, line, value) -> bool:
|
self._reports["ssl"]["virtualhost"][virtualhost] = report
|
||||||
grValue = re.search(value, line)
|
|
||||||
if grValue:
|
def _check_ssl_version(self, lines) -> dict:
|
||||||
return True
|
report = dict()
|
||||||
return False
|
findProtocol = False
|
||||||
|
protocolsFound = list()
|
||||||
|
for line in lines:
|
||||||
|
line = line.decode("utf-8")
|
||||||
|
|
||||||
|
grSSLProtocol = re.search(
|
||||||
|
"(?#)(\s)SSLProtocol",
|
||||||
|
line,
|
||||||
|
re.IGNORECASE
|
||||||
|
)
|
||||||
|
if grSSLProtocol:
|
||||||
|
for protocol in self._ssl_versions["protocols"]:
|
||||||
|
grProtocol = re.search(f"-{protocol}", line)
|
||||||
|
if grProtocol:
|
||||||
|
protocolsFound.append(protocol)
|
||||||
|
|
||||||
|
if len(self._ssl_versions["protocols"]) == len(protocolsFound):
|
||||||
|
report["result"] = "success"
|
||||||
|
else:
|
||||||
|
report["msg"] = list()
|
||||||
|
report["result"] = "failed"
|
||||||
|
for proto in self._ssl_versions["protocols"]:
|
||||||
|
if proto not in protocolsFound:
|
||||||
|
report["msg"].append(
|
||||||
|
f"{proto} need to be disabled"
|
||||||
|
)
|
||||||
|
|
||||||
|
report["description"] = \
|
||||||
|
self._ssl_versions["description"]
|
||||||
|
report["level"] = self._ssl_versions["level"]
|
||||||
|
report["recommand_value"] = \
|
||||||
|
self._ssl_versions["recommand_value"]
|
||||||
|
return report
|
||||||
|
|
||||||
|
################################################
|
||||||
|
# Analyzing Signature
|
||||||
|
################################################
|
||||||
|
def _analyzingSignature(self):
|
||||||
|
# Check if the apache2.conf exist
|
||||||
|
path = f"{self._apache_directory}/apache2.conf"
|
||||||
|
if isfile(path):
|
||||||
|
self._reports["signature"]["audit"] = True
|
||||||
|
|
||||||
|
with open(path, 'rb') as fdata:
|
||||||
|
self._reports["signature"]["signature"] = \
|
||||||
|
self._parsingApacheConfigForSignature(fdata)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self._reports["signature"]["audit"] = False
|
||||||
|
self._reports["signature"]["msg"] = \
|
||||||
|
f"The file {path} do not exist"
|
||||||
|
|
||||||
|
def _parsingApacheConfigForSignature(self, fdata) -> dict:
|
||||||
|
report = dict()
|
||||||
|
data = fdata.read()
|
||||||
|
lines = data.splitlines()
|
||||||
|
|
||||||
|
for signature in self._signatures["signature"]:
|
||||||
|
report[signature] = dict()
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
line = line.decode('utf-8')
|
||||||
|
|
||||||
|
for signature in self._signatures["signature"]:
|
||||||
|
grSignature = re.search(
|
||||||
|
f"(?#){signature}",
|
||||||
|
line,
|
||||||
|
re.IGNORECASE
|
||||||
|
)
|
||||||
|
if grSignature:
|
||||||
|
# It's not a comment
|
||||||
|
if '#' not in line:
|
||||||
|
report[signature]["audit"] = True
|
||||||
|
report[signature]["result"] = "success"
|
||||||
|
report[signature]["description"] = self._signatures["description"]
|
||||||
|
report[signature]["level"] = self._signatures["level"]
|
||||||
|
|
||||||
|
for signature in report:
|
||||||
|
if len(report[signature]) == 0:
|
||||||
|
report[signature]["audit"] = True
|
||||||
|
report[signature]["result"] = "failed"
|
||||||
|
report[signature]["recommand_value"] = signature
|
||||||
|
report[signature]["description"] = self._signatures["description"]
|
||||||
|
report[signature]["level"] = self._signatures["level"]
|
||||||
|
|
||||||
|
return report
|
||||||
|
|
||||||
|
################################################
|
||||||
|
# Analyzing Indexes
|
||||||
|
################################################
|
||||||
|
def _analyzingIndexes(self):
|
||||||
|
# Check if the apache2.conf exist
|
||||||
|
path = f"{self._apache_directory}/apache2.conf"
|
||||||
|
if isfile(path):
|
||||||
|
self._reports["indexes"]["audit"] = True
|
||||||
|
|
||||||
|
with open(path, 'rb') as fdata:
|
||||||
|
self._reports["indexes"] = \
|
||||||
|
self._parsingApacheConfig(fdata)
|
||||||
|
else:
|
||||||
|
self._reports["indexes"]["audit"] = False
|
||||||
|
self._reports["indexes"]["msg"] = \
|
||||||
|
f"The file {path} do not exist"
|
||||||
|
|
||||||
|
def _parsingApacheConfig(self, fdata) -> dict:
|
||||||
|
report = dict()
|
||||||
|
report["directories"] = dict()
|
||||||
|
data = fdata.read()
|
||||||
|
lines = data.splitlines()
|
||||||
|
# Each entry in the variable directories contains a list
|
||||||
|
# of <Directory> with all data in it
|
||||||
|
# We create another entry when a found </Directory>
|
||||||
|
directories = dict()
|
||||||
|
directoryFound = False
|
||||||
|
index = 0
|
||||||
|
optsFound = list()
|
||||||
|
currentPath = None
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
line = line.decode('utf-8')
|
||||||
|
|
||||||
|
# Find a <Directory
|
||||||
|
if not directoryFound:
|
||||||
|
grDirectory = re.search("<Directory ", line, re.IGNORECASE)
|
||||||
|
if grDirectory:
|
||||||
|
directoryFound = True
|
||||||
|
currentPath = self._getDirectoryPath(line)
|
||||||
|
directories[currentPath] = list()
|
||||||
|
directories[currentPath].append(line)
|
||||||
|
else:
|
||||||
|
directories[currentPath].append(line)
|
||||||
|
grDirectory = re.search("</Directory>", line, re.IGNORECASE)
|
||||||
|
if grDirectory:
|
||||||
|
directoryFound = False
|
||||||
|
index += 1
|
||||||
|
currentPath = None
|
||||||
|
|
||||||
|
# We will find if we find an indexes option
|
||||||
|
for directory in directories:
|
||||||
|
report["directories"][directory] = dict()
|
||||||
|
report["directories"][directory]["options"] = list()
|
||||||
|
|
||||||
|
for line in directories[directory]:
|
||||||
|
grFlag = re.search(
|
||||||
|
f"{self._indexes['flag']}",
|
||||||
|
line,
|
||||||
|
re.IGNORECASE
|
||||||
|
)
|
||||||
|
if grFlag:
|
||||||
|
for opt in self._indexes['options']:
|
||||||
|
grOption = re.search(
|
||||||
|
f"-{opt}",
|
||||||
|
line,
|
||||||
|
re.IGNORECASE
|
||||||
|
)
|
||||||
|
if grOption:
|
||||||
|
optsFound.append(opt)
|
||||||
|
|
||||||
|
# We can check if you found the options
|
||||||
|
if len(optsFound) == len(self._indexes['options']):
|
||||||
|
report["directories"][directory]["result"] = "success"
|
||||||
|
else:
|
||||||
|
report["directories"][directory]["result"] = "failed"
|
||||||
|
for opt in self._indexes["options"]:
|
||||||
|
if opt not in optsFound:
|
||||||
|
report["directories"][directory]["options"].append(
|
||||||
|
f"{opt} is not removed. You should disable it"
|
||||||
|
)
|
||||||
|
optsFound.clear()
|
||||||
|
|
||||||
|
report["audit"] = True
|
||||||
|
report["description"] = self._indexes["description"]
|
||||||
|
report["level"] = self._indexes["level"]
|
||||||
|
report["recommand_value"] = self._indexes["recommand_value"]
|
||||||
|
return report
|
||||||
|
|
||||||
|
def _getDirectoryPath(self, line) -> str:
|
||||||
|
"""
|
||||||
|
This function return the directory path
|
||||||
|
"""
|
||||||
|
path = None
|
||||||
|
grDirectory = re.search(
|
||||||
|
f"<Directory",
|
||||||
|
line,
|
||||||
|
re.IGNORECASE
|
||||||
|
)
|
||||||
|
if grDirectory:
|
||||||
|
path = line.replace("<Directory", "")
|
||||||
|
path = path.replace(">", "")
|
||||||
|
path = path.replace("\"", "")
|
||||||
|
return path
|
||||||
|
|
||||||
def _constructReports(self):
|
def _constructReports(self):
|
||||||
"""
|
"""
|
||||||
Construct dictionary for result of the tests
|
Construct dictionary for result of the tests
|
||||||
Each entry contains:
|
Each entry contains:
|
||||||
Key:
|
Key:
|
||||||
- filename: filename of the test
|
|
||||||
- line: line of the test
|
|
||||||
- parse: Display the line where the vulnerabilites has been found
|
|
||||||
- description: description of the vulnerability
|
- description: description of the vulnerability
|
||||||
- level: high, medium or low
|
- level: high, medium or low
|
||||||
"""
|
"""
|
||||||
self._reports['apache'] = dict()
|
self._reports['ssl'] = dict()
|
||||||
|
self._reports['signature'] = dict()
|
||||||
|
self._reports['indexes'] = dict()
|
||||||
|
@ -29,10 +29,12 @@ class Grub:
|
|||||||
|
|
||||||
if permission != oct(self._object['value']):
|
if permission != oct(self._object['value']):
|
||||||
self._reports['result'] = 'failed'
|
self._reports['result'] = 'failed'
|
||||||
|
self._reports['resolve'] = self._object['resolve']
|
||||||
else:
|
else:
|
||||||
self._reports['result'] = 'success'
|
self._reports['result'] = 'success'
|
||||||
self._reports['description'] = self._object['description']
|
self._reports['description'] = self._object['description']
|
||||||
self._reports['recommand_value'] = self._object['value']
|
self._reports['level'] = self._object['level']
|
||||||
|
self._reports['current_value'] = permission[2:]
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self._reports['grub']['error'] = \
|
self._reports['grub']['error'] = \
|
||||||
f'File {path} not found'
|
f'File {path} not found'
|
||||||
|
@ -50,12 +50,14 @@ class LocalAccount:
|
|||||||
self._reports['profile']['vulnerabilities'] = dict()
|
self._reports['profile']['vulnerabilities'] = dict()
|
||||||
self._reports['profile']['vulnerabilities'][self._profile['flag']] = dict()
|
self._reports['profile']['vulnerabilities'][self._profile['flag']] = dict()
|
||||||
self._reports['profile']['vulnerabilities'][self._profile['flag']]["result"] = "success"
|
self._reports['profile']['vulnerabilities'][self._profile['flag']]["result"] = "success"
|
||||||
|
self._reports['profile']['vulnerabilities'][self._profile['flag']]['level'] = self._profile['level']
|
||||||
self._reports['profile']['vulnerabilities'][self._profile['flag']]["description"] = self._profile['description']
|
self._reports['profile']['vulnerabilities'][self._profile['flag']]["description"] = self._profile['description']
|
||||||
self._reports['profile']['vulnerabilities'][self._profile['flag']]["flagFound"] = lineFound
|
self._reports['profile']['vulnerabilities'][self._profile['flag']]["flagFound"] = lineFound
|
||||||
else:
|
else:
|
||||||
self._reports['profile']['vulnerabilities'] = dict()
|
self._reports['profile']['vulnerabilities'] = dict()
|
||||||
self._reports['profile']['vulnerabilities'][self._profile['flag']] = dict()
|
self._reports['profile']['vulnerabilities'][self._profile['flag']] = dict()
|
||||||
self._reports['profile']['vulnerabilities'][self._profile['flag']]["result"] = "failed"
|
self._reports['profile']['vulnerabilities'][self._profile['flag']]["result"] = "failed"
|
||||||
|
self._reports['profile']['vulnerabilities'][self._profile['flag']]['level'] = self._profile['level']
|
||||||
self._reports['profile']['vulnerabilities'][self._profile["flag"]]["recommand_value"] = self._profile["value"]
|
self._reports['profile']['vulnerabilities'][self._profile["flag"]]["recommand_value"] = self._profile["value"]
|
||||||
self._reports['profile']['vulnerabilities'][self._profile['flag']]["description"] = self._profile['description']
|
self._reports['profile']['vulnerabilities'][self._profile['flag']]["description"] = self._profile['description']
|
||||||
self._reports['profile']['vulnerabilities'][self._profile['flag']]["flag"] = self._profile['flag']
|
self._reports['profile']['vulnerabilities'][self._profile['flag']]["flag"] = self._profile['flag']
|
||||||
|
@ -56,11 +56,13 @@ class Postfix:
|
|||||||
if res:
|
if res:
|
||||||
self._reports["postfix"][obj['flag']] = dict()
|
self._reports["postfix"][obj['flag']] = dict()
|
||||||
self._reports["postfix"][obj['flag']]["result"] = "success"
|
self._reports["postfix"][obj['flag']]["result"] = "success"
|
||||||
|
self._reports["postfix"][obj['flag']]["level"] = obj['level']
|
||||||
self._reports["postfix"][obj['flag']]["description"] = obj['description']
|
self._reports["postfix"][obj['flag']]["description"] = obj['description']
|
||||||
self._reports["postfix"][obj['flag']]["flagFound"] = line
|
self._reports["postfix"][obj['flag']]["flagFound"] = line
|
||||||
else:
|
else:
|
||||||
self._reports["postfix"][obj['flag']] = dict()
|
self._reports["postfix"][obj['flag']] = dict()
|
||||||
self._reports["postfix"][obj['flag']]["result"] = "failed"
|
self._reports["postfix"][obj['flag']]["result"] = "failed"
|
||||||
|
self._reports["postfix"][obj['flag']]["level"] = obj['level']
|
||||||
self._reports["postfix"][obj["flag"]]["recommand_value"] = obj["value"]
|
self._reports["postfix"][obj["flag"]]["recommand_value"] = obj["value"]
|
||||||
self._reports["postfix"][obj['flag']]["description"] = obj['description']
|
self._reports["postfix"][obj['flag']]["description"] = obj['description']
|
||||||
self._reports["postfix"][obj['flag']]["flag"] = obj['flag']
|
self._reports["postfix"][obj['flag']]["flag"] = obj['flag']
|
||||||
|
@ -4,8 +4,8 @@ from datetime import datetime
|
|||||||
import jinja2
|
import jinja2
|
||||||
|
|
||||||
|
|
||||||
def generateHtmlReport(data):
|
def generateHtmlReport(path, data):
|
||||||
today = datetime.now().isoformat()[0:10].replace("-", "_")
|
today = datetime.now().isoformat()[0:10]
|
||||||
dataJinja2 = dict()
|
dataJinja2 = dict()
|
||||||
dataJinja2['title'] = 'Report check system'
|
dataJinja2['title'] = 'Report check system'
|
||||||
dataJinja2['plugins'] = list()
|
dataJinja2['plugins'] = list()
|
||||||
@ -20,7 +20,6 @@ def generateHtmlReport(data):
|
|||||||
|
|
||||||
body = str()
|
body = str()
|
||||||
for plugin in data['system']:
|
for plugin in data['system']:
|
||||||
#print(plugin)
|
|
||||||
dataJinja2['plugins'].append(f"{plugin}.html.j2")
|
dataJinja2['plugins'].append(f"{plugin}.html.j2")
|
||||||
|
|
||||||
if 'postfix' in data['system']:
|
if 'postfix' in data['system']:
|
||||||
@ -39,7 +38,24 @@ def generateHtmlReport(data):
|
|||||||
_generateAccordion(dataJinja2['sysctl']['file']['sysctl'], 'sysctl')
|
_generateAccordion(dataJinja2['sysctl']['file']['sysctl'], 'sysctl')
|
||||||
|
|
||||||
if 'apache' in data['system']:
|
if 'apache' in data['system']:
|
||||||
pass
|
dataJinja2['apache'] = data['system']['apache']
|
||||||
|
|
||||||
|
if data['system']['apache']['audit']:
|
||||||
|
if data['system']['apache']['ssl']['audit']:
|
||||||
|
_generateAccordion(
|
||||||
|
dataJinja2["apache"]["ssl"]["virtualhost"],
|
||||||
|
"apache-virtualhost"
|
||||||
|
)
|
||||||
|
if data['system']['apache']['signature']['audit']:
|
||||||
|
_generateAccordion(
|
||||||
|
dataJinja2["apache"]["signature"]["signature"],
|
||||||
|
"apache-signature"
|
||||||
|
)
|
||||||
|
if data['system']['apache']['indexes']['audit']:
|
||||||
|
_generateAccordion(
|
||||||
|
dataJinja2["apache"]["indexes"]["directories"],
|
||||||
|
"apache-indexes"
|
||||||
|
)
|
||||||
|
|
||||||
if 'localaccount' in data['system']:
|
if 'localaccount' in data['system']:
|
||||||
if 'profile' in data['system']['localaccount']:
|
if 'profile' in data['system']['localaccount']:
|
||||||
@ -53,8 +69,6 @@ def generateHtmlReport(data):
|
|||||||
if 'grub' in data['system']:
|
if 'grub' in data['system']:
|
||||||
dataJinja2['grub'] = data['system']['grub']
|
dataJinja2['grub'] = data['system']['grub']
|
||||||
dataJinja2['grub']['accordion-id'] = f"accordion-grub-1"
|
dataJinja2['grub']['accordion-id'] = f"accordion-grub-1"
|
||||||
#_generateAccordion(dataJinja2['grub'], 'grub')
|
|
||||||
print(dataJinja2['grub'])
|
|
||||||
|
|
||||||
dataJinja2['year'] = '2023'
|
dataJinja2['year'] = '2023'
|
||||||
dataJinja2['hostname'] = data['hostname']
|
dataJinja2['hostname'] = data['hostname']
|
||||||
@ -62,11 +76,12 @@ def generateHtmlReport(data):
|
|||||||
dataJinja2['release'] = data['release']
|
dataJinja2['release'] = data['release']
|
||||||
rdr = tmplIndex.render(data=dataJinja2)
|
rdr = tmplIndex.render(data=dataJinja2)
|
||||||
|
|
||||||
with open(f"reports/reports_{today}.html", "w") as f:
|
hostname = data['hostname'].lower()
|
||||||
|
with open(f"{path}/reports/reports_{hostname}_{today}.html", "w") as f:
|
||||||
f.write(rdr)
|
f.write(rdr)
|
||||||
|
|
||||||
print("The report is generated at this location: " \
|
print("The report is generated at this location: " \
|
||||||
f"reports/reports_{today}.html")
|
f"reports/reports_{hostname}_{today}.html")
|
||||||
|
|
||||||
def _generateAccordion(obj, parent):
|
def _generateAccordion(obj, parent):
|
||||||
index = 1
|
index = 1
|
||||||
|
35
issues.py
35
issues.py
@ -1,35 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
class Issues:
|
|
||||||
OS = ['Debian', 'Ubuntu', 'Redhat']
|
|
||||||
CATEGORY = ['cve', 'cis']
|
|
||||||
|
|
||||||
def __init__(self, alias, os, severity, priority, component, description, category):
|
|
||||||
self._alias = alias # CVE-xxxx-yyyy
|
|
||||||
self._os = os
|
|
||||||
self._severity = severity
|
|
||||||
self._priority = priority
|
|
||||||
self._component = component
|
|
||||||
self._description = description
|
|
||||||
self._category = category
|
|
||||||
|
|
||||||
def getAlias(self) -> str:
|
|
||||||
return self._alias
|
|
||||||
|
|
||||||
def getOs(self) -> str:
|
|
||||||
return self._os
|
|
||||||
|
|
||||||
def getSeverity(self) -> str:
|
|
||||||
return self._severity
|
|
||||||
|
|
||||||
def getPriority(self) -> str:
|
|
||||||
return self._priority
|
|
||||||
|
|
||||||
def getComponent(self) -> str:
|
|
||||||
return self._component
|
|
||||||
|
|
||||||
def getDescription(self) -> str:
|
|
||||||
return self._description
|
|
||||||
|
|
||||||
def getCategory(self) -> str:
|
|
||||||
return self._category
|
|
4
main.py
4
main.py
@ -1,7 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from core.main import main
|
from core.main import main
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
path = f"{os.path.dirname(__file__)}"
|
||||||
|
main(path)
|
||||||
|
118
old_main.py
118
old_main.py
@ -1,118 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import re
|
|
||||||
from os import path
|
|
||||||
from subprocess import call, check_output, run
|
|
||||||
|
|
||||||
|
|
||||||
# 3 levels to tests: low, medium anh high
|
|
||||||
CHECKSLIST = {}
|
|
||||||
|
|
||||||
# TIPS
|
|
||||||
# https://www.process.st/server-security/
|
|
||||||
|
|
||||||
def identifySystem():
|
|
||||||
os = None
|
|
||||||
with open('/etc/issue', 'r') as f:
|
|
||||||
line = f.readline()
|
|
||||||
if re.search('Arch Linux', line):
|
|
||||||
os = 'ARCHLINUX'
|
|
||||||
elif re.search('Ubuntu', line):
|
|
||||||
os = 'UBUNTU'
|
|
||||||
elif re.search('Debian', line):
|
|
||||||
os = 'DEBIAN'
|
|
||||||
else:
|
|
||||||
os = 'UNKNOWN'
|
|
||||||
|
|
||||||
return os
|
|
||||||
|
|
||||||
def check_upgrade_packages():
|
|
||||||
pass
|
|
||||||
|
|
||||||
def check_telnet_is_open():
|
|
||||||
# check port 23 is listening
|
|
||||||
r = run(['ss', '-atn'], capture_output=True)
|
|
||||||
r = r.stdout.decode()
|
|
||||||
print(r)
|
|
||||||
|
|
||||||
def check_empty_local_passwords():
|
|
||||||
pass
|
|
||||||
|
|
||||||
def check_security_access():
|
|
||||||
# Check in /etc/security/access
|
|
||||||
pass
|
|
||||||
|
|
||||||
def check_hosts_allow():
|
|
||||||
# Check in /etc/hosts.allow
|
|
||||||
pass
|
|
||||||
|
|
||||||
def check_sshd_root():
|
|
||||||
res = False
|
|
||||||
|
|
||||||
if not path.exists("/etc/ssh/sshd_config"):
|
|
||||||
print("File sshd_config doesn't exist")
|
|
||||||
return False
|
|
||||||
|
|
||||||
with open("/etc/ssh/sshd_config", "r") as f:
|
|
||||||
for l in f.readlines():
|
|
||||||
l = l.replace('\n', '')
|
|
||||||
if re.search("PermitRootLogin.*root", l):
|
|
||||||
if not re.search("^#", l):
|
|
||||||
res = True
|
|
||||||
return res
|
|
||||||
|
|
||||||
def generateChecksList():
|
|
||||||
# LOW
|
|
||||||
CHECKSLIST['low'] = []
|
|
||||||
CHECKSLIST['low'].append({
|
|
||||||
'callback': check_sshd_root,
|
|
||||||
'name': check_sshd_root.__name__,
|
|
||||||
'resolution': 'Please, remove root auth to your server',
|
|
||||||
'score': 100
|
|
||||||
})
|
|
||||||
CHECKSLIST['low'].append({
|
|
||||||
'callback': check_upgrade_packages,
|
|
||||||
'name': check_upgrade_packages.__name__,
|
|
||||||
'resolution': 'Please, upgrade your packages',
|
|
||||||
'score': 50
|
|
||||||
})
|
|
||||||
CHECKSLIST['low'].append({
|
|
||||||
'callback': check_telnet_is_open,
|
|
||||||
'name': check_telnet_is_open.__name__,
|
|
||||||
'resolution': 'Telnet is enabled. Please, disabled this program if you could.',
|
|
||||||
'score': 50
|
|
||||||
})
|
|
||||||
# MEDIUM
|
|
||||||
CHECKSLIST['medium'] = {}
|
|
||||||
# HIGH
|
|
||||||
CHECKSLIST['high'] = {}
|
|
||||||
|
|
||||||
def getTotalScore():
|
|
||||||
score = 0
|
|
||||||
for entry in CHECKSLIST['low']:
|
|
||||||
score += entry['score']
|
|
||||||
|
|
||||||
return score
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Generate our checklist
|
|
||||||
generateChecksList()
|
|
||||||
|
|
||||||
# Get total score
|
|
||||||
totalScore = getTotalScore()
|
|
||||||
|
|
||||||
# Identify system
|
|
||||||
identifySystem()
|
|
||||||
|
|
||||||
score = totalScore
|
|
||||||
for entry in CHECKSLIST['low']:
|
|
||||||
print(f'Checking {entry["name"]}...')
|
|
||||||
res = entry['callback']()
|
|
||||||
if res:
|
|
||||||
print(entry['resolution'])
|
|
||||||
score -= entry['score']
|
|
||||||
|
|
||||||
print(f'Your total score: {score}')
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
48
reports/templates/apache-indexes.html.j2
Normal file
48
reports/templates/apache-indexes.html.j2
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{% if data["apache"]["indexes"]["audit"] %}
|
||||||
|
{% for item in data['apache']['indexes']['directories'] %}
|
||||||
|
<div class="accordion" id="accordionApacheIndexes">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['apache']['indexes']['directories'][item]['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['apache']['indexes']['directories'][item]['accordion-id'] }}">
|
||||||
|
<strong>Directory {{ item }}</strong>
|
||||||
|
{% if data['apache']['indexes']['directories'][item]['result'] == 'failed' %}
|
||||||
|
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['indexes']['directories'][item]['result'] }}</span>
|
||||||
|
{% elif data['apache']['indexes']['directories'][item]['result'] == 'success' %}
|
||||||
|
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['indexes']['directories'][item]['result'] }}</span>
|
||||||
|
{% endif %}
|
||||||
|
<span class="text-bg-primary p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['indexes']['level'] }}</span>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="{{ data['apache']['indexes']['directories'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionApacheIndexes">
|
||||||
|
<div class="accordion-body">
|
||||||
|
{{ data['apache']['indexes']['description'] }}. <br />
|
||||||
|
{% if data['apache']['indexes']["directories"][item]['result'] == 'failed' %}
|
||||||
|
Result of the audit:
|
||||||
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
|
<div class="highlight">
|
||||||
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
|
{% for indexes in data['apache']['indexes']["directories"][item]['options'] %}
|
||||||
|
{{ indexes }}
|
||||||
|
{% endfor %}
|
||||||
|
</pre></code>
|
||||||
|
</div> <!-- end .highlight -->
|
||||||
|
</div> <!-- end .bd-code-snippet -->
|
||||||
|
|
||||||
|
For resolving the issue, add this line in the apache config file:
|
||||||
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
|
<div class="highlight">
|
||||||
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
|
{{ data['apache']['indexes']['recommand_value'] }}
|
||||||
|
</pre></code>
|
||||||
|
</div> <!-- end .highlight -->
|
||||||
|
</div> <!-- end .bd-code-snippet -->
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div> <!-- end .accordion-body -->
|
||||||
|
</div> <!-- end .accordion-collapse -->
|
||||||
|
</div> <!-- end .accordion-item -->
|
||||||
|
</div> <!-- end .accordion -->
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{ data['apache']['indexes']['msg'] }}
|
||||||
|
{% endif %}
|
38
reports/templates/apache-signature.html.j2
Normal file
38
reports/templates/apache-signature.html.j2
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{% if data['apache']['signature']['audit'] %}
|
||||||
|
{% for item in data['apache']['signature']['signature'] %}
|
||||||
|
<div class="accordion" id="accordionApacheSignature">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['apache']['signature']['signature'][item]['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['apache']['signature']['signature'][item]['accordion-id'] }}">
|
||||||
|
<strong>VirtualHost {{ item }}</strong>
|
||||||
|
{% if data['apache']['signature']['signature'][item]['result'] == 'failed' %}
|
||||||
|
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['signature']['signature'][item]['result'] }}</span>
|
||||||
|
{% elif data['apache']['signature']['signature'][item]['result'] == 'success' %}
|
||||||
|
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['signature']['signature'][item]['result'] }}</span>
|
||||||
|
{% endif %}
|
||||||
|
<span class="text-bg-primary p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['signature']['signature'][item]['level'] }}</span>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="{{ data['apache']['signature']['signature'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionApacheSignature">
|
||||||
|
<div class="accordion-body">
|
||||||
|
{{ data['apache']['signature']['signature'][item]['description'] }}. <br />
|
||||||
|
{% if data['apache']['signature']['signature'][item]['result'] == 'failed' %}
|
||||||
|
For resolving the issue, add this line in the VirtualHost file:
|
||||||
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
|
<div class="highlight">
|
||||||
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
|
{{ data['apache']['signature']['signature'][item]['recommand_value'] }}
|
||||||
|
</pre></code>
|
||||||
|
</div> <!-- end .highlight -->
|
||||||
|
</div> <!-- end .bd-code-snippet -->
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div> <!-- end .accordion-body -->
|
||||||
|
</div> <!-- end .accordion-collapse -->
|
||||||
|
</div> <!-- end .accordion-item -->
|
||||||
|
</div> <!-- end .accordion -->
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
{{ data['apache']['signature']['msg'] }}
|
||||||
|
{% endif %}
|
48
reports/templates/apache-ssl.html.j2
Normal file
48
reports/templates/apache-ssl.html.j2
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{% if data["apache"]["ssl"]["audit"] %}
|
||||||
|
{% for item in data['apache']['ssl']['virtualhost'] %}
|
||||||
|
<div class="accordion" id="accordionApacheSsl">
|
||||||
|
<div class="accordion-item">
|
||||||
|
<h2 class="accordion-header">
|
||||||
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['apache']['ssl']['virtualhost'][item]['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['apache']['ssl']['virtualhost'][item]['accordion-id'] }}">
|
||||||
|
<strong>VirtualHost {{ item }}</strong>
|
||||||
|
{% if data['apache']['ssl']['virtualhost'][item]['result'] == 'failed' %}
|
||||||
|
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['ssl']['virtualhost'][item]['result'] }}</span>
|
||||||
|
{% elif data['apache']['ssl']['virtualhost'][item]['result'] == 'success' %}
|
||||||
|
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['ssl']['virtualhost'][item]['result'] }}</span>
|
||||||
|
{% endif %}
|
||||||
|
<span class="text-bg-primary p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['apache']['ssl']['virtualhost'][item]['level'] }}</span>
|
||||||
|
</button>
|
||||||
|
</h2>
|
||||||
|
<div id="{{ data['apache']['ssl']['virtualhost'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionApacheSsl">
|
||||||
|
<div class="accordion-body">
|
||||||
|
{{ data['apache']['ssl']['virtualhost'][item]['description'] }}. <br />
|
||||||
|
{% if data['apache']['ssl']['virtualhost'][item]['result'] == 'failed' %}
|
||||||
|
Result of the audit:
|
||||||
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
|
<div class="highlight">
|
||||||
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
|
{% for protocol in data['apache']['ssl']['virtualhost'][item]['msg'] %}
|
||||||
|
{{ protocol }}
|
||||||
|
{% endfor %}
|
||||||
|
</pre></code>
|
||||||
|
</div> <!-- end .highlight -->
|
||||||
|
</div> <!-- end .bd-code-snippet -->
|
||||||
|
|
||||||
|
For resolving the issue, add this line in the VirtualHost file:
|
||||||
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
|
<div class="highlight">
|
||||||
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
|
{{ data['apache']['ssl']['virtualhost'][item]['recommand_value'] }}
|
||||||
|
</pre></code>
|
||||||
|
</div> <!-- end .highlight -->
|
||||||
|
</div> <!-- end .bd-code-snippet -->
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div> <!-- end .accordion-body -->
|
||||||
|
</div> <!-- end .accordion-collapse -->
|
||||||
|
</div> <!-- end .accordion-item -->
|
||||||
|
</div> <!-- end .accordion -->
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
{{ data['apache']['ssl']['msg'] }}
|
||||||
|
{% endif %}
|
@ -1,43 +1,19 @@
|
|||||||
<h3 class="fs-3">Apache</h3>
|
<h3 class="fs-3">Apache</h3>
|
||||||
|
|
||||||
{% for item in data['postfix']['vulnerabilities'] %}
|
{% if data['apache']['audit'] %}
|
||||||
<div class="accordion" id="accordionSysctl">
|
<h5 class="fs-5">SSL</h5>
|
||||||
<div class="accordion-item">
|
{% include 'apache-ssl.html.j2' %}
|
||||||
<h2 class="accordion-header">
|
|
||||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}">
|
<div style="margin-bottom: 15pt"></div>
|
||||||
<strong>{{ item }}</strong>
|
|
||||||
{% if data['postfix']['vulnerabilities'][item]['result'] == 'failed' %}
|
<h5 class="fs-5">Signature</h5>
|
||||||
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['postfix']['vulnerabilities'][item]['result'] }}</span>
|
{% include 'apache-signature.html.j2' %}
|
||||||
{% elif data['postfix']['vulnerabilities'][item]['result'] == 'success' %}
|
|
||||||
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['postfix']['vulnerabilities'][item]['result'] }}</span>
|
<div style="margin-bottom: 15pt"></div>
|
||||||
{% endif %}
|
|
||||||
</button>
|
<h5 class="fs-5">Indexes</h5>
|
||||||
</h2>
|
{% include 'apache-indexes.html.j2' %}
|
||||||
<div id="{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionApache">
|
|
||||||
<div class="accordion-body">
|
{% else %}
|
||||||
{{ data['postfix']['vulnerabilities'][item]['description'] }}. <br />
|
{{ data['apache']['msg'] }}
|
||||||
{% if data['postfix']['vulnerabilities'][item]['result'] == 'success' %}
|
{% endif %}
|
||||||
<div class="bd-example-snippet bd-code-snippet">
|
|
||||||
<div class="highlight">
|
|
||||||
<pre tabindex="0" class="chroma"><code class="language-shell">
|
|
||||||
{{ data['postfix']['vulnerabilities'][item]['flagFound'] }}
|
|
||||||
</pre></code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
For resolving the issue, add this line in the <strong>{{ data['postfix']['filename'] }}</strong> vulnerabilities:
|
|
||||||
<div class="bd-example-snippet bd-code-snippet">
|
|
||||||
<div class="highlight">
|
|
||||||
<pre tabindex="0" class="chroma"><code class="language-shell">
|
|
||||||
{% for value in data['postfix']['vulnerabilities'][item]['recommand_value'] %}
|
|
||||||
{{ data['postfix']['vulnerabilities'][item]['flag'] }} = {{ value }}
|
|
||||||
{% endfor %}
|
|
||||||
</pre></code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
@ -1,39 +1,46 @@
|
|||||||
<h3 class="fs-3">Grub</h3>
|
<h3 class="fs-3">Grub</h3>
|
||||||
|
|
||||||
<div class="accordion" id="accordionSysctl">
|
<div class="accordion" id="accordionGrub">
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header">
|
<h2 class="accordion-header">
|
||||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['grub']['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['grub']['accordion-id'] }}">
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['grub']['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['grub']['accordion-id'] }}">
|
||||||
<strong>Grub</strong>
|
<strong>Grub</strong>
|
||||||
{% if data['grub']['result'] == 'failed' %}
|
{% if data['grub']['result'] == 'failed' %}
|
||||||
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['grub']['result'] }}</span>
|
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['grub']['result'] }}</span>
|
||||||
{% elif data['grub']['result'] == 'success' %}
|
{% elif data['grub']['result'] == 'success' %}
|
||||||
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['grub']['result'] }}</span>
|
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['grub']['result'] }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<span class="text-bg-primary p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['grub']['level'] }}</span>
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div id="{{ data['grub']['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionGrub">
|
<div id="{{ data['grub']['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionGrub">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
{{ data['grub']['description'] }}. <br />
|
{{ data['grub']['description'] }}. <br />
|
||||||
{% if data['grub']['result'] == 'success' %}
|
{% if data['grub']['result'] == 'success' %}
|
||||||
<div class="bd-example-snippet bd-code-snippet">
|
Your current permission of this file:
|
||||||
<div class="highlight">
|
|
||||||
<pre tabindex="0" class="chroma"><code class="language-shell">
|
|
||||||
{{ data['grub']['recommand_value'] }}
|
|
||||||
</pre></code>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
For resolving the issue, add this line in the <strong>{{ data['filename'] }}</strong> profile:
|
|
||||||
<div class="bd-example-snippet bd-code-snippet">
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
<div class="highlight">
|
<div class="highlight">
|
||||||
<pre tabindex="0" class="chroma"><code class="language-shell">
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
{{ data['grub']['recommand_value'] }}
|
{{ data['grub']['current_value'] }}
|
||||||
</pre></code>
|
</pre></code>
|
||||||
</div>
|
</div> <!-- end .highlight -->
|
||||||
</div>
|
</div> <!-- end .bd-code-snippet -->
|
||||||
|
{% else %}
|
||||||
|
For resolving the issue, change the permission of the file:
|
||||||
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
|
<div class="highlight">
|
||||||
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
|
{{ data['grub']['resolve'] }}
|
||||||
|
</pre></code>
|
||||||
|
</div> <!-- end highlight -->
|
||||||
|
</div> <!-- end bd-code-snippet -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
|
||||||
</div>
|
{% if 'id' in data['grub'] %}
|
||||||
</div>
|
linked with the <strong>{{ data['grub']['id'] }}</strong>
|
||||||
</div>
|
{% endif %}
|
||||||
|
|
||||||
|
</div> <!-- end .accordion-body -->
|
||||||
|
</div> <!-- end .accordion-collapse -->
|
||||||
|
</div> <!-- end .accordion-item -->
|
||||||
|
</div> <!-- end .accordion -->
|
||||||
|
@ -1,29 +1,30 @@
|
|||||||
<h3 class="fs-3">Profile</h3>
|
<h3 class="fs-3">Profile</h3>
|
||||||
|
|
||||||
{% for item in data['profile']['vulnerabilities'] %}
|
{% for item in data['profile']['vulnerabilities'] %}
|
||||||
<div class="accordion" id="accordionSysctl">
|
<div class="accordion" id="accordionProfile">
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header">
|
<h2 class="accordion-header">
|
||||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['profile']['vulnerabilities'][item]['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['profile']['vulnerabilities'][item]['accordion-id'] }}">
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['profile']['vulnerabilities'][item]['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['profile']['vulnerabilities'][item]['accordion-id'] }}">
|
||||||
<strong>{{ item }}</strong>
|
<strong>{{ item }}</strong>
|
||||||
{% if data['profile']['vulnerabilities'][item]['result'] == 'failed' %}
|
{% if data['profile']['vulnerabilities'][item]['result'] == 'failed' %}
|
||||||
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['profile']['vulnerabilities'][item]['result'] }}</span>
|
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['profile']['vulnerabilities'][item]['result'] }}</span>
|
||||||
{% elif data['profile']['vulnerabilities'][item]['result'] == 'success' %}
|
{% elif data['profile']['vulnerabilities'][item]['result'] == 'success' %}
|
||||||
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['profile']['vulnerabilities'][item]['result'] }}</span>
|
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['profile']['vulnerabilities'][item]['result'] }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<span class="text-bg-primary p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['profile']['vulnerabilities'][item]['level'] }}</span>
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div id="{{ data['profile']['vulnerabilities'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionProfile">
|
<div id="{{ data['profile']['vulnerabilities'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionProfile">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
{{ data['profile']['vulnerabilities'][item]['description'] }}. <br />
|
{{ data['profile']['vulnerabilities'][item]['description'] }}. <br />
|
||||||
{% if data['profile']['vulnerabilities'][item]['result'] == 'success' %}
|
{% if data['profile']['vulnerabilities'][item]['result'] == 'success' %}
|
||||||
<div class="bd-example-snippet bd-code-snippet">
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
<div class="highlight">
|
<div class="highlight">
|
||||||
<pre tabindex="0" class="chroma"><code class="language-shell">
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
{{ data['profile']['vulnerabilities'][item]['flagFound'] }}
|
{{ data['profile']['vulnerabilities'][item]['flagFound'] }}
|
||||||
</pre></code>
|
</pre></code>
|
||||||
</div>
|
</div> <!-- end highlight -->
|
||||||
</div>
|
</div> <!-- end bd-code-snippet -->
|
||||||
{% else %}
|
{% else %}
|
||||||
For resolving the issue, add this line in the <strong>{{ data['filename'] }}</strong> profile:
|
For resolving the issue, add this line in the <strong>{{ data['filename'] }}</strong> profile:
|
||||||
<div class="bd-example-snippet bd-code-snippet">
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
@ -31,11 +32,16 @@
|
|||||||
<pre tabindex="0" class="chroma"><code class="language-shell">
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
{{ data['profile']['vulnerabilities'][item]['flag'] }} = {{ data['profile']['vulnerabilities'][item]['recommand_value'] }}
|
{{ data['profile']['vulnerabilities'][item]['flag'] }} = {{ data['profile']['vulnerabilities'][item]['recommand_value'] }}
|
||||||
</pre></code>
|
</pre></code>
|
||||||
</div>
|
</div> <!-- end highlight -->
|
||||||
</div>
|
</div> <!-- end bd-code-snippet -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
|
||||||
</div>
|
{% if 'id' in data['profile']['vulnerabilities']['item'] %}
|
||||||
</div>
|
Linked with the <strong>{{ data['profile']['vulnerabilities'][item]['id'] }}</strong>
|
||||||
</div>
|
{% endif %}
|
||||||
|
|
||||||
|
</div> <!-- end .accordion-body -->
|
||||||
|
</div> <!-- end .accordion-collapse -->
|
||||||
|
</div> <!-- end .accordion-item -->
|
||||||
|
</div> <!-- end .accordion -->
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
<h3 class="fs-3">Postfix</h3>
|
<h3 class="fs-3">Postfix</h3>
|
||||||
|
|
||||||
{% for item in data['postfix']['vulnerabilities'] %}
|
{% for item in data['postfix']['vulnerabilities'] %}
|
||||||
<div class="accordion" id="accordionSysctl">
|
<div class="accordion" id="accordionPostfix">
|
||||||
<div class="accordion-item">
|
<div class="accordion-item">
|
||||||
<h2 class="accordion-header">
|
<h2 class="accordion-header">
|
||||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}">
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}" aria-expanded="true" aria-controls="{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}">
|
||||||
<strong>{{ item }}</strong>
|
<strong>{{ item }}</strong>
|
||||||
{% if data['postfix']['vulnerabilities'][item]['result'] == 'failed' %}
|
{% if data['postfix']['vulnerabilities'][item]['result'] == 'failed' %}
|
||||||
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['postfix']['vulnerabilities'][item]['result'] }}</span>
|
<span class="text-bg-danger p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['postfix']['vulnerabilities'][item]['result'] }}</span>
|
||||||
{% elif data['postfix']['vulnerabilities'][item]['result'] == 'success' %}
|
{% elif data['postfix']['vulnerabilities'][item]['result'] == 'success' %}
|
||||||
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['postfix']['vulnerabilities'][item]['result'] }}</span>
|
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['postfix']['vulnerabilities'][item]['result'] }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<span class="text-bg-primary p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['postfix']['vulnerabilities'][item]['level'] }}</span>
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div id="{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionPostfix">
|
<div id="{{ data['postfix']['vulnerabilities'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionPostfix">
|
||||||
@ -22,8 +23,8 @@
|
|||||||
<pre tabindex="0" class="chroma"><code class="language-shell">
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
{{ data['postfix']['vulnerabilities'][item]['flagFound'] }}
|
{{ data['postfix']['vulnerabilities'][item]['flagFound'] }}
|
||||||
</pre></code>
|
</pre></code>
|
||||||
</div>
|
</div> <!-- end .highlight -->
|
||||||
</div>
|
</div> <!-- end .bd-code-snippet -->
|
||||||
{% else %}
|
{% else %}
|
||||||
For resolving the issue, add this line in the <strong>{{ data['postfix']['filename'] }}</strong> vulnerabilities:
|
For resolving the issue, add this line in the <strong>{{ data['postfix']['filename'] }}</strong> vulnerabilities:
|
||||||
<div class="bd-example-snippet bd-code-snippet">
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
@ -33,11 +34,16 @@
|
|||||||
{{ data['postfix']['vulnerabilities'][item]['flag'] }} = {{ value }}
|
{{ data['postfix']['vulnerabilities'][item]['flag'] }} = {{ value }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</pre></code>
|
</pre></code>
|
||||||
</div>
|
</div> <!-- end .highlight -->
|
||||||
</div>
|
</div> <!-- end .bd-code-snippet -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
|
||||||
</div>
|
{% if 'id' in data['postfix']['vulnerabilities'][item] %}
|
||||||
</div>
|
linked with the <strong>{{ data['postfix']['vulnerabilities'][item]['id'] }}</strong>
|
||||||
</div>
|
{% endif %}
|
||||||
|
|
||||||
|
</div> <!-- end .accordion-body -->
|
||||||
|
</div> <!-- end .accordion-collapse -->
|
||||||
|
</div> <!-- end .accordion-item -->
|
||||||
|
</div> <!-- end .accordion -->
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -11,21 +11,27 @@
|
|||||||
{% elif data['sysctl']['file']['sysctl'][item]['result']['result'] == 'success' %}
|
{% elif data['sysctl']['file']['sysctl'][item]['result']['result'] == 'success' %}
|
||||||
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['sysctl']['file']['sysctl'][item]['result']['result'] }}</span>
|
<span class="text-bg-success p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['sysctl']['file']['sysctl'][item]['result']['result'] }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<span class="text-bg-primary p-1" style="padding-left:10pt;padding-right:10pt;margin-left:15pt;">{{ data['sysctl']['file']['sysctl'][item]['level'] }}</span>
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div id="{{ data['sysctl']['file']['sysctl'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionSysctl">
|
<div id="{{ data['sysctl']['file']['sysctl'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionSysctl">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
{{ data['sysctl']['file']['sysctl'][item]['description'] }}. <br />
|
{{ data['sysctl']['file']['sysctl'][item]['description'] }}. <br />
|
||||||
For resolving the issue, add this line in the <strong>{{ data['sysctl']['file']['filename'] }}</strong> file:
|
For resolving the issue, add this line in the <strong>{{ data['sysctl']['file']['filename'] }}</strong> file:
|
||||||
<div class="bd-example-snippet bd-code-snippet">
|
<div class="bd-example-snippet bd-code-snippet">
|
||||||
<div class="highlight">
|
<div class="highlight">
|
||||||
<pre tabindex="0" class="chroma"><code class="language-shell">
|
<pre tabindex="0" class="chroma"><code class="language-shell">
|
||||||
{{ data['sysctl']['file']['sysctl'][item]['flag'] }} = {{ data['sysctl']['file']['sysctl'][item]['value'] }}
|
{{ data['sysctl']['file']['sysctl'][item]['flag'] }} = {{ data['sysctl']['file']['sysctl'][item]['value'] }}
|
||||||
</pre></code>
|
</pre></code>
|
||||||
</div>
|
</div> <!-- end highlight -->
|
||||||
</div>
|
</div> <!-- end bd-code-snippet -->
|
||||||
</div>
|
|
||||||
</div>
|
{% if 'id' in data['sysctl']['file']['sysctl'][item] %}
|
||||||
</div>
|
Linked with the <strong>{{ data['sysctl']['file']['sysctl'][item]['id'] }}</strong>
|
||||||
</div>
|
{% endif %}
|
||||||
|
|
||||||
|
</div> <!-- end accordion-body -->
|
||||||
|
</div> <!-- end accordion-collapse -->
|
||||||
|
</div> <!-- end accordion-item -->
|
||||||
|
</div> <!-- end .accordion -->
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
11
utils.py
11
utils.py
@ -14,17 +14,6 @@ class ConfigError(Exception):
|
|||||||
super().__init__(self.message)
|
super().__init__(self.message)
|
||||||
|
|
||||||
def identifySystem():
|
def identifySystem():
|
||||||
#os = None
|
|
||||||
#with open('/etc/issue', 'r') as f:
|
|
||||||
# line = f.readline()
|
|
||||||
# if re.search('Arch Linux', line):
|
|
||||||
# os = 'ARCHLINUX'
|
|
||||||
# elif re.search('Ubuntu', line):
|
|
||||||
# os = 'UBUNTU'
|
|
||||||
# elif re.search('Debian', line):
|
|
||||||
# os = 'DEBIAN'
|
|
||||||
# else:
|
|
||||||
# os = 'UNKNOWN'
|
|
||||||
kernelVers = run(['/usr/bin/lsb_release', '-is'], capture_output=True)
|
kernelVers = run(['/usr/bin/lsb_release', '-is'], capture_output=True)
|
||||||
return kernelVers.stdout.decode('utf-8')
|
return kernelVers.stdout.decode('utf-8')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user