Files
atap/ATAPAuditor/AuditGroups/Red Hat Enterprise Linux 9-CIS-1.0.0.ps1
T
2026-05-11 09:15:08 +02:00

3833 lines
113 KiB
PowerShell

$rcTrue = "True"
$rcCompliant = "Compliant"
$rcFalse = "False"
$rcNone = "None"
$rcNonCompliant = "Non-Compliant"
$rcNonCompliantManualReviewRequired = "Manual review required"
$rcCompliantIPv6isDisabled = "IPv6 is disabled"
$retCompliant = @{
Message = $rcCompliant
Status = $rcTrue
}
$retNonCompliant = @{
Message = $rcNonCompliant
Status = $rcFalse
}
$retCompliantIPv6Disabled = @{
Message = $rcCompliantIPv6isDisabled
Status = $rcTrue
}
$retNonCompliantManualReviewRequired = @{
Message = $rcNonCompliantManualReviewRequired
Status = $rcNone
}
$IPv6Status_script = grep -Pqs '^\h*0\b' /sys/module/ipv6/parameters/disable && echo "IPv6 is enabled" || echo "IPv6 is not enabled"
$IPv6Status = bash -c $IPv6Status_script
if ($IPv6Status -match "is enabled") {
$IPv6Status = "enabled"
} else {
$IPv6Status = "disabled"
}
$parentPath = Split-Path -Parent -Path $PSScriptRoot
$scriptPath = $parentPath + "/Helpers/ShellScripts/RHEL9/"
### Chapter 1 - Initial Setup
[AuditTest] @{
Id = "1.1.1.1"
Task = "Ensure mounting of squashfs filesystems is disabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_1111.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.1.2"
Task = "Ensure mounting of udf filesystems is disabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_1112.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.2.1"
Task = "Ensure /tmp is a separate partition"
Test = {
$result = findmnt --kernel /tmp | grep -E '\s/tmp\s'
if ($result -match "/tmp") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.2.2"
Task = "Ensure nodev option set on /tmp partition"
Test = {
$result = findmnt --kernel /tmp | grep nodev
if ($result -match "/tmp") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.2.3"
Task = "Ensure noexec option set on /tmp partition"
Test = {
$result = findmnt --kernel /tmp | grep noexec
if ($result -match "/tmp") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.2.4"
Task = "Ensure nosuid option set on /tmp partition"
Test = {
$result = findmnt --kernel /tmp | grep nosuid
if ($result -match "/tmp") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.3.1"
Task = "Ensure separate partition exists for /var"
Test = {
$result = findmnt --kernel /var
if ($result -match "/var") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.3.2"
Task = "Ensure nodev option set on /var partition"
Test = {
$result = findmnt --kernel /var | grep nodev
if ($result -match "/var") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.3.3"
Task = "Ensure nosuid option set on /var partition"
Test = {
$result = findmnt --kernel /var | grep nosuid
if ($result -match "/var") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.4.1"
Task = "Ensure separate partition exists for /var/tmp"
Test = {
$result = findmnt --kernel /var/tmp
if ($result -match "/var/tmp") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.4.2"
Task = "Ensure noexec option set on /var/tmp partition"
Test = {
$result = findmnt --kernel /var/tmp | grep noexec
if ($result -match "/var/tmp") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.4.3"
Task = "Ensure nosuid option set on /var/tmp partition"
Test = {
$result = findmnt --kernel /var/tmp | grep nosuid
if ($result -match "/var/tmp") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.4.4"
Task = "Ensure nodev option set on /var/tmp partition"
Test = {
$result = findmnt --kernel /var/tmp | grep nodev
if ($result -match "/tmp") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.5.1"
Task = "Ensure separate partition exists for /var/log"
Test = {
$result = findmnt --kernel /var/log
if ($result -match "/var/log") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.5.2"
Task = "Ensure nodev option set on /var/log"
Test = {
$result = findmnt --kernel /var/log | grep nodev
if ($result -match "/var/log") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.5.3"
Task = "Ensure noexec option set on /var/log"
Test = {
$result = findmnt --kernel /var/log | grep noexec
if ($result -match "/var/log") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.5.4"
Task = "Ensure nosuid option set on /var/log"
Test = {
$result = findmnt --kernel /var/log | grep nosuid
if ($result -match "/var/log") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.6.1"
Task = "Ensure separate partition exists for /var/log/audit"
Test = {
$result = findmnt --kernel /var/log/audit
if ($result -match "/var/log/audit") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.6.2"
Task = "Ensure noexec option set on /var/log/audit"
Test = {
$result = findmnt --kernel /var/log/audit | grep noexec
if ($result -match "/var/log/audit") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.6.3"
Task = "Ensure nodev option set on /var/log/audit"
Test = {
$result = findmnt --kernel /var/log/audit | grep nodev
if ($result -match "/var/log/audit") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.6.4"
Task = "Ensure nosuid option set on /var/log/audit"
Test = {
$result = findmnt --kernel /var/log/audit | grep nosuid
if ($result -match "/var/log/audit") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.7.1"
Task = "Ensure separate partition exists for /home"
Test = {
$result = findmnt --kernel /home
if ($result -match "/home") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.7.2"
Task = "Ensure nodev option set on /home"
Test = {
$result = findmnt --kernel /home | grep nodev
if ($result -match "/home") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.7.3"
Task = "Ensure nosuid option set on /home"
Test = {
$result = findmnt --kernel /home | grep nosuid
if ($result -match "/home") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.8.1"
Task = "Ensure /dev/shm is a separate partition"
Test = {
$result = findmnt --kernel /dev/shm
if ($result -match "/dev/shm") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.8.2"
Task = "Ensure nodev option set on /dev/shm partition"
Test = {
$result = mount | grep -E '\s/dev/shm\s' | grep nodev
if ($result -match "/dev/shm") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.8.3"
Task = "Ensure noexec option set on /dev/shm partition"
Test = {
$result = findmnt --kernel /dev/shm | grep noexec
if ($result -match "/dev/shm") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.8.4"
Task = "Ensure nosuid option set on /dev/shm partition"
Test = {
$result = findmnt --kernel /dev/shm | grep nosuid
if ($result -match "/dev/shm") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.1.9"
Task = "Disable USB Storage"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_119.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.2.1"
Task = "Ensure GPG keys are configured"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "1.2.2"
Task = "Ensure gpgcheck is globally activated"
Test = {
$result = grep ^gpgcheck /etc/dnf/dnf.conf
if ($result -match "gpgcheck=1") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.2.3"
Task = "Ensure package manager repositories are configured"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "1.2.4"
Task = "Ensure repo_gpgcheck is globally activated"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "1.3.1"
Task = "Ensure aide is installed"
Test = {
$result = rpm -q aide
if ($result -match "aide-") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.3.2"
Task = "Ensure filesystem integrity is regularly checked"
Test = {
$result1 = systemctl is-enabled aidecheck.service
$result2 = systemctl is-enabled aidecheck.timer
$result3 = systemctl status aidecheck.service
if ($result1 -match "enabled" -and $result2 -match "enabled" -and $result3 -match "Active:") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.3.3"
Task = "Ensure filesystem integrity is regularly checked"
Test = {
$result = grep -Ps -- '(\/sbin\/(audit|au)\H*\b)' /etc/aide.conf.d/*.conf /etc/aide.conf
if ($result -match "/sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512" -and
$result -match "/sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512" -and
$result -match "/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512" -and
$result -match "/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512" -and
$result -match "/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512" -and
$result -match "/sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512"){
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.4.1"
Task = "Ensure bootloader password is set"
Test = {
$result = awk -F. '/^\s*GRUB2_PASSWORD/ {print $1"."$2"."$3}' /boot/grub2/user.cfg
if ($result -match "GRUB2_PASSWORD=grub.pbkdf2.sha512") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.4.2"
Task = "Ensure permissions on bootloader config are configured"
Test = {
$result1 = stat -Lc "%n %#a %u/%U %g/%G" /boot/grub2/grub.cfg | grep '/boot/grub2/grub.cfg\s*0700\s*0/root\s*0/root'
$result2 = stat -Lc "%n %#a %u/%U %g/%G" /boot/grub2/grubenv | grep '/boot/grub2/grubenv\s*0600\s*0/root\s*0/root'
$result3 = stat -Lc "%n %#a %u/%U %g/%G" /boot/grub2/user.cfg | grep '/boot/grub2/user.cfg\s*0600\s*0/root\s*0/root'
if ($result1 -ne $null -and $result2 -ne $null -and $result3 -ne $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.5.1"
Task = "Ensure core dump storage is disabled"
Test = {
$result = grep -i '^\s*storage\s*=\s*none' /etc/systemd/coredump.conf
if ($result -match "Storage=none") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.5.2"
Task = "Ensure core dump backtraces are disabled"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
grep -Pi '^\h*ProcessSizeMax\h*=\h*0\b' /etc/systemd/coredump.conf || echo -e "\n- Audit results:\n FAIL\n - \"ProcessSizeMax\" is: \"$(grep -i 'ProcessSizeMax' /etc/systemd/coredump.conf)\""
}
'@
$result = bash -c $script_string
if ($result -match "FAIL") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "1.5.3"
Task = "Ensure address space layout randomization (ASLR) is enabled"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
l_output="" l_output2=""
l_parlist="kernel.randomize_va_space=2"
l_searchloc="/run/sysctl.d/*.conf /etc/sysctl.d/*.conf /usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf /etc/sysctl.conf $([ -f /etc/default/ufw ] && awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)"
KPC()
{
l_krp="$(sysctl "$l_kpname" | awk -F= '{print $2}' | xargs)"
l_pafile="$(grep -Psl -- "^\h*$l_kpname\h*=\h*$l_kpvalue\b\h*(#.*)?$" $l_searchloc)"
l_fafile="$(grep -s -- "^\s*$l_kpname" $l_searchloc | grep -Pv -- "\h*=\h*$l_kpvalue\b\h*" | awk -F: '{print $1}')"
if [ "$l_krp" = "$l_kpvalue" ]; then
l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in the running configuration"
else
l_output2="$l_output2\n - \"$l_kpname\" is set to \"$l_krp\" in the running configuration"
fi
if [ -n "$l_pafile" ]; then
l_output="$l_output\n - \"$l_kpname\" is set to \"$l_kpvalue\" in \"$l_pafile\""
else
l_output2="$l_output2\n - \"$l_kpname = $l_kpvalue\" is not set in a kernel parameter configuration file"
fi
[ -n "$l_fafile" ] && l_output2="$l_output2\n - \"$l_kpname\" is set incorrectly in \"$l_fafile\""
}
for l_kpe in $l_parlist; do
l_kpname="$(awk -F= '{print $1}' <<< "$l_kpe")"
l_kpvalue="$(awk -F= '{print $2}' <<< "$l_kpe")"
KPC
done
if [ -z "$l_output2" ]; then
echo -e "\n- Audit Result:\n PASS\n$l_output\n"
else
echo -e "\n- Audit Result:\n FAIL\n - Reason(s) for audit failure:\n$l_output2\n" [ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n"
fi
}
'@
$script = bash -c $script_string
if ($script -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.6.1.1"
Task = "Ensure SELinux is installed"
Test = {
$result = rpm -q libselinux
if ($result -match "libselinux-") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.6.1.2"
Task = "Ensure SELinux is not disabled in bootloader configuration"
Test = {
$result = grubby --info=ALL | grep -Po '(selinux|enforcing)=0\b'
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.6.1.3"
Task = "Ensure SELinux policy is configured"
Test = {
$result1 = grep -E '^\s*SELINUXTYPE=(targeted|mls)\b' /etc/selinux/config
$result2 = sestatus | grep Loaded
if (($result1 -match "targeted" -or $result1 -match "mls") -and ($result2 -match "targeted" -or $result2 -match "mls")) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.6.1.4"
Task = "Ensure the SELinux mode is not disabled"
Test = {
$result1 = getenforce
$result2 = grep -Ei '^\s*SELINUX=(enforcing|permissive)' /etc/selinux/config
if (($result1 -match "Enforcing" -or $result1 -match "Permissive") -and ($result2 -match "SELINUX=enforcing" -or $result2 -match "SELINUX=permissive")) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.6.1.5"
Task = "Ensure the SELinux mode is enforcing"
Test = {
$result1 = getenforce
$result2 = grep -i SELINUX=enforcing /etc/selinux/config
if ($result1 -match "Enforcing" -and $result2 -match "SELINUX=enforcing") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.6.1.6"
Task = "Ensure no uncofined services exist"
Test = {
$result = ps -eZ | grep unconfined_service_t
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.6.1.7"
Task = "Ensure SETroubleshoot is not installed"
Test = {
$result = rpm -q setroubleshoot
if ($result -match "is not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.6.1.8"
Task = "Ensure the MCS Translation Service (mcstrans) is not installed"
Test = {
$result = rpm -q mcstrans
if ($result -match "is not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.7.1"
Task = "Ensure the MCS Translation Service (mcstrans) is not installed"
Test = {
$result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/motd
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.7.2"
Task = "Ensure local login warning banner is configured properly"
Test = {
$result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.7.3"
Task = "Ensure remote login warning banner is configured properly"
Test = {
$result = grep -E -i "(\\\v|\\\r|\\\m|\\\s|$(grep '^ID=' /etc/os-release | cut -d= -f2 | sed -e 's/"//g'))" /etc/issue.net
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.7.4"
Task = "Ensure permissions on /etc/motd are configured"
Test = {
$result = stat -c "%a" /etc/motd
if ($result -eq 644) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.7.5"
Task = "Ensure permissions on /etc/issue are configured"
Test = {
$result = stat -c "%a" /etc/issue
if ($result -eq 644) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.7.6"
Task = "Ensure permissions on /etc/issue.net are configured"
Test = {
$result = stat -c "%a" /etc/issue.net
if ($result -eq 644) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.1"
Task = "Ensure GNOME Display Manager is removed"
Test = {
$result = rpm -q gdm
if ($result -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.2"
Task = "Ensure GDM login banner is configured"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_182.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.3"
Task = "Ensure GDM disable-user-list option is enabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_183.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.4"
Task = "Ensure GDM screen locks then the user is idle"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_184.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.5"
Task = "Ensure GDM screen locks cannot be overridden"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_185.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.6"
Task = "Ensure GDM automatic mounting of removable media is disabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_186.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.7"
Task = "Ensure GDM disabling automatic mounting of removable media is not overridden"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_187.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.8"
Task = "Ensure GDM autorun-never is enabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_188.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.9"
Task = "Ensure GDM autorun-never is not overridden"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_189.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.8.10"
Task = "Ensure XDCMP is not enabled"
Test = {
$test = grep -Eis '^\s*Enable\s*=\s*true' /etc/gdm/custom.conf
if ($test -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "1.9"
Task = "Ensure updates, patches, and additional security software are installed"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "1.10"
Task = "Ensure system-wide crypto policy is not legacy"
Test = {
$test = grep -E -i '^\s*LEGACY\s*(\s+#.*)?$' /etc/crypto-policies/config
if ($test -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
### Chapter 2 - Services
[AuditTest] @{
Id = "2.1.1"
Task = "Ensure time synchronization is in use"
Test = {
$test = rpm -q chrony
if ($test -match "chrony-") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.1.2"
Task = "Ensure chrony is configured"
Test = {
$test = grep -E "^(server|pool)" /etc/chrony.conf | grep OPTIONS\s*-u\s*chrony
if ($test -match "OPTIONS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.1"
Task = "Ensure xorg-x11-server-common is not installed"
Test = {
$test = rpm -q xorg-x11-server-common
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.2"
Task = "Ensure Avahi Server is not installed"
Test = {
$test = rpm -q avahi
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.3"
Task = "Ensure CUPS is not installed"
Test = {
$test = rpm -q cups
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.4"
Task = "Ensure DHCP Server is not installed"
Test = {
$test = rpm -q dhcp-server
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.5"
Task = "Ensure DNS Server is not installed"
Test = {
$test = rpm -q bind
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.6"
Task = "Ensure VSFTP Server is not installed"
Test = {
$test = rpm -q vsftpd
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.7"
Task = "Ensure VSFTP Server is not installed"
Test = {
$test = rpm -q vsftpd
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.8"
Task = "Ensure a web server is not installed"
Test = {
$test = rpm -q httpd nginx
if ($test -match "httpd is not installed" -and $test -match "nginx is not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.9"
Task = "Ensure IMAP and POP3 server is not installed"
Test = {
$test = rpm -q dovecot cyrus-imapd
if ($test -match "dovecot is not installed" -and $test -match "cyrus-imapd is not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.10"
Task = "Ensure Samba is not installed"
Test = {
$test = rpm -q samba
if ($test -match "samba is not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.11"
Task = "Ensure HTTP Proxy Server is not installed"
Test = {
$test = rpm -q squid
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.12"
Task = "Ensure net-snmp is not installed"
Test = {
$test = rpm -q net-snmp
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.13"
Task = "Ensure telnet-server is not installed"
Test = {
$test = rpm -q telnet-server
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.14"
Task = "Ensure dnsmasq is not installed"
Test = {
$test = rpm -q dnsmasq
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.15"
Task = "Ensure mail transfer agent is configured for local-only mode"
Test = {
$test = ss -lntu | grep -E ':25\s' | grep -E -v '\s(127.0.0.1|\[?::1\]?):25\s'
if ($test -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.16"
Task = "Ensure nfs-utils is not installed or the nfs-server service is masked"
Test = {
rpm -q nfs-utils
if ($?) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.17"
Task = "Ensure rpcbind is not installed or the rpcbind services are masked"
Test = {
$test1 = rpm -q rpcbind
$test21 = systemctl is-enabled rpcbind
$test22 = systemctl is-enabled rpcbind.socket
if ($test1 -match "not installed" -or ($test21 -match "masked" -and $test22 -match "masked")) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.2.18"
Task = "Ensure rsync-daemon is not installed or the rsyncd service is masked"
Test = {
$test1 = rpm -q rsync-daemon
$test2 = systemctl is-enabled rsync-daemon
if ($test1 -match "not installed" -or $test2 -match "masked") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.3.1"
Task = "Ensure telnet client is not installed"
Test = {
$test = rpm -q telnet
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.3.2"
Task = "Ensure LDAP client is not installed"
Test = {
$test = rpm -q openldap-clients
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.3.3"
Task = "Ensure TFTP client is not installed"
Test = {
$test = rpm -q tftp
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.3.4"
Task = "Ensure FTP client is not installed"
Test = {
$test = rpm -q ftp
if ($test -match "not installed") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "2.4"
Task = "Ensure nonessential services listening on the system are removed or masked"
Test = {
return $retNonCompliantManualReviewRequired
}
}
### Chapter 3 - Network Configuration
[AuditTest] @{
Id = "3.1.1"
Task = "Ensure IPv6 status is identified"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "3.1.2"
Task = "Ensure wireless interfaces are disabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_312.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.1.3"
Task = "Ensure TIPC is disabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_313.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.2.1"
Task = "Ensure IP forwarding is disabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_321.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.2.2"
Task = "Ensure packet redirect sending is disabled"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_322_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_322_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "PASS" -and $result2 -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.3.1"
Task = "Ensure packet redirect sending is disabled"
Test = {
$resultScript11 = $scriptPath + "CIS100_RHEL9_331_11.sh"
$result11 = bash $resultScript11
$resultScript12 = $scriptPath + "CIS100_RHEL9_331_12.sh"
$result12 = bash $resultScript12
$resultScript21 = $scriptPath + "CIS100_RHEL9_331_21.sh"
$result21 = bash $resultScript21
$resultScript22 = $scriptPath + "CIS100_RHEL9_331_22.sh"
$result22 = bash $resultScript22
if ($IPv6Status -eq "enabled") {
if ($result21 -match "PASS" -and $result22 -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
} else {
if ($result11 -match "PASS" -and $result12 -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
}
[AuditTest] @{
Id = "3.3.2"
Task = "Ensure ICMP redirects are not accepted"
Test = {
$resultScript11 = $scriptPath + "CIS100_RHEL9_332_11.sh"
$result11 = bash $resultScript11
$resultScript12 = $scriptPath + "CIS100_RHEL9_332_12.sh"
$result12 = bash $resultScript12
$resultScript21 = $scriptPath + "CIS100_RHEL9_332_21.sh"
$result21 = bash $resultScript21
$resultScript22 = $scriptPath + "CIS100_RHEL9_332_22.sh"
$result22 = bash $resultScript22
if ($IPv6Status -eq "enabled") {
if ($result21 -match "PASS" -and $result22 -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
} else {
if ($result11 -match "PASS" -and $result12 -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
}
# 3.3.3 ist identisch mit 3.3.2 ... warum auch immer - wird hier weg gelassen
[AuditTest] @{
Id = "3.3.4"
Task = "Ensure suspicious packets are logged"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_334_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_334_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "PASS" -and $result2 -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.3.5"
Task = "Ensure broadcast ICMP requests are ignored"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_335.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.3.6"
Task = "Ensure bogus ICMP responses are ignored"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_336.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.3.7"
Task = "Ensure Reverse Path Filtering is enabled"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_337_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_337_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "PASS" -and $result2 -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.3.8"
Task = "Ensure TCP SYN Cookies is enabled"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_338.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.3.9"
Task = "Ensure IPv6 router advertisements are not accepted"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_339_1.sh"
$resultScript1 = $scriptPath + "CIS100_RHEL9_339_2.sh"
if ($IPv6Status -match "disabled") {
return $retCompliantIPv6Disabled
} else {
$script1 = bash $resultScript1
$script2 = bash $resultScript2
if ($script1 -match "PASS" -and $script2 -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
}
[AuditTest] @{
Id = "3.4.1.1"
Task = "Ensure nftables is installed"
Test = {
$result = rpm -q nftables
if ($result -match "nftables-") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.4.1.2"
Task = "Ensure a single firewall configuration utility is in use"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_3412.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.4.2.1"
Task = "Ensure firewalld default zone is set"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_3421.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.4.2.2"
Task = "Ensure at least one nftables table exists"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "3.4.2.3"
Task = "Ensure nftables base chains exist"
Test = {
try{
$test1 = nft list ruleset | grep 'hook input'
$test2 = nft list ruleset | grep 'hook forward'
$test3 = nft list ruleset | grep 'hook output'
if($test1 -match "type filter hook input" -and $test2 -match "type filter hook forward" -and $test3 -match "type filter hook output"){
return @{
Message = "Compliant"
Status = "True"
}
}
return @{
Message = "Not-Compliant"
Status = "False"
}
}
catch{
return @{
Message = "Command not found!"
Status = "False"
}
}
}
}
[AuditTest] @{
Id = "3.4.2.4"
Task = "Ensure host based firewall loopback traffic is configured"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
l_output="" l_output2=""
if nft list ruleset | awk '/hook\s+input\s+/,/\}\s*(#.*)?$/' | grep -Pq -- '\H+\h+"lo"\h+accept'; then
l_output="$l_output\n - Network traffic to the loopback address is correctly set to accept"
else
l_output2="$l_output2\n - Network traffic to the loopback address is not set to accept"
fi
l_ipsaddr="$(nft list ruleset | awk '/filter_IN_public_deny|hook\s+input\s+/,/\}\s*(#.*)?$/' | grep -P -- 'ip\h+saddr')"
if grep -Pq -- 'ip\h+saddr\h+127\.0\.0\.0\/8\h+(counter\h+packets\h+\d+\h+bytes\h+\d+\h+)?drop' <<< "$l_ipsaddr" || grep -Pq -- 'ip\h+daddr\h+\!\=\h+127\.0\.0\.1\h+ip\h+saddr\h+127\.0\.0\.1\h+drop' <<< "$l_ipsaddr"; then
l_output="$l_output\n - IPv4 network traffic from loopback address correctly set to drop"
else
l_output2="$l_output2\n - IPv4 network traffic from loopback address not set to drop"
fi
if grep -Pq -- '^\h*0\h*$' /sys/module/ipv6/parameters/disable; then
l_ip6saddr="$(nft list ruleset | awk '/filter_IN_public_deny|hook input/,/}/' | grep 'ip6 saddr')"
if grep -Pq 'ip6\h+saddr\h+::1\h+(counter\h+packets\h+\d+\h+bytes\h+\d+\h+)?drop' <<< "$l_ip6saddr" || grep -Pq -- 'ip6\h+daddr\h+\!=\h+::1\h+ip6\h+saddr\h+::1\h+drop' <<< "$l_ip6saddr"; then
l_output="$l_output\n - IPv6 network traffic from loopback address correctly set to drop"
else
l_output2="$l_output2\n - IPv6 network traffic from loopback address not set to drop"
fi
fi
if [ -z "$l_output2" ]; then
echo -e "\n- Audit Result:\n PASS\n$l_output"
else
echo -e "\n- Audit Result:\n FAIL\n$l_output2\n\n - Correctly set:\n$l_output"
fi
}
'@
$script = bash -c $script_string
if ($script -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "3.4.2.5"
Task = "Ensure firewalld drops unnecessary services and ports"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "3.4.2.6"
Task = "Ensure nftables established connections are configured"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "3.4.2.7"
Task = "Ensure nftables default deny firewall policy"
Test = {
$result1 = systemctl --quiet is-enabled nftables.service && nft list ruleset | grep 'hook input' | grep -v 'policy drop'
$result2 = systemctl --quiet is-enabled nftables.service && nft list ruleset | grep 'hook forward' | grep -v 'policy drop'
if ($result1 -eq $null -and $result2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
### Chapter 4 - Logging and Auditing
[AuditTest] @{
Id = "4.1.1.1"
Task = "Ensure auditd is installed"
Test = {
$result1 = rpm -q audit
if ($result1 -match "audit-") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.1.2"
Task = "Ensure auditing for processes that start prior to auditd is enabled"
Test = {
$result1 = grubby --info=ALL | grep -Po '\baudit=1\b'
if ($result1 -match "audit=1") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.1.3"
Task = "Ensure audit_backlog_limit is sufficient"
Test = {
$result1 = grubby --info=ALL | grep -Po "\baudit_backlog_limit=\d+\b"
if ($result1 -match "audit_backlog_limit=") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.1.4"
Task = "Ensure auditd service is enabled"
Test = {
$result1 = systemctl is-enabled auditd
if ($result1 -match "enabled") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.2.1"
Task = "Ensure audit log storage size is configured"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "4.1.2.2"
Task = "Ensure audit logs are not automatically deleted"
Test = {
$result1 = grep max_log_file_action /etc/audit/auditd.conf | grep max_log_file_action
if ($result1 -match "max_log_file_action = keep_logs") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.2.3"
Task = "Ensure system is disabled when audit logs are full"
Test = {
$result1 = grep space_left_action /etc/audit/auditd.conf
$result2 = grep action_mail_acct /etc/audit/auditd.conf
$result3 = grep -E 'admin_space_left_action\s*=\s*(halt|single)' /etc/audit/auditd.conf
if ($result1 -match "space_left_action = email" -and $result2 -match "action_mail_acct = root" -and ($result3 -match "admin_space_left_action = halt" -or $result3 -match "admin_space_left_action = single")) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.1"
Task = "Ensure changes to system administration scope (sudoers) is collected"
Test = {
$result1 = awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
$result2 = auditctl -l | awk '/^ *-w/ &&/\/etc\/sudoers/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
if ($result1 -match "-w /etc/sudoers -p wa -k scope" -and $result1 -match "-w /etc/sudoers.d -p wa -k scope" -and $result2 -match "-w /etc/sudoers -p wa -k scope" -and $result2 -match "-w /etc/sudoers.d -p wa -k scope") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.2"
Task = "Ensure actions as another user are always logged"
Test = {
$result1 = awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&(/ -C *euid!=uid/||/ -C *uid!=euid/) &&/ -S *execve/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
$result2 = auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&(/ -F *auid!=unset/||/ -F *auid!=-1/||/ -F *auid!=4294967295/) &&(/ -C *euid!=uid/||/ -C *uid!=euid/) &&/ -S *execve/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
if ($result1 -match "-a always,exit -F arch=b64 -C euid!=uid -F auid!=unset -S execve -k user_emulation" -and $result1 -match "-a always,exit -F arch=b32 -C euid!=uid -F auid!=unset -S execve -k user_emulation" -and $result2 -match "-a always,exit -F arch=b64 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation" -and $result2 -match "-a always,exit -F arch=b32 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.3"
Task = "Ensure events that modify the sudo log file are collected"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_4133_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_4133_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "-w /var/log/sudo.log -p wa -k sudo_log_file" -and $result2 -match "-w /var/log/sudo.log -p wa -k sudo_log_file") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.4"
Task = "Ensure events that modify date and time information are collected"
Test = {
$script_string1 = @'
#!/usr/bin/env bash
{
awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&/ -S/ &&(/adjtimex/ ||/settimeofday/ ||/clock_settime/ ) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
awk '/^ *-w/ &&/\/etc\/localtime/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
}
'@
$script_string2 = @'
#!/usr/bin/env bash
{
auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b[2346]{2}/ &&/ -S/ &&(/adjtimex/ ||/settimeofday/ ||/clock_settime/ ) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
auditctl -l | awk '/^ *-w/ &&/\/etc\/localtime/ &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
}
'@
$result1 = bash -c $script_string1
$result2 = bash -c $script_string2
if ($result1 -match "-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -F key=time-change" -and $result1 -match "-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time-change" -and $result1 -match "-w /etc/localtime -p wa -k time-change" -and
$result2 -match "-w /var/log/sudo.log -p wa -k sudo_log_file" -and $result2 -match "-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -F key=time-change" -and $result2 -match "-w /etc/localtime -p wa -k time-change") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.5"
Task = "Ensure events that modify the system's network environment are collected"
Test = {
$script_string1 = @'
#!/usr/bin/env bash
{
awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&/ -S/ &&(/sethostname/ ||/setdomainname/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
awk '/^ *-w/ &&(/\/etc\/issue/ ||/\/etc\/issue.net/ ||/\/etc\/hosts/ ||/\/etc\/sysconfig\/network/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
}
'@
$script_string2 = @'
#!/usr/bin/env bash
{
auditctl -l | awk '/^ *-a *always,exit/ &&/ -F *arch=b(32|64)/ &&/ -S/ &&(/sethostname/ ||/setdomainname/) &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
auditctl -l | awk '/^ *-w/ &&(/\/etc\/issue/ ||/\/etc\/issue.net/ ||/\/etc\/hosts/ ||/\/etc\/sysconfig\/network/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
}
'@
$result1 = bash -c $script_string1
$result2 = bash -c $script_string2
if ($result1 -match "-a always,exit -F arch=b64 -S sethostname,setdomainname -k system-locale" -and $result1 -match "-a always,exit -F arch=b32 -S sethostname,setdomainname -k system-locale" -and $result1 -match "-w /etc/issue -p wa -k system-locale" -and $result1 -match "-w /etc/issue.net -p wa -k system-locale" -and $result1 -match "-w /etc/hosts -p wa -k system-locale" -and $result1 -match "-w /etc/sysconfig/network -p wa -k system-locale" -and $result1 -match "-w /etc/sysconfig/network-scripts/ -p wa -k system-locale" -and
$result2 -match "-a always,exit -F arch=b64 -S sethostname,setdomainname -F key=system-locale" -and $result2 -match "-a always,exit -F arch=b32 -S sethostname,setdomainname -F key=system-locale" -and $result2 -match "-w /etc/issue -p wa -k system-locale" -and $result2 -match "-w /etc/issue.net -p wa -k system-locale" -and $result2 -match "-w /etc/hosts -p wa -k system-locale" -and $result2 -match "-w /etc/sysconfig/network -p wa -k system-locale" -and $result2 -match "-w /etc/sysconfig/network-scripts -p wa -k system-locale") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.6"
Task = "Ensure use of privileged commands are collected"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_4136_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_4136_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "Warning" -or $result2 -match "Warning") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.7"
Task = "Ensure unsuccessful file access attempts are collected"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_4137_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_4137_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access" -and $result1 -match "-a always,exit -F arch=b64 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access" -and $result1 -match "-a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access" -and $result1 -match "-a always,exit -F arch=b32 -S creat,open,openat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access" -and
$result2 -match "-a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access" -and $result2 -match "-a always,exit -F arch=b64 -S open,truncate,ftruncate,creat,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access" -and $result2 -match "-a always,exit -F arch=b32 -S open,truncate,ftruncate,creat,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access" -and $result2 -match "-a always,exit -F arch=b32 -S open,truncate,ftruncate,creat,openat -F exit=-EPERM -F auid>=1000 -F auid!=-1 -F key=access") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.8"
Task = "Ensure events that modify user/group information are collected"
Test = {
$script_string1 = @'
#!/usr/bin/env bash
{
awk '/^ *-w/ &&(/\/etc\/group/ ||/\/etc\/passwd/ ||/\/etc\/gshadow/ ||/\/etc\/shadow/ ||/\/etc\/security\/opasswd/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
}
'@
$script_string2 = @'
#!/usr/bin/env bash
{
auditctl -l | awk '/^ *-w/ &&(/\/etc\/group/ ||/\/etc\/passwd/ ||/\/etc\/gshadow/ ||/\/etc\/shadow/ ||/\/etc\/security\/opasswd/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
}
'@
$result1 = bash -c $script_string1
$result2 = bash -c $script_string2
if ($result1 -match "-w /etc/group -p wa -k identity" -and $result1 -match "-w /etc/passwd -p wa -k identity" -and $result1 -match "-w /etc/gshadow -p wa -k identity" -and $result1 -match "-w /etc/shadow -p wa -k identity" -and $result1 -match "-w /etc/security/opasswd -p wa -k identity" -and
$result2 -match "-w /etc/group -p wa -k identity" -and $result2 -match "-w /etc/passwd -p wa -k identity" -and $result2 -match "-w /etc/gshadow -p wa -k identity" -and $result2 -match "-w /etc/shadow -p wa -k identity" -and $restul2 -match "-w /etc/security/opasswd -p wa -k identity") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.9"
Task = "Ensure discretionary access control permission modification events are collected"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_4139_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_4139_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod" -and $result1 -match "-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod" -and $result1 -match "-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod" -and
$result1 -match "-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod" -and $result1 -match "-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod" -and $result1 -match "-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod" -and
$result2 -match "-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and $result2 -match "-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and $result2 -match "-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and
$result2 -match "-a always,exit -F arch=b32 -S lchown,fchown,chown,fchownat -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and $result2 -match "-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod" -and $result2 -match "-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=-1 -F key=perm_mod") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.10"
Task = "Ensure successful file system mounts are collected"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_41310_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_41310_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=unset -k mounts" -and $result1 -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=unset -k mounts" -and
$result2 -match "-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts" -and $result2 -match "-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=-1 -F key=mounts") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.11"
Task = "Ensure session initiation information is collected"
Test = {
$script_string1 = @'
#!/usr/bin/env bash
{
awk '/^ *-w/ &&(/\/var\/run\/utmp/ ||/\/var\/log\/wtmp/ ||/\/var\/log\/btmp/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
}
'@
$script_string2 = @'
#!/usr/bin/env bash
{
auditctl -l | awk '/^ *-w/ &&(/\/var\/run\/utmp/ ||/\/var\/log\/wtmp/ ||/\/var\/log\/btmp/) &&/ +-p *wa/ &&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
}
'@
$result1 = bash -c $script_string1
$result2 = bash -c $script_string2
if ($result1 -match "-w /var/run/utmp -p wa -k session" -and $result1 -match "-w /var/log/wtmp -p wa -k session" -and $result1 -match "-w /var/log/btmp -p wa -k session" -and
$result2 -match "-w /var/run/utmp -p wa -k session" -and $result2 -match "-w /var/log/wtmp -p wa -k session" -and $result2 -match "-w /var/log/btmp -p wa -k session") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.12"
Task = "Ensure login and logout events are collected"
Test = {
$script_string1 = @'
#!/usr/bin/env bash
{
awk '/^ *-w/ \
&&(/\/var\/log\/lastlog/ \
||/\/var\/run\/faillock/) \
&&/ +-p *wa/ \
&&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)' /etc/audit/rules.d/*.rules
}
'@
$script_string2 = @'
#!/usr/bin/env bash
{
auditctl -l | awk '/^ *-w/ \
&&(/\/var\/log\/lastlog/ \
||/\/var\/run\/faillock/) \
&&/ +-p *wa/ \
&&(/ key= *[!-~]* *$/||/ -k *[!-~]* *$/)'
}
'@
$result1 = bash -c $script_string1
$result2 = bash -c $script_string2
if ($result1 -match "-w /var/log/lastlog -p wa -k logins" -and $result1 -match "-w /var/run/faillock -p wa -k logins" -and
$result2 -match "-w /var/log/lastlog -p wa -k logins" -and $result2 -match "-w /var/run/faillock -p wa -k logins") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.13"
Task = "Ensure file deletion events by users are collected"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_41313_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_41313_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=unset -k delete" -and $result1 -match "-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=unset -k delete" -and
$result2 -match "-a always,exit -F arch=b64 -S rename,unlink,unlinkat,renameat -F auid>=1000 -F auid!=-1 -F key=delete" -and $result2 -match "-a always,exit -F arch=b32 -S unlink,rename,unlinkat,renameat -F auid>=1000 -F auid!=-1 -F key=delete") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.14"
Task = "Ensure events that modify the system's Mandatory Access Controls are collected"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_41314_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_41314_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "-w /etc/selinux -p wa -k MAC-policy" -and $result1 -match "-w /usr/share/selinux -p wa -k MAC-policy" -and
$result2 -match "-w /etc/selinux -p wa -k MAC-policy" -and $result2 -match "-w /usr/share/selinux -p wa -k MAC-policy") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.15"
Task = "Ensure successful and unsuccessful attempts to use the chcon command are recorded"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_41315_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_41315_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=unset -k perm_chng" -and
$result2 -match "-a always,exit -S all -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=-1 -F key=perm_chng") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.16"
Task = "Ensure successful and unsuccessful attempts to use the setfacl command are recorded"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_41316_1.sh"
$resultScript2 = $scriptPath + "CIS100_RHEL9_41316_2.sh"
$result1 = bash $resultScript1
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=unset -k perm_chng" -and
$result2 -match "-a always,exit -S all -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=-1 -F key=perm_chng") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.17"
Task = "Ensure successful and unsuccessful attempts to use the chacl command are recorded"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_41317_1.sh"
$resultScript2 = $scriptPath + "CIS100_RHEL9_41317_2.sh"
$result1 = bash $resultScript1
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=unset -k perm_chng" -and
$result2 -match "-a always,exit -S all -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=-1 -F key=perm_chng") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.18"
Task = "Ensure successful and unsuccessful attempts to use the usermod command are recorded"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_41318_1.sh"
$resultScript2 = $scriptPath + "CIS100_RHEL9_41318_2.sh"
$result1 = bash $resultScript1
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=unset -k usermod" -and
$result2 -match "-a always,exit -S all -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=-1 -F key=usermod") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.19"
Task = "Ensure kernel module loading unloading and modification is collected"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_41319_1.sh"
$resultScript2 = $scriptPath + "CIS100_RHEL9_41319_2.sh"
$result1 = bash $resultScript1
$result2 = bash $resultScript2
if ($result1 -match "-a always,exit -F arch=b64 -S init_module,finit_module,delete_module,create_module,query_module -F auid>=1000 -F auid!=unset -k kernel_modules" -and $result1 -match "-a always,exit -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=unset -k kernel_modules" -and
$result2 -match "-a always,exit -F arch=b64 -S create_module,init_module,delete_module,query_module,finit_module -F auid>=1000 -F auid!=-1 -F key=kernel_modules" -and $result2 -match "-a always,exit -S all -F path=/usr/bin/kmod -F perm=x -F auid>=1000 -F auid!=-1 -F key=kernel_modules" -and $result3 -match "OK") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.20"
Task = "Ensure the audit configuration is immutable"
Test = {
$result1 = grep -Ph -- '^\h*-e\h+2\b' /etc/audit/rules.d/*.rules | tail -1
if ($result1 -match "-e 2") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.3.21"
Task = "Ensure the running and on disk configuration is the same"
Test = {
$result1 = augenrules --check
if ($result1 -match "/usr/sbin/augenrules: No change") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.1"
Task = "Ensure audit log files are mode 0640 or less permissive"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_4141.sh"
$result = bash $resultScript
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.2"
Task = "Ensure only authorized users own audit log files"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_3412.sh"
$result = bash $resultScript
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.3"
Task = "Ensure only authorized groups are assigned ownership of audit log files"
Test = {
$script_string1 = @'
#!/usr/bin/env bash
{
stat -c "%n %G" "$(dirname $(awk -F"=" '/^\s*log_file\s*=\s*/ {print $2}' /etc/audit/auditd.conf | xargs))"/* | grep -Pv '^\h*\H+\h+(adm|root)\b'
}
'@
$result1 = bash -c $script_string1
$result2 = grep -Piw -- '^\h*log_group\h*=\h*(adm|root)\b' /etc/audit/auditd.conf
if (($result1 -match "log_group = adm" -or $result1 -match "log_group = root") -and $result2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.4"
Task = "Ensure the audit log directory is 0750 or more restrictive"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_4144.sh"
$result = bash $resultScript
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.5"
Task = "Ensure audit configuration files are 640 or more restrictive"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_4145.sh"
$result = bash $resultScript
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.6"
Task = "Ensure audit configuration files are owned by root"
Test = {
$result1_string = @'
#!/usr/bin/env bash
{
find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) ! -user root
}
'@
$result1 = bash -c $result1_string
if ($result1 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.7"
Task = "Ensure audit configuration files belong to group root"
Test = {
$result1_string = @'
#!/usr/bin/env bash
{
find /etc/audit/ -type f \( -name '*.conf' -o -name '*.rules' \) ! -group root
}
'@
$result1 = bash -c $result1_string
if ($result1 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.8"
Task = "Ensure audit tools are 755 or more restrictive"
Test = {
$result1 = stat -c "%n %a" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+([0-7][0,1,4,5][0,1,4,5])\h*$'
if ($result1 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.9"
Task = "Ensure audit tools are owned by root"
Test = {
$result1 = stat -c "%n %U" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+root\h*$'
if ($result1 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.1.4.10"
Task = "Ensure audit tools belong to group root"
Test = {
$result1 = stat -c "%n %a %U %G" /sbin/auditctl /sbin/aureport /sbin/ausearch /sbin/autrace /sbin/auditd /sbin/augenrules | grep -Pv -- '^\h*\H+\h+([0-7][0,1,4,5][0,1,4,5])\h+root\h+root\h*$'
if ($result1 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.1.1"
Task = "Ensure rsyslog is installed"
Test = {
$result1 = rpm -q rsyslog
if ($result1 -match "rsyslog-") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.1.2"
Task = "Ensure rsyslog service is enabled"
Test = {
$result1 = systemctl is-enabled rsyslog
if ($result1 -match "enabled") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.1.3"
Task = "Ensure journald is configured to send logs to rsyslog"
Test = {
$result1 = grep ^\s*ForwardToSyslog /etc/systemd/journald.conf
if ($result1 -match "ForwardToSyslog=yes") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.1.4"
Task = "Ensure journald is configured to send logs to rsyslog"
Test = {
$result1 = grep -Ps '^\h*\$FileCreateMode\h+0[0,2,4,6][0,2,4]0\b' /etc/rsyslog.conf /etc/rsyslog.d/*.conf
if ($result1 -match "FileCreateMode 0640") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.1.5"
Task = "Ensure logging is configured"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "4.2.1.6"
Task = "Ensure rsyslog is configured to send logs to a remote log host"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "4.2.1.7"
Task = "Ensure journald is configured to send logs to rsyslog"
Test = {
$result1 = grep -Ps -- '^\h*module\(load="imtcp"\)' /etc/rsyslog.conf /etc/rsyslog.d/*.conf
$result2 = grep -Ps -- '^\h*input\(type="imtcp" port="514"\)' /etc/rsyslog.conf /etc/rsyslog.d/*.conf
if ($result1 -eq $null -and $result2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.2.1.1"
Task = "Ensure journald is configured to send logs to rsyslog"
Test = {
$result1 = rpm -q systemd-journal-remote
if ($result1 -eq "systemd-journal-remote-") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.2.1.2"
Task = "Ensure systemd-journal-remote is configured"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "4.2.2.1.3"
Task = "Ensure systemd-journal-remote is enabled"
Test = {
$result1 = systemctl is-enabled systemd-journal-upload.service
if ($result1 -match "enabled") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.2.1.4"
Task = "Ensure journald is not configured to receive logs from a remote client"
Test = {
$result1 = systemctl is-enabled systemd-journal-remote.socket
if ($result1 -match "masked") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.2.2"
Task = "Ensure journald service is enabled"
Test = {
$result1 = systemctl is-enabled systemd-journald.service
if ($result1 -match "static") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.2.3"
Task = "Ensure journald is configured to compress large log files"
Test = {
$result1 = grep ^\s*Compress /etc/systemd/journald.conf
if ($result1 -match "Compress=yes") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.2.4"
Task = "Ensure journald is configured to write logfiles to persistent disk"
Test = {
$result1 = grep ^\s*Storage /etc/systemd/journald.conf
if ($result1 -match "Storage=persistent") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.2.2.5"
Task = "Ensure journald is not configured to send logs to rsyslog"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "4.2.2.6"
Task = "Ensure journald log rotation is configured per site policy"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "4.2.2.7"
Task = "Ensure journald default file permissions configured"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "4.2.3"
Task = "Ensure all logfiles have appropriate permissions and ownership"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
echo -e "\n- Start check - logfiles have appropriate permissions and ownership"
output=""
UID_MIN=$(awk '/^\s*UID_MIN/{print $2}' /etc/login.defs)
find /var/log -type f | (while read -r fname; do
bname="$(basename "$fname")"
fugname="$(stat -Lc "%U %G" "$fname")"
funame="$(awk '{print $1}' <<< "$fugname")"
fugroup="$(awk '{print $2}' <<< "$fugname")"
fuid="$(stat -Lc "%u" "$fname")"
fmode="$(stat -Lc "%a" "$fname")"
case "$bname" in lastlog | lastlog.* | wtmp | wtmp.* | wtmp-* | btmp | btmp.* | btmp-*)
if ! grep -Pq -- '^\h*[0,2,4,6][0,2,4,6][0,4]\h*$' <<< "$fmode"; then
output="$output\n- File: \"$fname\" mode: \"$fmode\"\n"
fi
if ! grep -Pq -- '^\h*root\h+(utmp|root)\h*$' <<< "$fugname"; then
output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n"
fi
;;
secure | auth.log | syslog | messages)
if ! grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$' <<< "$fmode"; then
output="$output\n- File: \"$fname\" mode: \"$fmode\"\n"
fi
if ! grep -Pq -- '^\h*(syslog|root)\h+(adm|root)\h*$' <<< "$fugname"; then
output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n"
fi
;;
SSSD | sssd)
if ! grep -Pq -- '^\h*[0,2,4,6][0,2,4,6]0\h*$' <<< "$fmode"; then
output="$output\n- File: \"$fname\" mode: \"$fmode\"\n"
fi
if ! grep -Piq -- '^\h*(SSSD|root)\h+(SSSD|root)\h*$' <<< "$fugname"; then
output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n"
fi
;;
gdm | gdm3)
if ! grep -Pq -- '^\h*[0,2,4,6][0,2,4,6]0\h*$' <<< "$fmode"; then
output="$output\n- File: \"$fname\" mode: \"$fmode\"\n"
fi
if ! grep -Pq -- '^\h*(root)\h+(gdm3?|root)\h*$' <<< "$fugname"; then
output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n"
fi
;;
*.journal | *.journal~)
if ! grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$' <<< "$fmode"; then
output="$output\n- File: \"$fname\" mode: \"$fmode\"\n"
fi
if ! grep -Pq -- '^\h*(root)\h+(systemd-journal|root)\h*$' <<< "$fugname"; then
output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n"
fi
;;
*) if ! grep -Pq -- '^\h*[0,2,4,6][0,4]0\h*$' <<< "$fmode"; then
output="$output\n- File: \"$fname\" mode: \"$fmode\"\n"
fi
if [ "$fuid" -ge "$UID_MIN" ] || ! grep -Pq -- '(adm|root|'"$(id -gn "$funame")"')' <<< "$fugroup"; then
if [ -n "$(awk -v grp="$fugroup" -F: '$1==grp {print $4}' /etc/group)" ] || ! grep -Pq '(syslog|root)' <<< "$funame"; then
output="$output\n- File: \"$fname\" ownership: \"$fugname\"\n"
fi
fi
;;
esac
done # If all files passed, then we pass
if [ -z "$output" ]; then
echo -e "\n- Audit Results:\n PASS\n- All files in \"/var/log/\" have appropriate permissions and ownership\n"
else # print the reason why we are failing
echo -e "\n- Audit Results:\n FAIL\n$output"
fi
echo -e "- End check - logfiles have appropriate permissions and ownership\n"
)
}
'@
$script = bash -c $script_string
if ($script -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "4.3"
Task = "Ensure logrotate is configured"
Test = {
return $retNonCompliantManualReviewRequired
}
}
### Chapter 5 - Access, Authentication and Authorization
[AuditTest] @{
Id = "5.1.1"
Task = "Ensure cron daemon is enabled"
Test = {
$result1 = systemctl is-enabled crond
if ($result1 -match "enabled") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.1.2"
Task = "Ensure permissions on /etc/crontab are configured"
Test = {
$result1 = stat -c "%a" /etc/crontab
if ($result1 -eq 600 ) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.1.3"
Task = "Ensure permissions on /etc/cron.hourly are configured"
Test = {
$result1 = stat -c "%a" /etc/cron.hourly
if ($result1 -eq 700 ) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.1.4"
Task = "Ensure permissions on /etc/cron.daily are configured"
Test = {
$result1 = stat -c "%a" /etc/cron.daily
if ($result1 -eq 700 ) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.1.5"
Task = "Ensure permissions on /etc/cron.weekly are configured"
Test = {
$result1 = stat -c "%a" /etc/cron.weekly
if ($result1 -eq 700 ) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.1.6"
Task = "Ensure permissions on /etc/cron.monthly are configured"
Test = {
$result1 = stat -c "%a" /etc/cron.monthly
if ($result1 -eq 700 ) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.1.7"
Task = "Ensure permissions on /etc/cron.d are configured"
Test = {
$result1 = stat -c "%a" /etc/cron.d
if ($result1 -eq 700 ) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.1.8"
Task = "Ensure cron is restricted to authorized users"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
if rpm -q cronie >/dev/null; then
[ -e /etc/cron.deny ] && echo "Fail: cron.deny exists"
if [ ! -e /etc/cron.allow ]; then
echo "Fail: cron.allow doesn't exist"
else
! stat -Lc "%a" /etc/cron.allow | grep -Eq "[0,2,4,6]00" && echo "Fail: cron.allow mode too permissive"
! stat -Lc "%u:%g" /etc/cron.allow | grep -Eq "^0:0$" && echo "Fail: cron.allow owner and/or group not root"
fi
if [ ! -e /etc/cron.deny ] && [ -e /etc/cron.allow ] && stat -Lc "%a" /etc/cron.allow | grep -Eq "[0,2,4,6]00" \ && stat -Lc "%u:%g" /etc/cron.allow | grep -Eq "^0:0$"; then
echo "Pass"
fi
else
echo "PASS: cron is not installed on the system"
fi
}
'@
$script = bash -c $script_string
if ($script -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.1.9"
Task = "Ensure at is restricted to authorized users"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
if rpm -q at >/dev/null; then
[ -e /etc/at.deny ] && echo "Fail: at.deny exists"
if [ ! -e /etc/at.allow ]; then
echo "Fail: at.allow doesn't exist"
else
! stat -Lc "%a" /etc/at.allow | grep -Eq "[0,2,4,6]00" && echo "Fail: at.allow mode too permissive"
! stat -Lc "%u:%g" /etc/at.allow | grep -Eq "^0:0$" && echo "Fail: at.allow owner and/or group not root"
fi
if [ ! -e /etc/at.deny ] && [ -e /etc/at.allow ] && stat -Lc "%a" /etc/at.allow | grep -Eq "[0,2,4,6]00" && stat -Lc "%u:%g" /etc/at.allow | grep -Eq "^0:0$"; then
echo "PASS"
fi
else
echo "PASS: at is not installed on the system"
fi
}
'@
$script = bash -c $script_string
if ($script -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.1"
Task = "Ensure permissions on /etc/ssh/sshd_config are configured"
Test = {
$result1 = stat -Lc "%n %a %u/%U %g/%G" /etc/ssh/sshd_config
if ($result1 -match "/etc/ssh/sshd_config 600 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.2"
Task = "Ensure permissions on SSH private host key files are configured"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_522.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.3"
Task = "Ensure permissions on SSH public host key files are configured"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_523.sh"
$result = bash $resultScript
if ($result -match "PASS") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.4"
Task = "Ensure SSH access is limited"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$'
$test2 = grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' /etc/ssh/sshd_config
if ($test1 -match "allowusers " -or $test1 -match "allowgroups " -or $test1 -match "denyusers " -or $test1 -match "denygroups " -or
$test2 -match "allowusers " -or $test2 -match "allowgroups " -or $test2 -match "denyusers " -or $test2 -match "denygroups ") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.5"
Task = "Ensure SSH LogLevel is appropriate"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$'
$test2 = grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' /etc/ssh/sshd_config
if (($test1 -match "allowusers " -or $test1 -match "allowgroups " -or $test1 -match "denyusers " -or $test1 -match "denygroups ") -and
($test2 -match "allowusers " -or $test2 -match "allowgroups " -or $test2 -match "denyusers " -or $test2 -match "denygroups ")) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.6"
Task = "Ensure SSH PAM is enabled"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i usepam
$test2 = grep -Pi '^\h*(allow|deny)(users|groups)\h+\H+(\h+.*)?$' /etc/ssh/sshd_config
if ($test1 -match "usepam yes" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.7"
Task = "Ensure SSH root login is disabled"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitrootlogin
$test2 = grep -Ei '^\s*PermitRootLogin\s+yes' /etc/ssh/sshd_config
if ($test1 -match "permitrootlogin no" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.8"
Task = "Ensure SSH HostbasedAuthentication is disabled"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep hostbasedauthentication
$test2 = grep -Ei '^\s*HostbasedAuthentication\s+yes' /etc/ssh/sshd_config
if ($test1 -match "permitrootlogin no" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.9"
Task = "Ensure SSH PermitEmptyPasswords is disabled"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permitemptypasswords
$test2 = grep -Ei '^\s*PermitEmptyPasswords\s+yes' /etc/ssh/sshd_config
if ($test1 -match "permitemptypasswords no" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.10"
Task = "Ensure SSH PermitUserEnvironment is disabled"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep permituserenvironment
$test2 = grep -Ei '^\s*PermitUserEnvironment\s+yes' /etc/ssh/sshd_config
if ($test1 -match "permituserenvironment no" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.11"
Task = "Ensure SSH IgnoreRhosts is enabled"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep ignorerhosts
$test2 = grep -Ei '^\s*ignorerhosts\s+no\b' /etc/ssh/sshd_config
if ($test1 -match "ignorerhosts yes" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.12"
Task = "Ensure SSH X11 forwarding is disabled"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i x11forwarding
$test2 = grep -Ei '^\s*x11forwarding\s+yes' /etc/ssh/sshd_config
if ($test1 -match "x11forwarding no" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.13"
Task = "Ensure SSH AllowTcpForwarding is disabled"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i allowtcpforwarding
$test2 = grep -Ei '^\s*AllowTcpForwarding\s+yes' /etc/ssh/sshd_config
if ($test1 -match "allowtcpforwarding no" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.14"
Task = "Ensure system-wide crypto policy is not over-ridden"
Test = {
$test = grep -i '^\s*CRYPTO_POLICY=' /etc/sysconfig/sshd
if ($test -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.15"
Task = "Ensure SSH warning banner is configured"
Test = {
$test = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep banner
if ($test -match "banner /etc/issue.net") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.16"
Task = "Ensure SSH MaxAuthTries is set to 4 or less"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep maxauthtries
$test2 = grep -Ei '^\s*maxauthtries\s+([5-9]|[1-9][0-9]+)' /etc/ssh/sshd_config
if ($test1 -match "maxauthtries 4" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.17"
Task = "Ensure SSH MaxStartups is configured"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i maxstartups
$test2 = grep -Ei '^\s*maxstartups\s+(((1[1-9]|[1-9][0-9][0-9]+):([0-9]+):([0-9]+))|(([0-9]+):(3[1-9]|[4-9][0-9]|[1-9][0-9][0-9]+):([0-9]+))|(([0-9]+):([0-9]+):(6[1-9]|[7-9][0-9]|[1-9][0-9][0-9]+)))' /etc/ssh/sshd_config
if ($test1 -match "maxstartups 10:30:60" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.18"
Task = "Ensure SSH MaxSessions is set to 10 or less"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep -i maxsessions
$test2 = grep -Ei '^\s*MaxSessions\s+(1[1-9]|[2-9][0-9]|[1-9][0-9][0-9]+)' /etc/ssh/sshd_config
if ($test1 -match "maxsessions 10" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.19"
Task = "Ensure SSH LoginGraceTime is set to one minute or less"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep logingracetime
$test2 = grep -Ei '^\s*LoginGraceTime\s+(0|6[1-9]|[7-9][0-9]|[1-9][0-9][0-9]+|[^1]m)' /etc/ssh/sshd_config
if ($test1 -match "logingracetime 60" -and $test2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.2.20"
Task = "Ensure SSH Idle Timeout Interval is configured"
Test = {
$test1 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep clientaliveinterval | cut -d ' ' -f 2
$test2 = sshd -T -C user=root -C host="$(hostname)" -C addr="$(grep $(hostname) /etc/hosts | awk '{print $1}')" | grep clientalivecountmax | cut -d ' ' -f 2
if ($test1 -gt 0 -and $test2 -gt 0) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.3.1"
Task = "Ensure SUDO is installed"
Test = {
$test = dnf list sudo | grep sudo.x86_64
if ($test -match "sudo") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.3.2"
Task = "Ensure sudo commands use pty"
Test = {
$test = grep -rPi '^\h*Defaults\h+([^#\n\r]+,)?use_pty(,\h*\h+\h*)*\h*(#.*)?$' /etc/sudoers*
if ($test -match "/etc/sudoers:Defaults use_pty") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.3.3"
Task = "Ensure sudo log file exists"
Test = {
$test = grep -Ei '^\s*Defaults\s+logfile=\S+' /etc/sudoers /etc/sudoers.d/*
if ($test -match "/etc/sudoers:Defaults use_pty") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.3.4"
Task = "Ensure users must provide password for escalation"
Test = {
$test = grep -r "^[^#].*NOPASSWD" /etc/sudoers*
if ($test -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.3.5"
Task = "Ensure re-authentication for privilege escalation is not disabled globally"
Test = {
$test = grep -r "^[^#].*\!authenticate" /etc/sudoers*
if ($test -match "!authenticate") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "5.3.6"
Task = "Ensure sudo authentication timeout is configured correctly"
Test = {
$test = grep -roP "timestamp_timeout=\K[0-9]*" /etc/sudoers* | cut -d ' ' -f 2
if ($test -le 15) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.3.7"
Task = "Ensure access to the su command is restricted"
Test = {
$test1 = grep -Pi '^\h*auth\h+(?:required|requisite)\h+pam_wheel\.so\h+(?:[^#\n\r]+\h+)?((?!\2)(use_uid\b|group=\H+\b))\h+(?:[^#\n\r]+\h+)?((?!\1)(use_uid\b|group=\H+\b))(\h+.*)?$' /etc/pam.d/su
if ($test1 -match "auth required pam_wheel.so use_uid group=") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.4.1"
Task = "Ensure custom authselect profile is used"
Test = {
$test1 = authselect list | grep '^-\s*custom'
if ($test1 -eq $null) {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
# 5.4.2 ist leider schlecht beschrieben, die Pruefung ist mit ihren Parametern bestenfalls mangelhaft
[AuditTest] @{
Id = "5.4.2"
Task = "Ensure authselect includes with-faillock"
Test = {
$test1 = grep pam_faillock.so /etc/pam.d/password-auth /etc/pam.d/system-auth
if ($test1 -match "/etc/authselect/password-auth:auth") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.5.1"
Task = "Ensure password creation requirements are configured"
Test = {
$test1 = grep ^minlen /etc/security/pwquality.conf | cut -d '=' -f 2
if ($test1 -ge 14) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.5.2"
Task = "Ensure lockout for failed password attempts is configured"
Test = {
$test1 = grep -E '^\s*deny\s*=\s*[1-5]\b' /etc/security/faillock.conf | cut -d '=' -f 2
$test2 = grep -E '^\s*unlock_time\s*=\s*(0|9[0-9][0-9]|[1-9][0-9][0-9][0-9]+)\b' /etc/security/faillock.conf | cut -d '=' -f 2
if ($test1 -le 5 -and ($test2 -eq 0 -or $test2 -ge 900)) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.5.3"
Task = "Ensure password reuse is limited"
Test = {
$test1 = grep -P '^\h*password\h+(requisite|sufficient)\h+(pam_pwhistory\.so|pam_unix\.so)\h+([^#\n\r]+\h+)?remember=([5-9]|[1-9][0-9]+)\h*(\h+.*)?$' /etc/pam.d/system-auth
if ($test1 -match "remember=5") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.5.4"
Task = "Ensure password hashing algorithm is SHA-512 or yescrypt"
Test = {
$test1 = grep -Ei '^\s*crypt_style\s*=\s*(sha512|yescrypt)\b' /etc/libuser.conf
$test2 = grep -Ei '^\s*ENCRYPT_METHOD\s+(SHA512|yescrypt)\b' /etc/login.defs
if (($test2 -match "ENCRYPT_METHOD SHA512" -or $test2 -match "ENCRYPT_METHOD YESCRYPT") -and ($test1 -match "crypt_style = sha512" -or $test1 -match "crypt_style = yescrypt")) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.1.1"
Task = "Ensure password expiration is 365 days or less"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_5611_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_5611_2.sh"
$result2 = bash $resultScript2
if ($result1 -le 365 -and $result2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.1.2"
Task = "Ensure minimum days between password changes is configured"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_5612_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_5612_2.sh"
$result2 = bash $resultScript2
if ($result1 -ge 1 -and $result2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.1.3"
Task = "Ensure password expiration warning days is 7 or more"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_5613_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_5613_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "PASS_WARN_AGE\s*7" -and !($result2 -match "FAIL")) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.1.4"
Task = "Ensure inactive password lock is 30 days or less"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_5614_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_5614_2.sh"
$result2 = bash $resultScript2
if ($result1 -ge 2 -and $result2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.1.5"
Task = "Ensure all users last password change date is in the past"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_5615.sh"
$result = bash $resultScript
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.2"
Task = "Ensure system accounts are secured"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_562_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_562_2.sh"
$result2 = bash $resultScript2
if ($result1 -eq $null -and $result2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.3"
Task = "Ensure default user shell timeout is 900 seconds or less"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
output1="" output2=""
[ -f /etc/bashrc ] && BRC="/etc/bashrc"
for f in "$BRC" /etc/profile /etc/profile.d/*.sh ; do
grep -Pq '^\s*([^#]+\s+)?TMOUT=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9])\b' "$f" && grep -Pq '^\s*([^#]+;\s*)?readonly\s+TMOUT(\s+|\s*;|\s*$|=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9]))\b' "$f" && grep -Pq '^\s*([^#]+;\s*)?export\s+TMOUT(\s+|\s*;|\s*$|=(900|[1-8][0-9][0-9]|[1-9][0-9]|[1-9]))\b' "$f" && output1="$f"
done
grep -Pq '^\s*([^#]+\s+)?TMOUT=(9[0-9][1-9]|9[1-9][0-9]|0+|[1-9]\d{3,})\b' /etc/profile /etc/profile.d/*.sh "$BRC" && output2=$(grep -Ps '^\s*([^#]+\s+)?TMOUT=(9[0-9][1-9]|9[1-9][0-9]|0+|[1-9]\d{3,})\b' /etc/profile /etc/profile.d/*.sh $BRC)
if [ -n "$output1" ] && [ -z "$output2" ]; then
echo -e "\nPASSED\n\nTMOUT is configured in: \"$output1\"\n"
else
[ -z "$output1" ] && echo -e "\nFAILED\n\nTMOUT is not configured\n" [ -n "$output2" ] && echo -e "\nFAILED\n\nTMOUT is incorrectly configured in: \"$output2\"\n"
fi
}
'@
$script = bash -c $script_string
if ($script -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.4"
Task = "Ensure default group for the root account is GID 0"
Test = {
$test1 = grep "^root:" /etc/passwd | cut -f4 -d ':'
if ($test1 -eq 0) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.5"
Task = "Ensure default user shell timeout is 900 seconds or less"
Test = {
$resultScript1 = $scriptPath + "CIS100_RHEL9_565_1.sh"
$result1 = bash $resultScript1
$resultScript2 = $scriptPath + "CIS100_RHEL9_565_2.sh"
$result2 = bash $resultScript2
if ($result1 -match "umask is set" -and $result2 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "5.6.6"
Task = "Ensure root password is set"
Test = {
$test1 = passwd -S root
if ($test1 -match "Password set") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
### Chapter 6 - System Maintenance
[AuditTest] @{
Id = "6.1.1"
Task = "Ensure permissions on /etc/passwd are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/passwd
if ($test1 -match "644 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.2"
Task = "Ensure permissions on /etc/passwd are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/passwd-
if ($test1 -match "644 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.3"
Task = "Ensure permissions on /etc/group are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/group
if ($test1 -match "644 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.4"
Task = "Ensure permissions on /etc/group- are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/group-
if ($test1 -match "644 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.5"
Task = "Ensure permissions on /etc/shadow are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/shadow
if ($test1 -match "0 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.6"
Task = "Ensure permissions on /etc/shadow- are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/shadow-
if ($test1 -match "0 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.7"
Task = "Ensure permissions on /etc/gshadow are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/gshadow
if ($test1 -match "0 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.7"
Task = "Ensure permissions on /etc/gshadow are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/gshadow
if ($test1 -match "0 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.8"
Task = "Ensure permissions on /etc/gshadow- are configured"
Test = {
$test1 = stat -Lc "%n %a %u/%U %g/%G" /etc/gshadow-
if ($test1 -match "0 0/root 0/root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.9"
Task = "Ensure no world writable files exist"
Test = {
$test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type f -perm -0002
if ($test1 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.10"
Task = "Ensure no unowned files or directories exist"
Test = {
$test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nouser
if ($test1 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.11"
Task = "Ensure no ungrouped files or directories exist"
Test = {
$test1 = df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -nogroup
if ($test1 -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.12"
Task = "Ensure sticky bit is set on all world-writable directories"
Test = {
$test_string = "df --local -P | awk '{if (NR!=1) print $6}' | xargs -I '{}' find '{}' -xdev -type d \( -perm -0002 -a ! -perm -1000 \) 2>/dev/null"
$test = bash -c $test_string
if ($test -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.1.13"
Task = "Audit SUID executables"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "6.1.14"
Task = "Audit SGID executables"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "6.1.15"
Task = "Audit system file permissions"
Test = {
return $retNonCompliantManualReviewRequired
}
}
[AuditTest] @{
Id = "6.2.1"
Task = "Ensure accounts in /etc/passwd use shadowed passwords"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_621.sh"
$result = bash $resultScript
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.2.2"
Task = "Ensure /etc/shadow password fields are not empty"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_622.sh"
$result = bash $resultScript
if ($result -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.2.3"
Task = "Ensure all groups in /etc/passwd exist in /etc/group"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
for i in $(cut -s -d: -f4 /etc/passwd | sort -u ); do
grep -q -P "^.*?:[^:]*:$i:" /etc/group
if [ $? -ne 0 ]; then
echo "Group $i is referenced by /etc/passwd but does not exist in /etc/group"
fi
done
}
'@
$script = bash -c $script_string
if ($script -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.2.4"
Task = "Ensure no duplicate UIDs exist"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
cut -f3 -d":" /etc/passwd | sort -n | uniq -c | while read x ; do
[ -z "$x" ] && break
set - $x
if [ $1 -gt 1 ]; then
users=$(awk -F: '($3 == n) { print $1 }' n=$2 /etc/passwd | xargs)
echo "Duplicate UID ($2): $users"
fi
done
}
'@
$script = bash -c $script_string
if ($script -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.2.5"
Task = "Ensure no duplicate GIDs exist"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
cut -d: -f3 /etc/group | sort | uniq -d | while read x ; do
echo "Duplicate GID ($x) in /etc/group"
done
}
'@
$script = bash -c $script_string
if ($script -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.2.6"
Task = "Ensure no duplicate user names exist"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
cut -d: -f1 /etc/passwd | sort | uniq -d | while read -r x; do
echo "Duplicate login name $x in /etc/passwd"
done
}
'@
$script = bash -c $script_string
if ($script -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.2.7"
Task = "Ensure no duplicate group names exist"
Test = {
$script_string = @'
#!/usr/bin/env bash
{
cut -d: -f1 /etc/group | sort | uniq -d | while read -r x; do
echo "Duplicate group name $x in /etc/group"
done
}
'@
$script = bash -c $script_string
if ($script -eq $null) {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.2.8"
Task = "Ensure root PATH Integrity"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_628.sh"
$result = bash $resultScript
if ($result -match "is not a directory") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "6.2.9"
Task = "Ensure root is the only UID 0 account"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_629.sh"
$result = bash $resultScript
if ($result -eq "root") {
return $retCompliant
} else {
return $retNonCompliant
}
}
}
[AuditTest] @{
Id = "6.2.10"
Task = "Ensure local interactive user home directories exist"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_6210.sh"
$result = bash $resultScript
if ($result -match "FAILED") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "6.2.11"
Task = "Ensure local interactive users own their home directories"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_6210.sh"
$result = bash $resultScript
if ($result -match "FAILED") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "6.2.12"
Task = "Ensure local interactive user home directories are mode 750 or more restrictive"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_6212.sh"
$result = bash $resultScript
if ($result -match "FAILED") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "6.2.13"
Task = "Ensure no local interactive user has .netrc files"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_6213.sh"
$result = bash $resultScript
if ($result -match "FAILED") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "6.2.14"
Task = "Ensure no local interactive user has .forward files"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_6214.sh"
$result = bash $resultScript
if ($result -match "FAILED") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "6.2.15"
Task = "Ensure no local interactive user has .rhosts files"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_6215.sh"
$result = bash $resultScript
if ($result -match "FAILED") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}
[AuditTest] @{
Id = "6.2.16"
Task = "Ensure local interactive user dot files are not group or world writable"
Test = {
$resultScript = $scriptPath + "CIS100_RHEL9_6216.sh"
$result = bash $resultScript
if ($result -match "Failed") {
return $retNonCompliant
} else {
return $retCompliant
}
}
}