finalduty / cis-benchmarks-audit Goto Github PK
View Code? Open in Web Editor NEWSimple command line tool to check for compliance against CIS Benchmarks
License: Other
Simple command line tool to check for compliance against CIS Benchmarks
License: Other
Various checks in the audit rules (4) are not correct when compared to to the CIS benchmarking recommendations. These cause failures when in fact the correct settings are in place. Some things that are not checked or incorrectly checked in the /etc/audit/audit.rules file are:
4.1.6
MISSING: -w /etc/sysconfig/network-scripts/ -p wa -k system-locale
4.1.7
MISSING: -w /usr/share/selinux/ -p wa -k MAC-policy
4.1.8
this check filtered on the word 'logins' which also exists in 4.1.9 and causes a false failure
4.1.9
this check is filtered on 'session' but two the last two rules should be 'logins' (as below), this is the cause for the failure above but also renders this check invalid.
-w /var/log/wtmp -p wa -k logins
-w /var/log/btmp -p wa -k logins
4.1.14
this check is filtered on 'delete' which also exists in a comments line that is part of the default config. 4.1.17 also has the word delete and both causes a false failure.
4.1.15
missing a trailing forward slash on the folder name, should be
-w /etc/sudoers.d/ -p wa -k scope'
4.1.17
this check is filtered on 'time-change' which must be a typo from a copy\paste, its also missing a -F on the rule, should be.
search_term="modules"
expected='-w /sbin/insmod -p x -k modules\n
-w /sbin/rmmod -p x -k modules\n
-w /sbin/modprobe -p x -k modules\n
-a always,exit -F arch=b64 -S init_module -S delete_module -k modules'
The grep catches any occurrence of :25 including those inside a MAC address. This causes a false 'fail' status.
Adding a proceeding space avoids catching the possible MAC address result and it should only find the port number..
## Tests Start ##
[ $(netstat -tupln | egrep -v '127.0.0.1|::1:' | grep ":25 " | wc -l) -eq 0 ] && result="Pass"
## Tests End ##
The rpm test always returns one line so the current match for -eq 0 means its always a fail regardless of the actual state.
I suggest it includes a grep for "not installed" with -eq 1...
[ $(rpm -q ntp | grep "not installed" &>/dev/null; echo $?) -eq 1 ] && result="Pass"
Hi, i found miss checking on 2.2.1.1 , 5.3.2 and 5.3.3 .
i found solution for fix miss checking and i PR solution.
Hope you can help, Thx
cis-audit.sh: line 487: `test_1.1.1.x': not a valid identifier
According to CIS this is scored.
test 1.5.1 fails if the configuration is listed on multiple files
/etc/sysctl.conf:fs.suid_dumpable = 0
/etc/sysctl.d/99-sysctl.conf:fs.suid_dumpable = 0
the next comparison will fail, as there are multiple lines output being compared.
sed 's/^.*://')" == "fs.suid_dumpable = 0"
maybe add a pipe to uniq to resolve this?
[ "$(grep "fs.suid_dumpable" /etc/sysctl.conf /etc/sysctl.d/.conf | sed 's/^.://' | uniq)" == "fs.suid_dumpable = 0" ]
Can you suggest a way to put the test in to a cron job with an email output, or perhaps just output the final report to file so it can be wrapped in another script to then send as an email attachment.
Sorry, i am not good in programming
in my debug message, the $state return 8, does it means the test will fail after the below the below checking?
[ $state -eq 0 ] && result="Pass"
1.2.1 - is too restrictive since it assumes the existence of specific repo names (base and updates).
1.7.1.4 - if /etc/motd is a symbolic link then test_perms incorrectly inspects link perms instead of file.
3.6.3 and 3.6.4 - this doesn't take into account the iptables rules potentially having comments in them.
4.2.1.3 - doesn't find FileCreateMode if it is set under a /etc/rsyslog.d/*.conf file.
5.4.4 - doesn't find user mask if it occurs multiple times in file like in an if/else condition.
Node.js 12 actions are deprecated. For more information see: https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/. Please update the following actions to use Node.js 16: actions/checkout, actions/setup-python, codecov/codecov-action, actions/setup-python, actions/checkout
The CI Tests workflow https://github.com/finalduty/cis-benchmarks-audit/blob/devel/.github/workflows/ci-tests.yaml needs to be updated with the latest actions
Reviewing this repo after a few years has found that while it is popular, I have not kept up with development of it as much as I would like.
After review, the projects goal to provide an easy to use single-file executable with zero external requirements remains intact but it is becoming increasingly obvious that using bash is not the most effective language going forward.
The repository health shows some concerning symptoms that make me think this contribution is not as good as it should be. Notably, the age of issues is very high and the ratio of forks to pull requests suggest that the community find it easier to adapt/fix things themselves than push back to this repo. This leads to a dilution of community efforts, duplication of efforts and reduction in potential benefits gained by using this repo.
Implement testing suite and automated testing
Contribution experience
Many of the issues that have remained open are due to difficulty in fixing/replicating/preventing-regression. Automated regression testing as above will help, but there is still a process improvement to be made. This may need to be split to a different issue.
Improve support for various benchmarks/os/python versions
Supercedes #28
The grep doesn't match the returned value due to a space at the end which appears to exist in the default configuration.
Hi there,
I really appreciate your work, I'm working on matching this code for RHEL 7 (CIS benchmark v3.0.0)
and I am doing some changes in the code.
I was looking on test test_3.x-single and I saw that not all the conditional statement return the "result" output,
you can see that the second conditional (grep test) returning the state but not the result, is it OK?
(line https://github.com/finalduty/cis_benchmarks_audit/blob/1d134f465baf9fcff1939cbb9e798155a0c0e182/cis-audit.sh#L1212)
test_3.x-single() {
id=$1
level=$2
protocol=$3
sysctl=$4
val=$5
description=$( echo $@ | awk '{$1=$2=$3=$4=$5=""; print $0}' | sed 's/^ //')
scored="Scored"
test_start_time="$(test_start $id)"
[ "$(sysctl net.$protocol.$sysctl)" == "net.$protocol.$sysctl = $val" ] && result="Pass"
[ "$(grep "net.$protocol.$sysctl" /etc/sysctl.conf /etc/sysctl.d/.conf | sed -e 's/^.*://' -e 's/\s//g' | uniq)" == "net.$protocol.$sysctl=$val" ] || state=1
duration="$(test_finish $id $test_start_time)ms"
write_result "$id,$description,$scored,$level,$result,$duration"
}
Whilst the CIS benchmark check doesn't include it I suggest the check also matches on the word 'remember' in the first step. This avoids a failure when there are multiple entries in the files.
pwauth_history=$(egrep '^password\s+required\s+pam_pwhistory.so\s+remember' /etc/pam.d/password-auth)
sysauth_history=$(egrep '^password\s+required\s+pam_pwhistory.so\s+remember' /etc/pam.d/system-auth)
pwauth_unix=$(egrep '^password\s+sufficient\s+pam_unix.so\s+remember' /etc/pam.d/password-auth)
sysauth_unix=$(egrep '^password\s+sufficient\s+pam_unix.so\s+remember' /etc/pam.d/system-auth)
On one system I had a pass but on another a fail, both matched the CIS check but the script includes an extra comma match there is not always present.
mount | grep /dev/shm
PASS RESULT = tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,seclabel)
FAIL RESULT = tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,noexec)
The diff check uses $file and it should be $gdm_file
The grep doesn't account for the indented lines (leading spaces) and fails. The check should also confirm that the users.cfg contains the password.
I suggest..
## Tests Start ##
state=0
[ $(grep "set superusers" /boot/grub2/grub.cfg | wc -l) -eq 0 ] && state=1
[ $(grep "password_pbkdf2" /boot/grub2/grub.cfg | wc -l ) -eq 0 ] && state=1
[ $(grep "^GRUB2_PASSWORD" /boot/grub2/user.cfg | wc -l ) -eq 0 ] && state=1
[ $state -eq 0 ] && result="Pass"
## Tests End ##
It checks for /etc/ntpd.conf and should be /etc/ntp.conf
When I execute the script without --debug will fail on 1.1.1.7, 1.1.1.8, 3.1.2 and 3.2.7 even I followed the guideline and verified manually.
However, when I try to add --debug to find out the reason, the script showing pass.
Doesn't behave well if files are missing.
Example:
[00:00:06] (|) 102 of 106 tests completed ls: cannot access '/etc/hosts.allow': No such file or directory
./cis-audit.sh: line 1323: [: ==: unary operator expected
./cis-audit.sh: line 1324: [: ==: unary operator expected
./cis-audit.sh: line 1325: [: ==: unary operator expected
Tabs in the /etc/pam.d/password-auth and /etc/pam.d/system-auth are not configured right so the formatting can cause a failure. Also the /etc/security/pwquality.conf requires spaces between the equals characters but the check doesn't expect the spaces so it fails here also.
CIS released v1.0.0 guidelines for CentOS 8 on 2019-10-31
In test 2.2.2 below it looks like the test will ALWAYS pass with return 0 since all output and errors are wiped out before piping to wc -l
[ $(rpm -qa xorg-x11* &>/dev/null | wc -l) -eq 0 ] && result="Pass"
I'm not sure if this is a bug or a problem with my specific system but check 4.1.18 fails because the "auditctl -l | tail -l"' does not bring back the "-e 2". The check advised in the CIS benchmark is "grep "^\s*[^#]" /etc/audit/audit.rules | tail -1". My system does pass on this check.
As noted on bug #6 this check fails due to the spacing and requires a change to egrep with a slightly different syntax...
egrep "^auth\s+required\s+pam_wheel.so\s+use_uid" /etc/pam.d/su
If i did not turn on the SELinux, the permission setting will not contain the '.' after the permission?
[ $(ls -l /etc/at.allow 2>/dev/null | awk '{ print $1" "$3" "$4 }' | grep -c -- "-rw-------. root root") -eq 1 ]
e.g.
-rw------- No SELinux enabled / attribute is set
-rw-------.
The command chage --list {user} returns a date which is the date when the account would be locked due to inactivity. The check is expecting an integer that is the number of days as with the prior /etc/login.defs check but this will not work.
@finalduty I would like to take this opportunity to thank you for developing this audit script.
My question is in regards to test 6.2.6 Ensure no duplicate group names exist
which does not seem to be implemented as it points to the same function as test 6.2.5 Ensure no duplicate user names exist
.
According to the CIS document, this can be implemented in Bash as follows:
#!/bin/bash
cut -d: -f1 /etc/group | sort | uniq -d | while read -r x; do echo "Duplicate group name ${x} in /etc/group"
done
The following Python code should do the trick although it is untested:
def audit_duplicate_group_names(self) -> int:
state = 0
cmd = R"cut -d: -f1 /etc/group | sort | uniq -d"
r = self._shellexec(cmd)
if r.stdout[0] != "":
state = 1
return state
Kindly let me know if this test has been implemented or not.
Many thanks.
One of the forks of this project makes no other change than removing copyright/license information and replacing it with their own.
line 1108 in /main/cis_audit.py
if r.stdout[0] == 'install /bin/true\n':
Tests were failing, but I could verify they shouldn't be through manual means.
Here is CMD output printed from within the script test result.
'install /bin/true '
My output has a single space, not a new line.
Changing the expected string \n to a single space in the above file/line has resolved this issue for me.
@finalduty Is there any chance that Centos 9 or Amazon Linux 2023 hosts will be supported in the future?
I know this would be quite an ask but the benchmarking script works great for Amazon Linux 2 and just wanted to check if something was on the cards.
Cheers
I don't get a match with default config and I think its due the check now needed extended regular expression. egrep ?
Whilst it makes some sense to always have multiple entries in the server pool list its not a CIS requirement so the egrep count should be changed to -ge 1 rather than 2.
CIS released v3.0.0 of the CentOS 7 hardening benchmark on 2020-06-30.
This release involves a major rewrite of the framework and tests which will break compatibility with previous versions.
To Do's
Future Considerations
v3.0.0 changed the ordering of some tests. As such, it no longer makes sense to name test functions after their benchmark id and this change will involve renaming the test functions to a name that more closely matches what they test.
For example:
v0.10 | v0.11 |
---|---|
test_1.1.1.x | test_kernel_module_is_disabled |
test_1.2.2 | test_gpg_keys_are_configured |
The aim is to increase verbosity, which will make test names more descriptive and allow renumbering / reordering of tests in future to be a lot easier. It also means that other Standards such as CentOS 8 or Debian do not have contradictory IDs and test names.
Shellspec is a unit testing framework which allows for the creation of testing the functions and mocking files.
This will help improve code quality by offering a greater ability to test different system configurations to ensure that the correct results are returned by the tests.
Full disclosure, I've not used this before, but it looks really promising for helping create a quality tool.
Should be fairly self explanatory. This is a static analysis tool which helps implement better code quality.
Previously test functions were (semi-)duplicated in situations where the test was largely the same but the description did not fit the test function design.
This change will allow fewer duplicated test functions (DRY), and help pave the way to support additional OSs in future.
Previously, the results of test functions would take a default Fail result from a global variable. This worked well to prevent having to specify 'result = "Fail"' in each function, however it made it more difficult to interpret for anyone not familiar with the code, including myself when I haven't touched it in a while.
The aim here is to make each test wholly self-contained, so that contributors can look at a single function and understand all of it in one go. This also is a partial requirement for integrating Shellspec tests effectively.
The tests use a command which fails when IPv6 is disabled, disabling IPv6 is the remediation for 3.3.3 so this check really needs to be aware of this likly outcome and mark it as pass.
[root@RED-HAT-8]# ./cis_audit.py --level 2
Traceback (most recent call last):
File "./cis_audit.py", line 39, in <module>
from tests.integration import (
ModuleNotFoundError: No module named 'tests'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.