Analyzing grub

This commit is contained in:
gbucchino 2023-09-12 16:49:18 +02:00
parent 03143c4c0d
commit 9843ca26b9
8 changed files with 145 additions and 11 deletions

@ -1,11 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
def grub() -> list: def grub() -> dict:
grub = list() grub = dict()
grub.append({ grub['description'] = 'Change boot permission'
'description': 'Boot permission', grub['filename'] = '/boot/grub/grub.cfg'
'filename': '/boot/grub/grub.cfg' grub['value'] = 0o600
'chmod': 600,
})
return grub return grub

@ -13,6 +13,7 @@ AUDIT_SYSTEM = [
"postfix", "postfix",
"apache", "apache",
"localaccount", "localaccount",
"grub",
] ]
AUDIT_APPLICATION = [ AUDIT_APPLICATION = [
@ -31,6 +32,7 @@ def generateConfig() -> dict:
config["system"]["sysctl"] = dict() config["system"]["sysctl"] = dict()
config["system"]["sysctl"]["sysctl_file"] = "/etc/sysctl.conf" config["system"]["sysctl"]["sysctl_file"] = "/etc/sysctl.conf"
config['system']['localaccount'] = dict() config['system']['localaccount'] = dict()
config['system']['grub'] = dict()
config["system"]["exclude_plugins"] = list() config["system"]["exclude_plugins"] = list()
# Application # Application
config["application"] = dict() config["application"] = dict()

@ -5,6 +5,7 @@ from core.plugins.sysctl import Sysctl
from core.plugins.postfix import Postfix from core.plugins.postfix import Postfix
from core.plugins.apache import Apache from core.plugins.apache import Apache
from core.plugins.localaccount import LocalAccount from core.plugins.localaccount import LocalAccount
from core.plugins.grub import Grub
from core.report import generateHtmlReport from core.report import generateHtmlReport
from core.config import AUDIT_SYSTEM, AUDIT_APPLICATION, generateConfig, parsingConfigFile from core.config import AUDIT_SYSTEM, AUDIT_APPLICATION, generateConfig, parsingConfigFile
from core.dispatcher import Dispatcher from core.dispatcher import Dispatcher
@ -70,7 +71,6 @@ def main():
audit, audit,
configs["system"][audit] configs["system"][audit]
) )
if args.audit == "application": if args.audit == "application":
print("Auditing the application...") print("Auditing the application...")
pass pass
@ -102,5 +102,11 @@ def localaccount(*args) -> dict:
account.runAudit() account.runAudit()
return account.getReports() return account.getReports()
@Dispatcher.register_plugins
def grub(*args) -> dict:
grub = Grub(args[1])
grub.runAudit()
return grub.getReports()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

85
core/plugins/grub.py Normal file

@ -0,0 +1,85 @@
#!/usr/bin/env python3
from os import stat
from os.path import isfile
from audit.system.plugins.grub import grub
class Grub:
def __init__(self, arguments):
self._object = grub()
self._reports = dict()
# Create the report
self._constructReports()
def runAudit(self):
print("Running test for Grub")
self._analyzingGrub()
def getReports(self) -> dict:
return self._reports
def _analyzingGrub(self):
# Check if the file exist
path = self._object['filename']
try:
if isfile(path):
permission = self._check_permission(path)
if permission != oct(self._object['value']):
self._reports['result'] = 'failed'
else:
self._reports['result'] = 'success'
self._reports['description'] = self._object['description']
self._reports['recommand_value'] = self._object['value']
except FileNotFoundError:
self._reports['grub']['error'] = \
f'File {path} not found'
def _check_permission(self, path) -> oct:
"""
In this function, we get the permission of the file
"""
permission = stat(path).st_mode
octal = 0o000
# Check user permission
if permission & 0o400: # Read
octal += 0o400
if permission & 0o200: # Write
octal += 0o200
if permission & 0o100: # Execute
octal += 0o100
# Check group permission
if permission & 0o040:
octal += 0o040
if permission & 0o020:
octal += 0o020
if permission & 0o010:
octal += 0o010
# Check other permission
if permission & 0o004:
octal += 0o004
if permission & 0o002:
octal += 0o002
if permission & 0o001:
octal += 0o001
return oct(octal)
def _constructReports(self):
"""
Construct dictionary for result of the tests
Each entry contains:
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
- level: high, medium or low
"""
self._reports = dict()
self._reports['filename'] = self._object['filename']

@ -50,6 +50,11 @@ def generateHtmlReport(data):
_generateAccordion(dataJinja2['profile']['vulnerabilities'], 'profile') _generateAccordion(dataJinja2['profile']['vulnerabilities'], 'profile')
if 'pwd_quality' in data['system']['localaccount']: if 'pwd_quality' in data['system']['localaccount']:
pass pass
if 'grub' in data['system']:
dataJinja2['grub'] = data['system']['grub']
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']

@ -13,7 +13,7 @@
{% endif %} {% endif %}
</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="#accordionApache">
<div class="accordion-body"> <div class="accordion-body">
{{ data['postfix']['vulnerabilities'][item]['description'] }}. <br /> {{ data['postfix']['vulnerabilities'][item]['description'] }}. <br />
{% if data['postfix']['vulnerabilities'][item]['result'] == 'success' %} {% if data['postfix']['vulnerabilities'][item]['result'] == 'success' %}

@ -0,0 +1,39 @@
<h3 class="fs-3">Grub</h3>
<div class="accordion" id="accordionSysctl">
<div class="accordion-item">
<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'] }}">
<strong>Grub</strong>
{% 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>
{% 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>
{% endif %}
</button>
</h2>
<div id="{{ data['grub']['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionGrub">
<div class="accordion-body">
{{ data['grub']['description'] }}. <br />
{% if data['grub']['result'] == 'success' %}
<div class="bd-example-snippet bd-code-snippet">
<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="highlight">
<pre tabindex="0" class="chroma"><code class="language-shell">
{{ data['grub']['recommand_value'] }}
</pre></code>
</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>

@ -13,7 +13,7 @@
{% endif %} {% endif %}
</button> </button>
</h2> </h2>
<div id="{{ data['profile']['vulnerabilities'][item]['accordion-id'] }}" class="accordion-collapse collapse" data-bs-parent="#accordionPostfix"> <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' %}