Group
Guide to the Secure Configuration of Oracle Linux 8
Group contains 54 groups and 140 rules |
Group
System Settings
Group contains 28 groups and 44 rules |
[ref]
Contains rules that check correct system settings. |
Group
Installing and Maintaining Software
Group contains 8 groups and 12 rules |
[ref]
The following sections contain information on
security-relevant choices during the initial operating system
installation process and the setup of software
updates. |
Group
System and Software Integrity
Group contains 3 groups and 4 rules |
[ref]
System and software integrity can be gained by installing antivirus, increasing
system encryption strength with FIPS, verifying installed software, enabling SELinux,
installing an Intrusion Prevention System, etc. However, installing or enabling integrity
checking tools cannot prevent intrusions, but they can detect that an intrusion
may have occurred. Requirements for integrity checking may be highly dependent on
the environment in which the system will be used. Snapshot-based approaches such
as AIDE may induce considerable overhead in the presence of frequent software updates. |
Group
Software Integrity Checking
Group contains 1 group and 2 rules |
[ref]
Both the AIDE (Advanced Intrusion Detection Environment)
software and the RPM package management system provide
mechanisms for verifying the integrity of installed software.
AIDE uses snapshots of file metadata (such as hashes) and compares these
to current system files in order to detect changes.
The RPM package management system can conduct integrity
checks by comparing information in its metadata database with
files installed on the system. |
Group
Verify Integrity with RPM
Group contains 2 rules |
[ref]
The RPM package management system includes the ability
to verify the integrity of installed packages by comparing the
installed files with information about the files taken from the
package metadata stored in the RPM database. Although an attacker
could corrupt the RPM database (analogous to attacking the AIDE
database as described above), this check can still reveal
modification of important files. To list which files on the system differ from what is expected by the RPM database:
$ rpm -qVa
See the man page for rpm to see a complete explanation of each column. |
Rule
Verify File Hashes with RPM
[ref] | Without cryptographic integrity protections, system executables and files can be altered by
unauthorized users without detection. The RPM package management system can check the hashes
of installed software packages, including many that are important to system security.
To verify that the cryptographic hash of system files and commands matches vendor values, run
the following command to list which files on the system have hashes that differ from what is
expected by the RPM database:
$ rpm -Va --noconfig | grep '^..5'
If the file was not expected to change, investigate the cause of the change using audit logs
or other means. The package can then be reinstalled to restore the file. Run the following
command to determine which package owns the file:
$ rpm -qf FILENAME
The package can be reinstalled from a yum repository using the command:
$ sudo yum reinstall PACKAGENAME
Alternatively, the package can be reinstalled from trusted media using the command:
$ sudo rpm -Uvh PACKAGENAME
Warning:
This rule can take a long time to perform the check and might consume a considerable
amount of resources depending on the number of packages present on the system. It is not a
problem in most cases, but especially systems with a large number of installed packages
can be affected. | Rationale: | The hashes of important files like system executables should match the
information given by the RPM database. Executables with erroneous hashes could
be a sign of nefarious activity on the system. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_rpm_verify_hashes | References: | cis-csc | 11, 2, 3, 9 | cjis | 5.10.4.1 | cobit5 | APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02 | cui | 3.3.8, 3.4.1 | disa | CCI-000366, CCI-001749 | hipaa | 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4 | isa-62443-2013 | SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6 | iso27001-2013 | A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4 | nist | CM-6(d), CM-6(c), SI-7, SI-7(1), SI-7(6), AU-9(3) | nist-csf | PR.DS-6, PR.DS-8, PR.IP-1 | pcidss | Req-11.5 | os-srg | SRG-OS-000480-GPOS-00227 | pcidss4 | 11.5.2 |
| |
|
Rule
Verify and Correct File Permissions with RPM
[ref] | The RPM package management system can check file access permissions of installed software
packages, including many that are important to system security. Verify that the file
permissions of system files and commands match vendor values. Check the file permissions with
the following command:
$ sudo rpm -Va | awk '{ if (substr($0,2,1)=="M") print $NF }'
Output indicates files that do not match vendor defaults.
After locating a file with incorrect permissions, run the following command to determine which
package owns it:
$ rpm -qf FILENAME
Next, run the following command to reset its permissions to the correct values:
$ sudo rpm --restore PACKAGENAME
Warning:
Profiles may require that specific files have stricter file permissions than defined by
the vendor. Such files will be reported as a finding and need to be evaluated according to
your policy and deployment environment. Warning:
This rule can take a long time to perform the check and might consume a considerable
amount of resources depending on the number of packages present on the system. It is not a
problem in most cases, but especially systems with a large number of installed packages
can be affected. | Rationale: | Permissions on system binaries and configuration files that are too generous could allow an
unauthorized user to gain privileges that they should not have. The permissions set by the
vendor should be maintained. Any deviations from this baseline should be investigated. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_rpm_verify_permissions | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 18, 3, 5, 6, 9 | cjis | 5.10.4.1 | cobit5 | APO01.06, APO11.04, BAI03.05, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.04, DSS05.07, DSS06.02, MEA02.01 | cui | 3.3.8, 3.4.1 | disa | CCI-001493, CCI-001494, CCI-001495, CCI-001496 | hipaa | 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i) | isa-62443-2009 | 4.3.3.3.9, 4.3.3.5.8, 4.3.3.7.3, 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 2.1, SR 2.10, SR 2.11, SR 2.12, SR 2.8, SR 2.9, SR 5.2, SR 7.6 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.2, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.5.1, A.12.6.2, A.12.7.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R4.2, CIP-003-8 R6, CIP-007-3 R4, CIP-007-3 R4.1, CIP-007-3 R4.2 | nist | CM-6(d), CM-6(c), SI-7, SI-7(1), SI-7(6), AU-9(3), CM-6(a) | nist-csf | PR.AC-4, PR.DS-5, PR.IP-1, PR.PT-1 | pcidss | Req-11.5 | os-srg | SRG-OS-000256-GPOS-00097, SRG-OS-000257-GPOS-00098, SRG-OS-000258-GPOS-00099, SRG-OS-000278-GPOS-00108 | pcidss4 | 11.5.2 |
| |
|
Group
System Cryptographic Policies
Group contains 2 rules |
[ref]
Linux has the capability to centrally configure cryptographic polices. The command
update-crypto-policies is used to set the policy applicable for the various
cryptographic back-ends, such as SSL/TLS libraries. The configured cryptographic
policies will be the default policy used by these backends unless the application
user configures them otherwise. When the system has been configured to use the
centralized cryptographic policies, the administrator is assured that any application
that utilizes the supported backends will follow a policy that adheres to the
configured profile.
Currently the supported backends are:
- GnuTLS library
- OpenSSL library
- NSS library
- OpenJDK
- Libkrb5
- BIND
- OpenSSH
Applications and languages which rely on any of these backends will follow the
system policies as well. Examples are apache httpd, nginx, php, and others. |
Rule
Configure System Cryptography Policy
[ref] | To configure the system cryptography policy to use ciphers only from the FIPS
policy, run the following command:
$ sudo update-crypto-policies --set FIPS
The rule checks if settings for selected crypto policy are configured as expected. Configuration files in the /etc/crypto-policies/back-ends are either symlinks to correct files provided by Crypto-policies package or they are regular files in case crypto policy customizations are applied.
Crypto policies may be customized by crypto policy modules, in which case it is delimited from the base policy using a colon. Warning:
The system needs to be rebooted for these changes to take effect. Warning:
System Crypto Modules must be provided by a vendor that undergoes
FIPS-140 certifications.
FIPS-140 is applicable to all Federal agencies that use
cryptographic-based security systems to protect sensitive information
in computer and telecommunication systems (including voice systems) as
defined in Section 5131 of the Information Technology Management Reform
Act of 1996, Public Law 104-106. This standard shall be used in
designing and implementing cryptographic modules that Federal
departments and agencies operate or are operated for them under
contract. See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-2.pdf
To meet this, the system has to have cryptographic software provided by
a vendor that has undergone this certification. This means providing
documentation, test results, design information, and independent third
party review by an accredited lab. While open source software is
capable of meeting this, it does not meet FIPS-140 unless the vendor
submits to this process. | Rationale: | Centralized cryptographic policies simplify applying secure ciphers across an operating system and
the applications that run on that operating system. Use of weak or untested encryption algorithms
undermines the purposes of utilizing encryption to protect data. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_configure_crypto_policy | References: | disa | CCI-000068, CCI-003123, CCI-002450, CCI-000877, CCI-002418, CCI-001453, CCI-002890 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.312(e)(1), 164.312(e)(2)(ii) | ism | 1446 | nerc-cip | CIP-003-8 R4.2, CIP-007-3 R5.1, CIP-007-3 R7.1 | nist | AC-17(a), AC-17(2), CM-6(a), MA-4(6), SC-13, SC-12(2), SC-12(3) | ospp | FCS_COP.1(1), FCS_COP.1(2), FCS_COP.1(3), FCS_COP.1(4), FCS_CKM.1, FCS_CKM.2, FCS_TLSC_EXT.1 | os-srg | SRG-OS-000396-GPOS-00176, SRG-OS-000393-GPOS-00173, SRG-OS-000394-GPOS-00174 | stigid | OL08-00-010020 | pcidss4 | 2.2.7, 2.2 | stigref | SV-248524r958408_rule |
| |
|
Rule
Configure SSH to use System Crypto Policy
[ref] | Crypto Policies provide a centralized control over crypto algorithms usage of many packages.
SSH is supported by crypto policy, but the SSH configuration may be
set up to ignore it.
To check that Crypto Policies settings are configured correctly, ensure that
the CRYPTO_POLICY variable is either commented or not set at all
in the /etc/sysconfig/sshd . | Rationale: | Overriding the system crypto policy makes the behavior of the SSH service violate expectations,
and makes system configuration more fragmented. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_configure_ssh_crypto_policy | References: | disa | CCI-001453 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.312(e)(1), 164.312(e)(2)(ii) | nerc-cip | CIP-003-8 R4.2, CIP-007-3 R5.1, CIP-007-3 R7.1 | nist | AC-17(a), AC-17(2), CM-6(a), MA-4(6), SC-13 | ospp | FCS_SSH_EXT.1, FCS_SSHS_EXT.1, FCS_SSHC_EXT.1 | pcidss | Req-2.2 | os-srg | SRG-OS-000250-GPOS-00093 | stigid | OL08-00-010287 | pcidss4 | 2.2.7, 2.2 | stigref | SV-248560r991554_rule |
| |
|
Group
Disk Partitioning
Group contains 1 rule |
[ref]
To ensure separation and protection of data, there
are top-level system directories which should be placed on their
own physical partition or logical volume. The installer's default
partitioning scheme creates separate logical volumes for
/ , /boot , and swap .
- If starting with any of the default layouts, check the box to
\"Review and modify partitioning.\" This allows for the easy creation
of additional logical volumes inside the volume group already
created, though it may require making
/ 's logical volume smaller to
create space. In general, using logical volumes is preferable to
using partitions because they can be more easily adjusted
later. - If creating a custom layout, create the partitions mentioned in
the previous paragraph (which the installer will require anyway),
as well as separate ones described in the following sections.
If a system has already been installed, and the default
partitioning
scheme was used, it is possible but nontrivial to
modify it to create separate logical volumes for the directories
listed above. The Logical Volume Manager (LVM) makes this possible. |
Rule
Encrypt Partitions
[ref] | Oracle Linux 8 natively supports partition encryption through the
Linux Unified Key Setup-on-disk-format (LUKS) technology. The easiest way to
encrypt a partition is during installation time.
For manual installations, select the Encrypt checkbox during
partition creation to encrypt the partition. When this
option is selected the system will prompt for a passphrase to use in
decrypting the partition. The passphrase will subsequently need to be entered manually
every time the system boots.
For automated/unattended installations, it is possible to use Kickstart by adding
the --encrypted and --passphrase= options to the definition of each partition to be
encrypted. For example, the following line would encrypt the root partition:
part / --fstype=ext4 --size=100 --onpart=hda1 --encrypted --passphrase=PASSPHRASE
Any PASSPHRASE is stored in the Kickstart in plaintext, and the Kickstart
must then be protected accordingly.
Omitting the --passphrase= option from the partition definition will cause the
installer to pause and interactively ask for the passphrase during installation.
By default, the Anaconda installer uses aes-xts-plain64 cipher
with a minimum 512 bit key size which should be compatible with FIPS enabled.
Detailed information on encrypting partitions using LUKS or LUKS ciphers can be found on
the Oracle Linux 8 Documentation web site:
https://docs.oracle.com/en/operating-systems/oracle-linux/8/install/install-InstallingOracleLinuxManually.html#system-options
. | Rationale: | The risk of a system's physical compromise, particularly mobile systems such as
laptops, places its data at risk of compromise. Encrypting this data mitigates
the risk of its loss if the system is lost. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_encrypt_partitions | References: | cis-csc | 13, 14 | cobit5 | APO01.06, BAI02.01, BAI06.01, DSS04.07, DSS05.03, DSS05.04, DSS05.07, DSS06.02, DSS06.06 | cui | 3.13.16 | disa | CCI-002476, CCI-001199, CCI-002475 | hipaa | 164.308(a)(1)(ii)(D), 164.308(b)(1), 164.310(d), 164.312(a)(1), 164.312(a)(2)(iii), 164.312(a)(2)(iv), 164.312(b), 164.312(c), 164.314(b)(2)(i), 164.312(d) | isa-62443-2013 | SR 3.4, SR 4.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R4.2, CIP-007-3 R5.1 | nist | CM-6(a), SC-28, SC-28(1), SC-13, AU-9(3) | nist-csf | PR.DS-1, PR.DS-5 | os-srg | SRG-OS-000405-GPOS-00184, SRG-OS-000185-GPOS-00079, SRG-OS-000404-GPOS-00183 | stigid | OL08-00-010030 | stigref | SV-248525r958552_rule |
| |
|
Group
GNOME Desktop Environment
Group contains 1 group and 3 rules |
[ref]
GNOME is a graphical desktop environment bundled with many Linux distributions that
allow users to easily interact with the operating system graphically rather than
textually. The GNOME Graphical Display Manager (GDM) provides login, logout, and user
switching contexts as well as display server management.
GNOME is developed by the GNOME Project and is considered the default
Oracle Linux Graphical environment.
For more information on GNOME and the GNOME Project, see https://www.gnome.org. |
Group
GNOME Remote Access Settings
Group contains 2 rules |
[ref]
GNOME remote access settings that apply to the graphical interface. |
Rule
Require Credential Prompting for Remote Access in GNOME3
[ref] | By default, GNOME does not require credentials when using Vino for
remote access. To configure the system to require remote credentials, add or set
authentication-methods to ['vnc'] in
/etc/dconf/db/local.d/00-security-settings . For example:
[org/gnome/Vino]
authentication-methods=['vnc']
Once the settings have been added, add a lock to
/etc/dconf/db/local.d/locks/00-security-settings-lock to prevent user modification.
For example:
/org/gnome/Vino/authentication-methods
After the settings have been set, run dconf update . | Rationale: | Username and password prompting is required for remote access. Otherwise, non-authorized
and nefarious users can access the system freely. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_dconf_gnome_remote_access_credential_prompt | References: | cui | 3.1.12 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) |
| |
|
Rule
Require Encryption for Remote Access in GNOME3
[ref] | By default, GNOME requires encryption when using Vino for remote access.
To prevent remote access encryption from being disabled, add or set
require-encryption to true in
/etc/dconf/db/local.d/00-security-settings . For example:
[org/gnome/Vino]
require-encryption=true
Once the settings have been added, add a lock to
/etc/dconf/db/local.d/locks/00-security-settings-lock to prevent user modification.
For example:
/org/gnome/Vino/require-encryption
After the settings have been set, run dconf update . | Rationale: | Open X displays allow an attacker to capture keystrokes and to execute commands
remotely. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_dconf_gnome_remote_access_encryption | References: | cis-csc | 1, 11, 12, 13, 15, 16, 18, 20, 3, 4, 6, 9 | cobit5 | BAI03.08, BAI07.04, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS03.01 | cui | 3.1.13 | disa | CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3, 4.4.3.3 | isa-62443-2013 | SR 7.6 | iso27001-2013 | A.12.1.1, A.12.1.2, A.12.1.4, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.2, A.14.2.2, A.14.2.3, A.14.2.4 | nist | CM-6(a), AC-17(a), AC-17(2) | nist-csf | DE.AE-1, PR.DS-7, PR.IP-1 | os-srg | SRG-OS-000480-GPOS-00227 |
| |
|
Rule
Make sure that the dconf databases are up-to-date with regards to respective keyfiles
[ref] | By default, DConf uses a binary database as a data backend.
The system-level database is compiled from keyfiles in the /etc/dconf/db/
directory by the dconf update command. More specifically, content present
in the following directories:
/etc/dconf/db/local.d
/etc/dconf/db/local.d
| Rationale: | Unlike text-based keyfiles, the binary database is impossible to check by OVAL.
Therefore, in order to evaluate dconf configuration, both have to be true at the same time -
configuration files have to be compliant, and the database needs to be more recent than those keyfiles,
which gives confidence that it reflects them. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_dconf_db_up_to_date | References: | | |
|
Group
Updating Software
Group contains 4 rules |
[ref]
The yum command line tool is used to install and
update software packages. The system also provides a graphical
software update tool in the System menu, in the Administration submenu,
called Software Update.
Oracle Linux 8 systems contain an installed software catalog called
the RPM database, which records metadata of installed packages. Consistently using
yum or the graphical Software Update for all software installation
allows for insight into the current inventory of installed software on the system.
|
Rule
Ensure gpgcheck Enabled In Main yum Configuration
[ref] | The gpgcheck option controls whether
RPM packages' signatures are always checked prior to installation.
To configure yum to check package signatures before installing
them, ensure the following line appears in /etc/yum.conf in
the [main] section:
gpgcheck=1
| Rationale: | Changes to any software components can have significant effects on the
overall security of the operating system. This requirement ensures the
software has not been tampered with and that it has been provided by a
trusted vendor.
Accordingly, patches, service packs, device drivers, or operating system
components must be signed with a certificate recognized and approved by the
organization.
Verifying the authenticity of the software prior to installation
validates the integrity of the patch or upgrade received from a vendor.
This ensures the software has not been tampered with and that it has been
provided by a trusted vendor. Self-signed certificates are disallowed by
this requirement. Certificates used to verify the software must be from an
approved Certificate Authority (CA). | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_ensure_gpgcheck_globally_activated | References: | cis-csc | 11, 2, 3, 9 | cjis | 5.10.4.1 | cobit5 | APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02 | cui | 3.4.8 | disa | CCI-003992 | hipaa | 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4 | isa-62443-2013 | SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6 | iso27001-2013 | A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4 | nist | CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b) | nist-csf | PR.DS-6, PR.DS-8, PR.IP-1 | ospp | FPT_TUD_EXT.1, FPT_TUD_EXT.2 | pcidss | Req-6.2 | os-srg | SRG-OS-000366-GPOS-00153 | stigid | OL08-00-010370 | anssi | R59 | pcidss4 | 6.3.3, 6.3 | stigref | SV-248574r986332_rule |
| |
|
Rule
Ensure gpgcheck Enabled for Local Packages
[ref] | yum should be configured to verify the signature(s) of local packages
prior to installation. To configure yum to verify signatures of local
packages, set the localpkg_gpgcheck to 1 in /etc/yum.conf .
| Rationale: | Changes to any software components can have significant effects to the overall security
of the operating system. This requirement ensures the software has not been tampered and
has been provided by a trusted vendor.
Accordingly, patches, service packs, device drivers, or operating system components must
be signed with a certificate recognized and approved by the organization. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_ensure_gpgcheck_local_packages | References: | cis-csc | 11, 3, 9 | cobit5 | BAI10.01, BAI10.02, BAI10.03, BAI10.05 | cui | 3.4.8 | disa | CCI-003992 | hipaa | 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 7.6 | iso27001-2013 | A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4 | nist | CM-11(a), CM-11(b), CM-6(a), CM-5(3), SA-12, SA-12(10) | nist-csf | PR.IP-1 | ospp | FPT_TUD_EXT.1, FPT_TUD_EXT.2 | os-srg | SRG-OS-000366-GPOS-00153 | stigid | OL08-00-010371 | anssi | R59 | stigref | SV-248575r986333_rule |
| |
|
Rule
Ensure gpgcheck Enabled for All yum Package Repositories
[ref] | To ensure signature checking is not disabled for
any repos, remove any lines from files in /etc/yum.repos.d of the form:
gpgcheck=0
| Rationale: | Verifying the authenticity of the software prior to installation validates
the integrity of the patch or upgrade received from a vendor. This ensures
the software has not been tampered with and that it has been provided by a
trusted vendor. Self-signed certificates are disallowed by this
requirement. Certificates used to verify the software must be from an
approved Certificate Authority (CA)." | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_ensure_gpgcheck_never_disabled | References: | cis-csc | 11, 2, 3, 9 | cjis | 5.10.4.1 | cobit5 | APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02 | cui | 3.4.8 | disa | CCI-003992 | hipaa | 164.308(a)(1)(ii)(D), 164.312(b), 164.312(c)(1), 164.312(c)(2), 164.312(e)(2)(i) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4 | isa-62443-2013 | SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6 | iso27001-2013 | A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4 | nist | CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), SA-12, SA-12(10), CM-11(a), CM-11(b) | nist-csf | PR.DS-6, PR.DS-8, PR.IP-1 | ospp | FPT_TUD_EXT.1, FPT_TUD_EXT.2 | pcidss | Req-6.2 | os-srg | SRG-OS-000366-GPOS-00153 | stigid | OL08-00-010370 | anssi | R59 | pcidss4 | 6.3.3, 6.3 | stigref | SV-248574r986332_rule |
| |
|
Rule
Ensure Oracle Linux GPG Key Installed
[ref] | To ensure the system can cryptographically verify base software
packages come from Oracle (and to connect to the Unbreakable Linux Network to
receive them), the Oracle GPG key must properly be installed.
To install the Oracle GPG key, run:
$ sudo uln_register
If the system is not connected to the Internet,
then install the Oracle GPG key from trusted media such as
the Oracle installation CD-ROM or DVD. Assuming the disc is mounted
in /media/cdrom , use the following command as the root user to import
it into the keyring:
$ sudo rpm --import /media/cdrom/RPM-GPG-KEY-oracle
Alternatively, the key may be pre-loaded during the Oracle installation. In
such cases, the key can be installed by running the following command:
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
| Rationale: | Changes to software components can have significant effects on the
overall security of the operating system. This requirement ensures
the software has not been tampered with and that it has been provided
by a trusted vendor. The Oracle GPG key is necessary to
cryptographically verify packages are from Oracle. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_ensure_oracle_gpgkey_installed | References: | cis-csc | 11, 2, 3, 9 | cobit5 | APO01.06, BAI03.05, BAI06.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS06.02 | disa | CCI-001749 | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.4 | isa-62443-2013 | SR 3.1, SR 3.3, SR 3.4, SR 3.8, SR 7.6 | iso27001-2013 | A.11.2.4, A.12.1.2, A.12.2.1, A.12.5.1, A.12.6.2, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4 | nist | CM-5(3), SI-7, SC-12, SC-12(3), CM-6(a), CM-11(a), CM-11(b) | nist-csf | PR.DS-6, PR.DS-8, PR.IP-1 | pcidss | Req-6.2 | stigid | OL08-00-010019 | cis | 1.2.2 | anssi | R59 | stigref | SV-256978r986384_rule |
| |
|
Group
Account and Access Control
Group contains 4 groups and 10 rules |
[ref]
In traditional Unix security, if an attacker gains
shell access to a certain login account, they can perform any action
or access any file to which that account has access. Therefore,
making it more difficult for unauthorized people to gain shell
access to accounts, particularly to privileged accounts, is a
necessary part of securing a system. This section introduces
mechanisms for restricting access to accounts under
Oracle Linux 8. |
Group
Protect Physical Console Access
Group contains 5 rules |
[ref]
It is impossible to fully protect a system from an
attacker with physical access, so securing the space in which the
system is located should be considered a necessary step. However,
there are some steps which, if taken, make it more difficult for an
attacker to quickly or undetectably modify a system from its
console. |
Rule
Disable debug-shell SystemD Service
[ref] | SystemD's debug-shell service is intended to
diagnose SystemD related boot issues with various systemctl
commands. Once enabled and following a system reboot, the root shell
will be available on tty9 which is access by pressing
CTRL-ALT-F9 . The debug-shell service should only be used
for SystemD related issues and should otherwise be disabled.
By default, the debug-shell SystemD service is already disabled.
The debug-shell service can be disabled with the following command:
$ sudo systemctl mask --now debug-shell.service
| Rationale: | This prevents attackers with physical access from trivially bypassing security
on the machine through valid troubleshooting configurations and gaining root
access when the system is rebooted. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_service_debug-shell_disabled | References: | cui | 3.4.5 | disa | CCI-000366, CCI-002235 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | nist | CM-6 | ospp | FIA_UAU.1 | os-srg | SRG-OS-000324-GPOS-00125, SRG-OS-000480-GPOS-00227 | stigid | OL08-00-040180 | stigref | SV-248872r991589_rule |
| |
|
Rule
Disable Ctrl-Alt-Del Burst Action
[ref] | By default, SystemD will reboot the system if the Ctrl-Alt-Del
key sequence is pressed Ctrl-Alt-Delete more than 7 times in 2 seconds.
To configure the system to ignore the CtrlAltDelBurstAction
setting, add or modify the following to /etc/systemd/system.conf :
CtrlAltDelBurstAction=none
Warning:
Disabling the Ctrl-Alt-Del key sequence
in /etc/init/control-alt-delete.conf DOES NOT disable the Ctrl-Alt-Del
key sequence if running in runlevel 6 (e.g. in GNOME, KDE, etc.)! The
Ctrl-Alt-Del key sequence will only be disabled if running in
the non-graphical runlevel 3 . | Rationale: | A locally logged-in user who presses Ctrl-Alt-Del, when at the console,
can reboot the system. If accidentally pressed, as could happen in
the case of mixed OS environment, this can create the risk of short-term
loss of availability of systems due to unintentional reboot. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_burstaction | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.4.5 | disa | CCI-000366, CCI-002235 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2 | nist | CM-6(a), AC-6(1), CM-6(a) | nist-csf | PR.AC-4, PR.DS-5 | ospp | FAU_GEN.1.2 | os-srg | SRG-OS-000324-GPOS-00125, SRG-OS-000480-GPOS-00227 | stigid | OL08-00-040172 | stigref | SV-248871r991589_rule |
| |
|
Rule
Disable Ctrl-Alt-Del Reboot Activation
[ref] | By default, SystemD will reboot the system if the Ctrl-Alt-Del
key sequence is pressed.
To configure the system to ignore the Ctrl-Alt-Del key sequence from the
command line instead of rebooting the system, do either of the following:
ln -sf /dev/null /etc/systemd/system/ctrl-alt-del.target
or
systemctl mask ctrl-alt-del.target
Do not simply delete the /usr/lib/systemd/system/ctrl-alt-del.service file,
as this file may be restored during future system updates. | Rationale: | A locally logged-in user who presses Ctrl-Alt-Del, when at the console,
can reboot the system. If accidentally pressed, as could happen in
the case of mixed OS environment, this can create the risk of short-term
loss of availability of systems due to unintentional reboot. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_disable_ctrlaltdel_reboot | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.4.5 | disa | CCI-000366, CCI-002235 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2 | nist | CM-6(a), AC-6(1) | nist-csf | PR.AC-4, PR.DS-5 | ospp | FAU_GEN.1.2 | os-srg | SRG-OS-000324-GPOS-00125, SRG-OS-000480-GPOS-00227 | stigid | OL08-00-040170 | stigref | SV-248869r991589_rule |
| |
|
Rule
Verify that Interactive Boot is Disabled
[ref] | Oracle Linux 8 systems support an "interactive boot" option that can
be used to prevent services from being started. On a Oracle Linux 8
system, interactive boot can be enabled by providing a 1 ,
yes , true , or on value to the
systemd.confirm_spawn kernel argument in /etc/default/grub .
Remove any instance of systemd.confirm_spawn=(1|yes|true|on) from
the kernel arguments in that file to disable interactive boot.
Recovery booting must also be disabled. Confirm that
GRUB_DISABLE_RECOVERY=true is set in /etc/default/grub .
It is also required to change the runtime configuration, run:
/sbin/grubby --update-kernel=ALL --remove-args="systemd.confirm_spawn"
grub2-mkconfig -o /boot/grub2/grub.cfg
| Rationale: | Using interactive or recovery boot, the console user could disable auditing, firewalls,
or other services, weakening system security. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_grub2_disable_interactive_boot | References: | cis-csc | 11, 12, 14, 15, 16, 18, 3, 5 | cobit5 | DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06 | cui | 3.1.2, 3.4.5 | disa | CCI-000366 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7 | iso27001-2013 | A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | SC-2(1), CM-6(a) | nist-csf | PR.AC-4, PR.AC-6, PR.PT-3 | os-srg | SRG-OS-000480-GPOS-00227 |
| |
|
Rule
Require Authentication for Single User Mode
[ref] | Single-user mode is intended as a system recovery
method, providing a single user root access to the system by
providing a boot option at startup.
By default, single-user mode is protected by requiring a password and is set
in /usr/lib/systemd/system/rescue.service . | Rationale: | This prevents attackers with physical access from trivially bypassing security
on the machine and gaining root access. Such accesses are further prevented
by configuring the bootloader password. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_require_singleuser_auth | References: | cis-csc | 1, 11, 12, 14, 15, 16, 18, 3, 5 | cobit5 | DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10 | cui | 3.1.1, 3.4.5 | disa | CCI-000213 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7 | ism | 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561 | iso27001-2013 | A.18.1.4, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3 | nist | IA-2, AC-3, CM-6(a) | nist-csf | PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3 | ospp | FIA_UAU.1 | os-srg | SRG-OS-000080-GPOS-00048 | stigid | OL08-00-010151 | stigref | SV-248541r958472_rule |
| |
|
Group
Protect Accounts by Restricting Password-Based Login
Group contains 2 groups and 4 rules |
[ref]
Conventionally, Unix shell accounts are accessed by
providing a username and password to a login program, which tests
these values for correctness using the /etc/passwd and
/etc/shadow files. Password-based login is vulnerable to
guessing of weak passwords, and to sniffing and man-in-the-middle
attacks against passwords entered over a network or at an insecure
console. Therefore, mechanisms for accessing accounts by entering
usernames and passwords should be restricted to those which are
operationally necessary. |
Group
Verify Proper Storage and Existence of Password
Hashes
Group contains 1 rule |
[ref]
By default, password hashes for local accounts are stored
in the second field (colon-separated) in
/etc/shadow . This file should be readable only by
processes running with root credentials, preventing users from
casually accessing others' password hashes and attempting
to crack them.
However, it remains possible to misconfigure the system
and store password hashes
in world-readable files such as /etc/passwd , or
to even store passwords themselves in plaintext on the system.
Using system-provided tools for password change/creation
should allow administrators to avoid such misconfiguration. |
Rule
Prevent Login to Accounts With Empty Password
[ref] | If an account is configured for password authentication
but does not have an assigned password, it may be possible to log
into the account without authentication. Remove any instances of the
nullok in
/etc/pam.d/system-auth and
/etc/pam.d/password-auth
to prevent logins with empty passwords. Warning:
If the system relies on authselect tool to manage PAM settings, the remediation
will also use authselect tool. However, if any manual modification was made in
PAM files, the authselect integrity check will fail and the remediation will be
aborted in order to preserve intentional changes. In this case, an informative message will
be shown in the remediation report.
Note that this rule is not applicable for systems running within a
container. Having user with empty password within a container is not
considered a risk, because it should not be possible to directly login into
a container anyway. | Rationale: | If an account has an empty password, anyone could log in and
run commands with the privileges of that account. Accounts with
empty passwords should never be used in operational environments. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_no_empty_passwords | References: | cis-csc | 1, 12, 13, 14, 15, 16, 18, 3, 5 | cjis | 5.5.2 | cobit5 | APO01.06, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.02, DSS06.03, DSS06.10 | cui | 3.1.1, 3.1.5 | disa | CCI-000366 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.18.1.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5 | nist | IA-5(1)(a), IA-5(c), CM-6(a) | nist-csf | PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.DS-5 | ospp | FIA_UAU.1 | pcidss | Req-8.2.3 | os-srg | SRG-OS-000480-GPOS-00227 | stigid | OL08-00-020331, OL08-00-020332 | pcidss4 | 8.3.1, 8.3 | stigref | SV-248715r991589_rule, SV-248716r991589_rule |
| |
|
Group
Restrict Root Logins
Group contains 3 rules |
[ref]
Direct root logins should be allowed only for emergency use.
In normal situations, the administrator should access the system
via a unique unprivileged account, and then use su or sudo to execute
privileged commands. Discouraging administrators from accessing the
root account directly ensures an audit trail in organizations with
multiple administrators. Locking down the channels through which
root can connect directly also reduces opportunities for
password-guessing against the root account. The login program
uses the file /etc/securetty to determine which interfaces
should allow root logins.
The virtual devices /dev/console
and /dev/tty* represent the system consoles (accessible via
the Ctrl-Alt-F1 through Ctrl-Alt-F6 keyboard sequences on a default
installation). The default securetty file also contains /dev/vc/* .
These are likely to be deprecated in most environments, but may be retained
for compatibility. Root should also be prohibited from connecting
via network protocols. Other sections of this document
include guidance describing how to prevent root from logging in via SSH. |
Rule
Direct root Logins Not Allowed
[ref] | To further limit access to the root account, administrators
can disable root logins at the console by editing the /etc/securetty file.
This file lists all devices the root user is allowed to login to. If the file does
not exist at all, the root user can login through any communication device on the
system, whether via the console or via a raw network interface. This is dangerous
as user can login to the system as root via Telnet, which sends the password in
plain text over the network. By default, Oracle Linux 8's
/etc/securetty file only allows the root user to login at the console
physically attached to the system. To prevent root from logging in, remove the
contents of this file. To prevent direct root logins, remove the contents of this
file by typing the following command:
$ sudo echo > /etc/securetty
Warning:
This rule only checks the /etc/securetty file existence and its content.
If you need to restrict user access using the /etc/securetty file, make sure
the pam_securetty.so PAM module is properly enabled in relevant PAM files. | Rationale: | Disabling direct root logins ensures proper accountability and multifactor
authentication to privileged accounts. Users will first login, then escalate
to privileged (root) access via su / sudo. This is required for FISMA Low
and FISMA Moderate systems. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_no_direct_root_logins | References: | cis-csc | 1, 12, 15, 16, 5 | cobit5 | DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10 | cui | 3.1.1, 3.1.6 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1 | iso27001-2013 | A.18.1.4, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3 | nist | IA-2, CM-6(a) | nist-csf | PR.AC-1, PR.AC-6, PR.AC-7 | anssi | R33 | pcidss4 | 8.6.1, 8.6 |
| |
|
Rule
Restrict Serial Port Root Logins
[ref] | To restrict root logins on serial ports,
ensure lines of this form do not appear in /etc/securetty :
ttyS0
ttyS1
| Rationale: | Preventing direct root login to serial port interfaces
helps ensure accountability for actions taken on the systems
using the root account. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_restrict_serial_port_logins | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.1.1, 3.1.5 | disa | CCI-000770 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2 | nist | AC-6, CM-6(a) | nist-csf | PR.AC-4, PR.DS-5 |
| |
|
Rule
Restrict Virtual Console Root Logins
[ref] | To restrict root logins through the (deprecated) virtual console devices,
ensure lines of this form do not appear in /etc/securetty :
vc/1
vc/2
vc/3
vc/4
| Rationale: | Preventing direct root login to virtual console devices
helps ensure accountability for actions taken on the system
using the root account. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_securetty_root_login_console_only | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.1.1, 3.1.5 | disa | CCI-000770 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2 | nist | AC-6, CM-6(a) | nist-csf | PR.AC-4, PR.DS-5 | os-srg | SRG-OS-000324-GPOS-00125 | pcidss4 | 8.6.1, 8.6 |
| |
|
Rule
Enable authselect
[ref] | Configure user authentication setup to use the authselect tool.
If authselect profile is selected, the rule will enable the sssd profile. Warning:
If the sudo authselect select command returns an error informing that the chosen
profile cannot be selected, it is probably because PAM files have already been modified by
the administrator. If this is the case, in order to not overwrite the desired changes made
by the administrator, the current PAM settings should be investigated before forcing the
selection of the chosen authselect profile. | Rationale: | Authselect is a successor to authconfig.
It is a tool to select system authentication and identity sources from a list of supported
profiles instead of letting the administrator manually build the PAM stack.
That way, it avoids potential breakage of configuration, as it ships several tested profiles
that are well tested and supported to solve different use-cases. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_enable_authselect | References: | disa | CCI-000213 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | nist | AC-3 | ospp | FIA_UAU.1, FIA_AFL.1 | os-srg | SRG-OS-000480-GPOS-00227 | anssi | R31 | pcidss4 | 8.3.4, 8.3 |
| |
|
Group
GRUB2 bootloader configuration
Group contains 2 groups and 8 rules |
[ref]
During the boot process, the boot loader is
responsible for starting the execution of the kernel and passing
options to it. The boot loader allows for the selection of
different kernels - possibly on different partitions or media.
The default Oracle Linux 8 boot loader for x86 systems is called GRUB2.
Options it can pass to the kernel include single-user mode, which
provides root access without any authentication, and the ability to
disable SELinux. To prevent local users from modifying the boot
parameters and endangering security, protect the boot loader configuration
with a password and ensure its configuration file's permissions
are set properly. |
Group
Non-UEFI GRUB2 bootloader configuration
Group contains 4 rules |
[ref]
Non-UEFI GRUB2 bootloader configuration |
Rule
Verify /boot/grub2/grub.cfg Group Ownership
[ref] | The file /boot/grub2/grub.cfg should
be group-owned by the root group to prevent
destruction or modification of the file.
To properly set the group owner of /boot/grub2/grub.cfg , run the command:
$ sudo chgrp root /boot/grub2/grub.cfg
| Rationale: | The root group is a highly-privileged group. Furthermore, the group-owner of this
file should not have any access privileges anyway. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_file_groupowner_grub2_cfg | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cjis | 5.5.2.2 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.4.5 | disa | CCI-000366 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | CM-6(a), AC-6(1) | nist-csf | PR.AC-4, PR.DS-5 | pcidss | Req-7.1 | os-srg | SRG-OS-000480-GPOS-00227 | anssi | R29 | pcidss4 | 2.2.6, 2.2 |
| |
|
Rule
Verify /boot/grub2/grub.cfg User Ownership
[ref] | The file /boot/grub2/grub.cfg should
be owned by the root user to prevent destruction
or modification of the file.
To properly set the owner of /boot/grub2/grub.cfg , run the command:
$ sudo chown root /boot/grub2/grub.cfg
| Rationale: | Only root should be able to modify important boot parameters. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_file_owner_grub2_cfg | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cjis | 5.5.2.2 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.4.5 | disa | CCI-000366 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | CM-6(a), AC-6(1) | nist-csf | PR.AC-4, PR.DS-5 | pcidss | Req-7.1 | os-srg | SRG-OS-000480-GPOS-00227 | anssi | R29 | pcidss4 | 2.2.6, 2.2 |
| |
|
Rule
Verify /boot/grub2/grub.cfg Permissions
[ref] | File permissions for /boot/grub2/grub.cfg should be set to 600.
To properly set the permissions of /boot/grub2/grub.cfg , run the command:
$ sudo chmod 600 /boot/grub2/grub.cfg
| Rationale: | Proper permissions ensure that only the root user can modify important boot
parameters. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_file_permissions_grub2_cfg | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.4.5 | disa | CCI-000225 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | CM-6(a), AC-6(1) | nist-csf | PR.AC-4, PR.DS-5 | anssi | R29 | pcidss4 | 2.2.6, 2.2 |
| |
|
Rule
Set Boot Loader Password in grub2
[ref] | The grub2 boot loader should have a superuser account and password
protection enabled to protect boot-time settings.
Since plaintext passwords are a security risk, generate a hash for the password
by running the following command:
# grub2-setpassword
When prompted, enter the password that was selected.
Warning:
To prevent hard-coded passwords, automatic remediation of this control is not available. Remediation
must be automated as a component of machine provisioning, or followed manually as outlined above.
Also, do NOT manually add the superuser account and password to the
grub.cfg file as the grub2-mkconfig command overwrites this file. | Rationale: | Password protection on the boot loader configuration ensures
users with physical access cannot trivially alter
important bootloader settings. These include which kernel to use,
and whether to enter single-user mode. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_grub2_password | References: | cis-csc | 1, 11, 12, 14, 15, 16, 18, 3, 5 | cobit5 | DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10 | cui | 3.4.5 | disa | CCI-000213 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7 | iso27001-2013 | A.18.1.4, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5 | nist | CM-6(a) | nist-csf | PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.PT-3 | os-srg | SRG-OS-000080-GPOS-00048 | stigid | OL08-00-010150 | anssi | R5 | stigref | SV-248540r958472_rule |
| |
|
Group
UEFI GRUB2 bootloader configuration
Group contains 4 rules |
[ref]
UEFI GRUB2 bootloader configuration Warning:
UEFI generally uses vfat file systems, which does not support Unix-style permissions
managed by chmod command. In this case, in order to change file permissions for files
within /boot/efi it is necessary to update the mount options in /etc/fstab file and
reboot the system. |
Rule
Verify the UEFI Boot Loader grub.cfg Group Ownership
[ref] | The file /boot/efi/EFI/redhat/grub.cfg should
be group-owned by the root group to prevent
destruction or modification of the file.
To properly set the group owner of /boot/efi/EFI/redhat/grub.cfg , run the command:
$ sudo chgrp root /boot/efi/EFI/redhat/grub.cfg
| Rationale: | The root group is a highly-privileged group. Furthermore, the group-owner of this
file should not have any access privileges anyway. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_file_groupowner_efi_grub2_cfg | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cjis | 5.5.2.2 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.4.5 | disa | CCI-000225 | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | CM-6(a), AC-6(1) | nist-csf | PR.AC-4, PR.DS-5 | pcidss | Req-7.1 | anssi | R29 |
| |
|
Rule
Verify the UEFI Boot Loader grub.cfg User Ownership
[ref] | The file /boot/efi/EFI/redhat/grub.cfg should
be owned by the root user to prevent destruction
or modification of the file.
To properly set the owner of /boot/efi/EFI/redhat/grub.cfg , run the command:
$ sudo chown root /boot/efi/EFI/redhat/grub.cfg
| Rationale: | Only root should be able to modify important boot parameters. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_file_owner_efi_grub2_cfg | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cjis | 5.5.2.2 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.4.5 | disa | CCI-000225 | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | CM-6(a), AC-6(1) | nist-csf | PR.AC-4, PR.DS-5 | pcidss | Req-7.1 | anssi | R29 |
| |
|
Rule
Verify the UEFI Boot Loader grub.cfg Permissions
[ref] | File permissions for /boot/efi/EFI/redhat/grub.cfg should be set to 700.
To properly set the permissions of /boot/efi/EFI/redhat/grub.cfg , run the command:
$ sudo chmod 700 /boot/efi/EFI/redhat/grub.cfg
| Rationale: | Proper permissions ensure that only the root user can modify important boot
parameters. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_file_permissions_efi_grub2_cfg | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.4.5 | disa | CCI-000225 | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | CM-6(a), AC-6(1) | nist-csf | PR.AC-4, PR.DS-5 | anssi | R29 |
| |
|
Rule
Set the UEFI Boot Loader Password
[ref] | The grub2 boot loader should have a superuser account and password
protection enabled to protect boot-time settings.
Since plaintext passwords are a security risk, generate a hash for the password
by running the following command:
# grub2-setpassword
When prompted, enter the password that was selected.
Warning:
To prevent hard-coded passwords, automatic remediation of this control is not available. Remediation
must be automated as a component of machine provisioning, or followed manually as outlined above.
Also, do NOT manually add the superuser account and password to the
grub.cfg file as the grub2-mkconfig command overwrites this file. | Rationale: | Password protection on the boot loader configuration ensures
users with physical access cannot trivially alter
important bootloader settings. These include which kernel to use,
and whether to enter single-user mode. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_grub2_uefi_password | References: | cis-csc | 11, 12, 14, 15, 16, 18, 3, 5 | cobit5 | DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06 | cui | 3.4.5 | disa | CCI-000213 | hipaa | 164.308(a)(1)(ii)(B), 164.308(a)(7)(i), 164.308(a)(7)(ii)(A), 164.310(a)(1), 164.310(a)(2)(i), 164.310(a)(2)(ii), 164.310(a)(2)(iii), 164.310(b), 164.310(c), 164.310(d)(1), 164.310(d)(2)(iii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7 | iso27001-2013 | A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | CM-6(a) | nist-csf | PR.AC-4, PR.AC-6, PR.PT-3 | ospp | FIA_UAU.1 | os-srg | SRG-OS-000080-GPOS-00048 | stigid | OL08-00-010140 | anssi | R5 | stigref | SV-248537r958472_rule |
| |
|
Group
Configure Syslog
Group contains 1 group and 1 rule |
[ref]
The syslog service has been the default Unix logging mechanism for
many years. It has a number of downsides, including inconsistent log format,
lack of authentication for received messages, and lack of authentication,
encryption, or reliable transport for messages sent over a network. However,
due to its long history, syslog is a de facto standard which is supported by
almost all Unix applications.
In Oracle Linux 8, rsyslog has replaced ksyslogd as the
syslog daemon of choice, and it includes some additional security features
such as reliable, connection-oriented (i.e. TCP) transmission of logs, the
option to log to database formats, and the encryption of log data en route to
a central logging server.
This section discusses how to configure rsyslog for
best effect, and how to use tools provided with the system to maintain and
monitor logs. |
Group
Rsyslog Logs Sent To Remote Host
Group contains 1 rule |
[ref]
If system logs are to be useful in detecting malicious
activities, it is necessary to send logs to a remote server. An
intruder who has compromised the root account on a system may
delete the log entries which indicate that the system was attacked
before they are seen by an administrator.
However, it is recommended that logs be stored on the local
host in addition to being sent to the loghost, especially if
rsyslog has been configured to use the UDP protocol to send
messages over a network. UDP does not guarantee reliable delivery,
and moderately busy sites will lose log messages occasionally,
especially in periods of high traffic which may be the result of an
attack. In addition, remote rsyslog messages are not
authenticated in any way by default, so it is easy for an attacker to
introduce spurious messages to the central log server. Also, some
problems cause loss of network connectivity, which will prevent the
sending of messages to the central server. For all of these reasons, it is
better to store log messages both centrally and on each host, so
that they can be correlated if necessary. |
Rule
Ensure Logs Sent To Remote Host
[ref] | To configure rsyslog to send logs to a remote log server,
open /etc/rsyslog.conf and read and understand the last section of the file,
which describes the multiple directives necessary to activate remote
logging.
Along with these other directives, the system can be configured
to forward its logs to a particular log server by
adding or correcting one of the following lines,
substituting logcollector appropriately.
The choice of protocol depends on the environment of the system;
although TCP and RELP provide more reliable message delivery,
they may not be supported in all environments.
To use UDP for log message delivery:
*.* @logcollector
To use TCP for log message delivery:
*.* @@logcollector
To use RELP for log message delivery:
*.* :omrelp:logcollector
There must be a resolvable DNS CNAME or Alias record set to " logcollector" for logs to be sent correctly to the centralized logging utility. Warning:
It is important to configure queues in case the client is sending log
messages to a remote server. If queues are not configured,
the system will stop functioning when the connection
to the remote server is not available. Please consult Rsyslog
documentation for more information about configuration of queues. The
example configuration which should go into /etc/rsyslog.conf
can look like the following lines:
$ActionQueueType LinkedList
$ActionQueueFileName queuefilename
$ActionQueueMaxDiskSpace 1g
$ActionQueueSaveOnShutdown on
$ActionResumeRetryCount -1
| Rationale: | A log server (loghost) receives syslog messages from one or more
systems. This data can be used as an additional log source in the event a
system is compromised and its local logs are suspect. Forwarding log messages
to a remote loghost also provides system administrators with a centralized
place to view the status of multiple hosts within the enterprise. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_rsyslog_remote_loghost | References: | cis-csc | 1, 13, 14, 15, 16, 2, 3, 5, 6 | cobit5 | APO11.04, APO13.01, BAI03.05, BAI04.04, DSS05.04, DSS05.07, MEA02.01 | disa | CCI-000366, CCI-001851 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(5)(ii)(B), 164.308(a)(5)(ii)(C), 164.308(a)(6)(ii), 164.308(a)(8), 164.310(d)(2)(iii), 164.312(b), 164.314(a)(2)(i)(C), 164.314(a)(2)(iii) | isa-62443-2009 | 4.3.3.3.9, 4.3.3.5.8, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 2.10, SR 2.11, SR 2.12, SR 2.8, SR 2.9, SR 7.1, SR 7.2 | ism | 0988, 1405 | iso27001-2013 | A.12.1.3, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.17.2.1 | nerc-cip | CIP-003-8 R5.2, CIP-004-6 R3.3 | nist | CM-6(a), AU-4(1), AU-9(2) | nist-csf | PR.DS-4, PR.PT-1 | os-srg | SRG-OS-000479-GPOS-00224, SRG-OS-000480-GPOS-00227, SRG-OS-000342-GPOS-00133 | stigid | OL08-00-030690 | anssi | R71 | stigref | SV-248814r958754_rule |
| |
|
Group
Network Configuration and Firewalls
Group contains 1 group and 1 rule |
[ref]
Most systems must be connected to a network of some
sort, and this brings with it the substantial risk of network
attack. This section discusses the security impact of decisions
about networking which must be made when configuring a system.
This section also discusses firewalls, network access
controls, and other network security frameworks, which allow
system-level rules to be written that can limit an attackers' ability
to connect to your system. These rules can specify that network
traffic should be allowed or denied from certain IP addresses,
hosts, and networks. The rules can also specify which of the
system's network services are available to particular hosts or
networks. |
Group
IPSec Support
Group contains 1 rule |
[ref]
Support for Internet Protocol Security (IPsec)
is provided with Libreswan. |
Rule
Verify Any Configured IPSec Tunnel Connections
[ref] | Libreswan provides an implementation of IPsec
and IKE, which permits the creation of secure tunnels over
untrusted networks. As such, IPsec can be used to circumvent certain
network requirements such as filtering. Verify that if any IPsec connection
(conn ) configured in /etc/ipsec.conf and /etc/ipsec.d
exists is an approved organizational connection. Warning:
Automatic remediation of this control is not available due to the unique
requirements of each system. | Rationale: | IP tunneling mechanisms can be used to bypass network filtering. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_libreswan_approved_tunnels | References: | cis-csc | 1, 12, 13, 14, 15, 16, 18, 4, 6, 8, 9 | cobit5 | APO01.06, APO13.01, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.07, DSS06.02 | disa | CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.2.3.4, 4.3.3.4, 4.4.3.3 | isa-62443-2013 | SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | AC-17(a), MA-4(6), CM-6(a), AC-4, SC-8 | nist-csf | DE.AE-1, ID.AM-3, PR.AC-5, PR.DS-5, PR.PT-4 | os-srg | SRG-OS-000480-GPOS-00227 |
| |
|
Group
File Permissions and Masks
Group contains 4 groups and 5 rules |
[ref]
Traditional Unix security relies heavily on file and
directory permissions to prevent unauthorized users from reading or
modifying files to which they should not have access.
Several of the commands in this section search filesystems
for files or directories with certain characteristics, and are
intended to be run on every local partition on a given system.
When the variable PART appears in one of the commands below,
it means that the command is intended to be run repeatedly, with the
name of each local partition substituted for PART in turn.
The following command prints a list of all xfs partitions on the local
system, which is the default filesystem for Oracle Linux 8
installations:
$ mount -t xfs | awk '{print $3}'
For any systems that use a different
local filesystem type, modify this command as appropriate. |
Group
Restrict Dynamic Mounting and Unmounting of
Filesystems
Group contains 2 rules |
[ref]
Linux includes a number of facilities for the automated addition
and removal of filesystems on a running system. These facilities may be
necessary in many environments, but this capability also carries some risk -- whether direct
risk from allowing users to introduce arbitrary filesystems,
or risk that software flaws in the automated mount facility itself could
allow an attacker to compromise the system.
This command can be used to list the types of filesystems that are
available to the currently executing kernel:
$ find /lib/modules/`uname -r`/kernel/fs -type f -name '*.ko'
If these filesystems are not required then they can be explicitly disabled
in a configuratio file in /etc/modprobe.d . |
Rule
Disable the Automounter
[ref] | The autofs daemon mounts and unmounts filesystems, such as user
home directories shared via NFS, on demand. In addition, autofs can be used to handle
removable media, and the default configuration provides the cdrom device as /misc/cd .
However, this method of providing access to removable media is not common, so autofs
can almost always be disabled if NFS is not in use. Even if NFS is required, it may be
possible to configure filesystem mounts statically by editing /etc/fstab
rather than relying on the automounter.
The autofs service can be disabled with the following command:
$ sudo systemctl mask --now autofs.service
| Rationale: | Disabling the automounter permits the administrator to
statically control filesystem mounting through /etc/fstab .
Additionally, automatically mounting filesystems permits easy introduction of
unknown devices, thereby facilitating malicious activity. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_service_autofs_disabled | References: | cis-csc | 1, 12, 15, 16, 5 | cobit5 | APO13.01, DSS01.04, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10 | cui | 3.4.6 | disa | CCI-000778, CCI-000366, CCI-001958 | hipaa | 164.308(a)(3)(i), 164.308(a)(3)(ii)(A), 164.310(d)(1), 164.310(d)(2), 164.312(a)(1), 164.312(a)(2)(iv), 164.312(b) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.6 | iso27001-2013 | A.11.2.6, A.13.1.1, A.13.2.1, A.18.1.4, A.6.2.1, A.6.2.2, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3 | nist | CM-7(a), CM-7(b), CM-6(a), MP-7 | nist-csf | PR.AC-1, PR.AC-3, PR.AC-6, PR.AC-7 | os-srg | SRG-OS-000114-GPOS-00059, SRG-OS-000378-GPOS-00163, SRG-OS-000480-GPOS-00227 | stigid | OL08-00-040070 | stigref | SV-248836r958498_rule |
| |
|
Rule
Disable Modprobe Loading of USB Storage Driver
[ref] | To prevent USB storage devices from being used, configure the kernel module loading system
to prevent automatic loading of the USB storage driver.
To configure the system to prevent the usb-storage
kernel module from being loaded, add the following line to the file /etc/modprobe.d/usb-storage.conf :
install usb-storage /bin/false
To configure the system to prevent the usb-storage from being used,
add the following line to file /etc/modprobe.d/usb-storage.conf :
blacklist usb-storage
This will prevent the modprobe program from loading the usb-storage
module, but will not prevent an administrator (or another program) from using the
insmod program to load the module manually. | Rationale: | USB storage devices such as thumb drives can be used to introduce
malicious software. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_kernel_module_usb-storage_disabled | References: | cis-csc | 1, 12, 15, 16, 5 | cobit5 | APO13.01, DSS01.04, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10 | cui | 3.1.21 | disa | CCI-000778, CCI-001958, CCI-003959 | hipaa | 164.308(a)(3)(i), 164.308(a)(3)(ii)(A), 164.310(d)(1), 164.310(d)(2), 164.312(a)(1), 164.312(a)(2)(iv), 164.312(b) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.6 | iso27001-2013 | A.11.2.6, A.13.1.1, A.13.2.1, A.18.1.4, A.6.2.1, A.6.2.2, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3 | nist | CM-7(a), CM-7(b), CM-6(a), MP-7 | nist-csf | PR.AC-1, PR.AC-3, PR.AC-6, PR.AC-7 | os-srg | SRG-OS-000114-GPOS-00059, SRG-OS-000378-GPOS-00163, SRG-OS-000480-GPOS-00227 | app-srg-ctr | SRG-APP-000141-CTR-000315 | stigid | OL08-00-040080 | pcidss4 | 3.4.2, 3.4 | stigref | SV-248837r986386_rule |
| |
|
Group
Restrict Programs from Dangerous Execution Patterns
Group contains 2 groups and 3 rules |
[ref]
The recommendations in this section are designed to
ensure that the system's features to protect against potentially
dangerous program execution are activated.
These protections are applied at the system initialization or
kernel level, and defend against certain types of badly-configured
or compromised programs. |
Group
Disable Core Dumps
Group contains 1 rule |
[ref]
A core dump file is the memory image of an executable
program when it was terminated by the operating system due to
errant behavior. In most cases, only software developers
legitimately need to access these files. The core dump files may
also contain sensitive information, or unnecessarily occupy large
amounts of disk space.
Once a hard limit is set in /etc/security/limits.conf , or
to a file within the /etc/security/limits.d/ directory, a
user cannot increase that limit within his or her own session. If access
to core dumps is required, consider restricting them to only
certain users or groups. See the limits.conf man page for more
information.
The core dumps of setuid programs are further protected. The
sysctl variable fs.suid_dumpable controls whether
the kernel allows core dumps from these programs at all. The default
value of 0 is recommended. |
Rule
Disable Core Dumps for SUID programs
[ref] | To set the runtime status of the fs.suid_dumpable kernel parameter, run the following command: $ sudo sysctl -w fs.suid_dumpable=0
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d : fs.suid_dumpable = 0
| Rationale: | The core dump of a setuid program is more likely to contain
sensitive data, as the program itself runs with greater privileges than the
user who initiated execution of the program. Disabling the ability for any
setuid program to write a core file decreases the risk of unauthorized access
of such data. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sysctl_fs_suid_dumpable | References: | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | nist | SI-11(a), SI-11(b) | anssi | R14 | pcidss4 | 3.3.1.1, 3.3.1, 3.3 |
| |
|
Group
Enable ExecShield
Group contains 1 rule |
[ref]
ExecShield describes kernel features that provide
protection against exploitation of memory corruption errors such as buffer
overflows. These features include random placement of the stack and other
memory regions, prevention of execution in memory that should only hold data,
and special handling of text buffers. These protections are enabled by default
on 32-bit systems and controlled through sysctl variables
kernel.exec-shield and kernel.randomize_va_space . On the latest
64-bit systems, kernel.exec-shield cannot be enabled or disabled with
sysctl . |
Rule
Enable Randomized Layout of Virtual Address Space
[ref] | To set the runtime status of the kernel.randomize_va_space kernel parameter, run the following command: $ sudo sysctl -w kernel.randomize_va_space=2
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d : kernel.randomize_va_space = 2
| Rationale: | Address space layout randomization (ASLR) makes it more difficult for an
attacker to predict the location of attack code they have introduced into a
process's address space during an attempt at exploitation. Additionally,
ASLR makes it more difficult for an attacker to know the location of
existing code in order to re-purpose it using return oriented programming
(ROP) techniques. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sysctl_kernel_randomize_va_space | References: | cui | 3.1.7 | disa | CCI-000366, CCI-002824 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | nerc-cip | CIP-002-5 R1.1, CIP-002-5 R1.2, CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 4.1, CIP-004-6 4.2, CIP-004-6 R2.2.3, CIP-004-6 R2.2.4, CIP-004-6 R2.3, CIP-004-6 R4, CIP-005-6 R1, CIP-005-6 R1.1, CIP-005-6 R1.2, CIP-007-3 R3, CIP-007-3 R3.1, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.1.3, CIP-007-3 R5.2.1, CIP-007-3 R5.2.3, CIP-007-3 R8.4, CIP-009-6 R.1.1, CIP-009-6 R4 | nist | SC-30, SC-30(2), CM-6(a) | pcidss | Req-2.2.1 | os-srg | SRG-OS-000433-GPOS-00193, SRG-OS-000480-GPOS-00227 | app-srg-ctr | SRG-APP-000450-CTR-001105 | stigid | OL08-00-010430 | anssi | R9 | pcidss4 | 3.3.1.1, 3.3.1, 3.3 | stigref | SV-248594r958928_rule |
| |
|
Rule
Restrict Access to Kernel Message Buffer
[ref] | To set the runtime status of the kernel.dmesg_restrict kernel parameter, run the following command: $ sudo sysctl -w kernel.dmesg_restrict=1
To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d : kernel.dmesg_restrict = 1
| Rationale: | Unprivileged access to the kernel syslog can expose sensitive kernel
address information. | Severity: | low | Rule ID: | xccdf_org.ssgproject.content_rule_sysctl_kernel_dmesg_restrict | References: | cui | 3.1.5 | disa | CCI-001082, CCI-001090 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | nist | SI-11(a), SI-11(b) | os-srg | SRG-OS-000132-GPOS-00067, SRG-OS-000138-GPOS-00069 | app-srg-ctr | SRG-APP-000243-CTR-000600 | stigid | OL08-00-010375 | anssi | R9 | stigref | SV-248579r958524_rule |
| |
|
Group
SELinux
Group contains 1 group and 7 rules |
[ref]
SELinux is a feature of the Linux kernel which can be
used to guard against misconfigured or compromised programs.
SELinux enforces the idea that programs should be limited in what
files they can access and what actions they can take.
The default SELinux policy, as configured on Oracle Linux 8, has been
sufficiently developed and debugged that it should be usable on
almost any system with minimal configuration and a small
amount of system administrator training. This policy prevents
system services - including most of the common network-visible
services such as mail servers, FTP servers, and DNS servers - from
accessing files which those services have no valid reason to
access. This action alone prevents a huge amount of possible damage
from network attacks against services, from trojaned software, and
so forth.
This guide recommends that SELinux be enabled using the
default (targeted) policy on every Oracle Linux 8 system, unless that
system has unusual requirements which make a stronger policy
appropriate.
For more information on SELinux, see https://docs.oracle.com/en/operating-systems/oracle-linux/selinux/. |
Group
SELinux - Booleans
Group contains 3 rules |
[ref]
Enable or Disable runtime customization of SELinux system policies
without having to reload or recompile the SELinux policy. |
Rule
Disable the selinuxuser_execheap SELinux Boolean
[ref] | By default, the SELinux boolean selinuxuser_execheap is disabled.
When enabled this boolean is enabled it allows selinuxusers to execute code from the heap.
If this setting is enabled, it should be disabled.
To disable the selinuxuser_execheap SELinux boolean, run the following command:
$ sudo setsebool -P selinuxuser_execheap off
| Rationale: | Disabling code execution from the heap blocks buffer overflow attacks. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sebool_selinuxuser_execheap | References: | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | anssi | R48 |
| |
|
Rule
Enable the selinuxuser_execmod SELinux Boolean
[ref] | By default, the SELinux boolean selinuxuser_execmod is enabled.
If this setting is disabled, it should be enabled.
To enable the selinuxuser_execmod SELinux boolean, run the following command:
$ sudo setsebool -P selinuxuser_execmod on
| Rationale: | | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sebool_selinuxuser_execmod | References: | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) |
| |
|
Rule
Disable the selinuxuser_execstack SELinux Boolean
[ref] | By default, the SELinux boolean selinuxuser_execstack is enabled.
This setting should be disabled as unconfined executables should not be able
to make their stack executable.
To disable the selinuxuser_execstack SELinux boolean, run the following command:
$ sudo setsebool -P selinuxuser_execstack off
| Rationale: | Disabling code execution from the stack blocks buffer overflow attacks. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sebool_selinuxuser_execstack | References: | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | anssi | R48 |
| |
|
Rule
Ensure SELinux Not Disabled in /etc/default/grub
[ref] | SELinux can be disabled at boot time by an argument in
/etc/default/grub .
Remove any instances of selinux=0 from the kernel arguments in that
file to prevent SELinux from being disabled at boot. | Rationale: | Disabling a major host protection feature, such as SELinux, at boot time prevents
it from confining system services at boot time. Further, it increases
the chances that it will remain off during system operation. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_grub2_enable_selinux | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 18, 3, 4, 5, 6, 8, 9 | cobit5 | APO01.06, APO11.04, APO13.01, BAI03.05, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.03, DSS06.06, MEA02.01 | cui | 3.1.2, 3.7.2 | disa | CCI-000022, CCI-000032 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | isa-62443-2009 | 4.2.3.4, 4.3.3.2.2, 4.3.3.3.9, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4, 4.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.10, SR 2.11, SR 2.12, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3 | nist | AC-3, AC-3(3)(a) | nist-csf | DE.AE-1, ID.AM-3, PR.AC-4, PR.AC-5, PR.AC-6, PR.DS-5, PR.PT-1, PR.PT-3, PR.PT-4 | pcidss4 | 1.2.6, 1.2 |
| |
|
Rule
Ensure No Daemons are Unconfined by SELinux
[ref] | Daemons for which the SELinux policy does not contain rules will inherit the
context of the parent process. Because daemons are launched during
startup and descend from the init process, they inherit the unconfined_service_t context.
To check for unconfined daemons, run the following command:
$ sudo ps -eZ | grep "unconfined_service_t"
It should produce no output in a well-configured system. Warning:
Automatic remediation of this control is not available. Remediation
can be achieved by amending SELinux policy or stopping the unconfined
daemons as outlined above. | Rationale: | Daemons which run with the unconfined_service_t context may cause AVC denials,
or allow privileges that the daemon does not require. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_selinux_confinement_of_daemons | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 18, 3, 5, 6, 9 | cobit5 | APO01.06, APO11.04, BAI03.05, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.06, MEA02.01 | cui | 3.1.2, 3.1.5, 3.7.2 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | isa-62443-2009 | 4.3.3.3.9, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.10, SR 2.11, SR 2.12, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 2.8, SR 2.9, SR 5.2, SR 7.6 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.2, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.5.1, A.12.6.2, A.12.7.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2 | nist | CM-7(a), CM-7(b), CM-6(a), AC-3(3)(a), AC-6 | nist-csf | PR.AC-4, PR.DS-5, PR.IP-1, PR.PT-1, PR.PT-3 | pcidss4 | 1.2.6, 1.2 |
| |
|
Rule
Configure SELinux Policy
[ref] | The SELinux targeted policy is appropriate for
general-purpose desktops and servers, as well as systems in many other roles.
To configure the system to use this policy, add or correct the following line
in /etc/selinux/config :
SELINUXTYPE=targeted
Other policies, such as mls , provide additional security labeling
and greater confinement but are not compatible with many general-purpose
use cases. | Rationale: | Setting the SELinux policy to targeted or a more specialized policy
ensures the system will confine processes that are likely to be
targeted for exploitation, such as network or system services.
Note: During the development or debugging of SELinux modules, it is common to
temporarily place non-production systems in permissive mode. In such
temporary cases, SELinux policies should be developed, and once work
is completed, the system should be reconfigured to
targeted . | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_selinux_policytype | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 18, 3, 4, 5, 6, 8, 9 | cobit5 | APO01.06, APO11.04, APO13.01, BAI03.05, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.03, DSS06.06, MEA02.01 | cui | 3.1.2, 3.7.2 | disa | CCI-002696 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | isa-62443-2009 | 4.2.3.4, 4.3.3.2.2, 4.3.3.3.9, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4, 4.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.10, SR 2.11, SR 2.12, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.2, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-004-6 R3.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3, CIP-007-3 R6.5 | nist | AC-3, AC-3(3)(a), AU-9, SC-7(21) | nist-csf | DE.AE-1, ID.AM-3, PR.AC-4, PR.AC-5, PR.AC-6, PR.DS-5, PR.PT-1, PR.PT-3, PR.PT-4 | os-srg | SRG-OS-000445-GPOS-00199 | app-srg-ctr | SRG-APP-000233-CTR-000585 | stigid | OL08-00-010450 | anssi | R46, R64 | bsi | APP.4.4.A4, SYS.1.6.A3 | pcidss4 | 1.2.6, 1.2 | stigref | SV-248596r958944_rule |
| |
|
Rule
Ensure SELinux State is Enforcing
[ref] | The SELinux state should be set to enforcing at
system boot time. In the file /etc/selinux/config , add or correct the
following line to configure the system to boot into enforcing mode:
SELINUX=enforcing
| Rationale: | Setting the SELinux state to enforcing ensures SELinux is able to confine
potentially compromised processes to the security policy, which is designed to
prevent them from causing damage to the system or further elevating their
privileges. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_selinux_state | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 18, 3, 4, 5, 6, 8, 9 | cobit5 | APO01.06, APO11.04, APO13.01, BAI03.05, DSS01.05, DSS03.01, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.03, DSS06.06, MEA02.01 | cui | 3.1.2, 3.7.2 | disa | CCI-002696, CCI-001084 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | isa-62443-2009 | 4.2.3.4, 4.3.3.2.2, 4.3.3.3.9, 4.3.3.4, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.4.7, 4.4.2.1, 4.4.2.2, 4.4.2.4, 4.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.10, SR 2.11, SR 2.12, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.1, A.12.1.2, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.1.2, A.13.1.3, A.13.2.1, A.13.2.2, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.2, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-004-6 R3.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3, CIP-007-3 R6.5 | nist | AC-3, AC-3(3)(a), AU-9, SC-7(21) | nist-csf | DE.AE-1, ID.AM-3, PR.AC-4, PR.AC-5, PR.AC-6, PR.DS-5, PR.PT-1, PR.PT-3, PR.PT-4 | os-srg | SRG-OS-000445-GPOS-00199, SRG-OS-000134-GPOS-00068 | stigid | OL08-00-010170 | anssi | R37, R79 | bsi | APP.4.4.A4, SYS.1.6.A3 | pcidss4 | 1.2.6, 1.2 | stigref | SV-248548r958518_rule |
| |
|
Group
Services
Group contains 13 groups and 26 rules |
[ref]
The best protection against vulnerable software is running less software. This section describes how to review
the software which Oracle Linux 8 installs on a system and disable software which is not needed. It
then enumerates the software packages installed on a default Oracle Linux 8 system and provides guidance about which
ones can be safely disabled.
Oracle Linux 8 provides a convenient minimal install option that essentially installs the bare necessities for a functional
system. When building Oracle Linux 8 systems, it is highly recommended to select the minimal packages and then build up
the system from there. |
Group
Base Services
Group contains 1 rule |
[ref]
This section addresses the base services that are installed on a
Oracle Linux 8 default installation which are not covered in other
sections. Some of these services listen on the network and
should be treated with particular discretion. Other services are local
system utilities that may or may not be extraneous. In general, system services
should be disabled if not required. |
Rule
Disable KDump Kernel Crash Analyzer (kdump)
[ref] | The kdump service provides a kernel crash dump analyzer. It uses the kexec
system call to boot a secondary kernel ("capture" kernel) following a system
crash, which can load information from the crashed kernel for analysis.
The kdump service can be disabled with the following command:
$ sudo systemctl mask --now kdump.service
| Rationale: | Kernel core dumps may contain the full contents of system memory at the
time of the crash. Kernel core dumps consume a considerable amount of disk
space and may result in denial of service by exhausting the available space
on the target file system partition. Unless the system is used for kernel
development or testing, there is little need to run the kdump service. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_service_kdump_disabled | References: | cis-csc | 11, 12, 14, 15, 3, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06 | disa | CCI-000366 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3), 164.308(a)(4), 164.310(b), 164.310(c), 164.312(a), 164.312(e) | isa-62443-2009 | 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2 | nist | CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4 | ospp | FMT_SMF_EXT.1.1 | os-srg | SRG-OS-000269-GPOS-00103, SRG-OS-000480-GPOS-00227 | stigid | OL08-00-010670 | stigref | SV-248628r991562_rule |
| |
|
Group
Cron and At Daemons
Group contains 1 rule |
[ref]
The cron and at services are used to allow commands to
be executed at a later time. The cron service is required by almost
all systems to perform necessary maintenance tasks, while at may or
may not be required on a given system. Both daemons should be
configured defensively. |
Rule
Enable cron Service
[ref] | The crond service is used to execute commands at
preconfigured times. It is required by almost all systems to perform necessary
maintenance tasks, such as notifying root of system activity.
The crond service can be enabled with the following command:
$ sudo systemctl enable crond.service
| Rationale: | Due to its usage for maintenance and security-supporting tasks,
enabling the cron daemon is essential. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_service_crond_enabled | References: | cis-csc | 11, 14, 3, 9 | cobit5 | BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.05, DSS06.06 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6 | iso27001-2013 | A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.9.1.2 | nist | CM-6(a) | nist-csf | PR.IP-1, PR.PT-3 |
| |
|
Group
NFS and RPC
Group contains 1 group and 1 rule |
[ref]
The Network File System is a popular distributed filesystem for
the Unix environment, and is very widely deployed. This section discusses the
circumstances under which it is possible to disable NFS and its dependencies,
and then details steps which should be taken to secure
NFS's configuration. This section is relevant to systems operating as NFS
clients, as well as to those operating as NFS servers. |
Group
Configure NFS Servers
Group contains 1 rule |
[ref]
The steps in this section are appropriate for systems which operate as NFS servers. |
Rule
Use Kerberos Security on All Exports
[ref] | Using Kerberos on all exported mounts prevents a malicious client or user from
impersonating a system user. To cryptography authenticate users to the NFS server,
add sec=krb5:krb5i:krb5p to each export in /etc/exports . | Rationale: | When an NFS server is configured to use AUTH_SYS a selected userid and groupid are used to handle
requests from the remote user. The userid and groupid could mistakenly or maliciously be set
incorrectly. The AUTH_GSS method of authentication uses certificates on the server and client
systems to more securely authenticate the remote mount request. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_use_kerberos_security_all_exports | References: | cis-csc | 1, 12, 14, 15, 16, 18, 3, 5 | cobit5 | DSS05.04, DSS05.10, DSS06.10 | disa | CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1 | iso27001-2013 | A.18.1.4, A.6.1.2, A.9.1.2, A.9.2.1, A.9.2.3, A.9.2.4, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5 | nist | CM-7(a), CM-7(b), CM-6(a), IA-2, IA-2(8), IA-2(9), AC-17(a) | nist-csf | PR.AC-4, PR.AC-7 | os-srg | SRG-OS-000480-GPOS-00227 |
| |
|
Group
Obsolete Services
Group contains 4 groups and 11 rules |
[ref]
This section discusses a number of network-visible
services which have historically caused problems for system
security, and for which disabling or severely limiting the service
has been the best available guidance for some time. As a result of
this, many of these services are not installed as part of Oracle Linux 8
by default.
Organizations which are running these services should
switch to more secure equivalents as soon as possible.
If it remains absolutely necessary to run one of
these services for legacy reasons, care should be taken to restrict
the service as much as possible, for instance by configuring host
firewall software such as iptables to restrict access to the
vulnerable service to only those remote hosts which have a known
need to use it. |
Group
Xinetd
Group contains 2 rules |
[ref]
The xinetd service acts as a dedicated listener for some
network services (mostly, obsolete ones) and can be used to provide access
controls and perform some logging. It has been largely obsoleted by other
features, and it is not installed by default. The older Inetd service
is not even available as part of Oracle Linux 8. |
Rule
Uninstall xinetd Package
[ref] | The xinetd package can be removed with the following command:
$ sudo yum erase xinetd
| Rationale: | Removing the xinetd package decreases the risk of the
xinetd service's accidental (or intentional) activation. | Severity: | low | Rule ID: | xccdf_org.ssgproject.content_rule_package_xinetd_removed | References: | cis-csc | 11, 12, 14, 15, 3, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06 | disa | CCI-000305 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2 | nist | CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4 | anssi | R62 | pcidss4 | 2.2.4, 2.2 |
| |
|
Rule
Disable xinetd Service
[ref] |
The xinetd service can be disabled with the following command:
$ sudo systemctl mask --now xinetd.service
| Rationale: | The xinetd service provides a dedicated listener service for some programs,
which is no longer necessary for commonly-used network services. Disabling
it ensures that these uncommon services are not running, and also prevents
attacks against xinetd itself. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_service_xinetd_disabled | References: | cis-csc | 11, 12, 14, 15, 3, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06 | cui | 3.4.7 | disa | CCI-000305 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2 | nist | CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4 |
| |
|
Group
Rlogin, Rsh, and Rexec
Group contains 4 rules |
[ref]
The Berkeley r-commands are legacy services which
allow cleartext remote access and have an insecure trust
model. |
Rule
Uninstall rsh-server Package
[ref] | The rsh-server package can be removed with the following command:
$ sudo yum erase rsh-server
| Rationale: | The rsh-server service provides unencrypted remote access service which does not
provide for the confidentiality and integrity of user passwords or the remote session and has very weak
authentication. If a privileged user were to login using this service, the privileged user password
could be compromised. The rsh-server package provides several obsolete and insecure
network services. Removing it decreases the risk of those services' accidental (or intentional)
activation. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_package_rsh-server_removed | References: | cis-csc | 11, 12, 14, 15, 3, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06 | disa | CCI-000381 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2 | nist | CM-7(a), CM-7(b), CM-6(a), IA-5(1)(c) | nist-csf | PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4 | os-srg | SRG-OS-000095-GPOS-00049 | stigid | OL08-00-040010 | anssi | R62 | pcidss4 | 2.2.4, 2.2 | stigref | SV-248827r958478_rule |
| |
|
Rule
Disable rexec Service
[ref] | The rexec service, which is available with the rsh-server package
and runs as a service through xinetd or separately as a systemd socket, should be disabled.
If using xinetd, set disable to yes in /etc/xinetd.d/rexec .
The rexec socket can be disabled with the following command:
$ sudo systemctl mask --now rexec.socket
| Rationale: | The rexec service uses unencrypted network communications, which
means that data from the login session, including passwords and
all other information transmitted during the session, can be
stolen by eavesdroppers on the network. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_service_rexec_disabled | References: | cis-csc | 11, 12, 14, 15, 3, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06 | cui | 3.1.13, 3.4.7 | disa | CCI-000068, CCI-001436 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2 | nist | CM-7(a), CM-7(b), CM-6(a), IA-5(1)(c) | nist-csf | PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4 |
| |
|
Rule
Disable rlogin Service
[ref] | The rlogin service, which is available with
the rsh-server package and runs as a service through xinetd or separately
as a systemd socket, should be disabled.
If using xinetd, set disable to yes in /etc/xinetd.d/rlogin .
The rlogin socket can be disabled with the following command:
$ sudo systemctl mask --now rlogin.socket
| Rationale: | The rlogin service uses unencrypted network communications, which
means that data from the login session, including passwords and
all other information transmitted during the session, can be
stolen by eavesdroppers on the network. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_service_rlogin_disabled | References: | cis-csc | 1, 11, 12, 14, 15, 16, 3, 5, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10 | cui | 3.1.13, 3.4.7 | disa | CCI-001436 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.18.1.4, A.6.2.1, A.6.2.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3 | nist | CM-7(a), CM-7(b), CM-6(a), IA-5(1)(c) | nist-csf | PR.AC-1, PR.AC-3, PR.AC-6, PR.AC-7, PR.IP-1, PR.PT-3, PR.PT-4 |
| |
|
Rule
Remove Rsh Trust Files
[ref] | The files /etc/hosts.equiv and ~/.rhosts (in
each user's home directory) list remote hosts and users that are trusted by the
local system when using the rshd daemon.
To remove these files, run the following command to delete them from any
location:
$ sudo rm /etc/hosts.equiv
$ rm ~/.rhosts
| Rationale: | This action is only meaningful if .rhosts support is permitted
through PAM. Trust files are convenient, but when used in conjunction with
the R-services, they can allow unauthenticated access to a system. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_no_rsh_trust_files | References: | cis-csc | 11, 12, 14, 15, 3, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06 | disa | CCI-001436 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2 | nist | CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4 |
| |
|
Group
Chat/Messaging Services
Group contains 2 rules |
[ref]
The talk software makes it possible for users to send and receive messages
across systems through a terminal session. |
Rule
Uninstall talk-server Package
[ref] | The talk-server package can be removed with the following command: $ sudo yum erase talk-server
| Rationale: | The talk software presents a security risk as it uses unencrypted protocols
for communications. Removing the talk-server package decreases the
risk of the accidental (or intentional) activation of talk services. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_package_talk-server_removed | References: | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | anssi | R62 | pcidss4 | 2.2.4, 2.2 |
| |
|
Rule
Uninstall talk Package
[ref] | The talk package contains the client program for the
Internet talk protocol, which allows the user to chat with other users on
different systems. Talk is a communication program which copies lines from one
terminal to the terminal of another user.
The talk package can be removed with the following command:
$ sudo yum erase talk
| Rationale: | The talk software presents a security risk as it uses unencrypted protocols
for communications. Removing the talk package decreases the
risk of the accidental (or intentional) activation of talk client program. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_package_talk_removed | References: | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | anssi | R62 | pcidss4 | 2.2.4, 2.2 |
| |
|
Group
Telnet
Group contains 3 rules |
[ref]
The telnet protocol does not provide confidentiality or integrity
for information transmitted on the network. This includes authentication
information such as passwords. Organizations which use telnet should be
actively working to migrate to a more secure protocol. |
Rule
Uninstall telnet-server Package
[ref] | The telnet-server package can be removed with the following command:
$ sudo yum erase telnet-server
| Rationale: | It is detrimental for operating systems to provide, or install by default,
functionality exceeding requirements or mission objectives. These
unnecessary capabilities are often overlooked and therefore may remain
unsecure. They increase the risk to the platform by providing additional
attack vectors.
The telnet service provides an unencrypted remote access service which does
not provide for the confidentiality and integrity of user passwords or the
remote session. If a privileged user were to login using this service, the
privileged user password could be compromised.
Removing the telnet-server package decreases the risk of the
telnet service's accidental (or intentional) activation. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_package_telnet-server_removed | References: | cis-csc | 11, 12, 14, 15, 3, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.05, DSS06.06 | disa | CCI-000381 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.2.1, A.6.2.2, A.9.1.2 | nist | CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.AC-3, PR.IP-1, PR.PT-3, PR.PT-4 | pcidss | Req-2.2.2 | os-srg | SRG-OS-000095-GPOS-00049 | stigid | OL08-00-040000 | anssi | R62 | pcidss4 | 2.2.4, 2.2 | stigref | SV-248823r958478_rule |
| |
|
Rule
Remove telnet Clients
[ref] | The telnet client allows users to start connections to other systems via
the telnet protocol. | Rationale: | The telnet protocol is insecure and unencrypted. The use
of an unencrypted transmission medium could allow an unauthorized user
to steal credentials. The ssh package provides an
encrypted session and stronger security and is included in Oracle Linux 8. | Severity: | low | Rule ID: | xccdf_org.ssgproject.content_rule_package_telnet_removed | References: | cui | 3.1.13 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | iso27001-2013 | A.8.2.3, A.13.1.1, A.13.2.1, A.13.2.3, A.14.1.2, A.14.1.3 | anssi | R62 | pcidss4 | 2.2.4, 2.2 |
| |
|
Rule
Disable telnet Service
[ref] | Make sure that the activation of the telnet service on system boot is disabled.
The telnet socket can be disabled with the following command:
$ sudo systemctl mask --now telnet.socket
Warning:
If the system relies on xinetd to manage telnet sessions, ensure the telnet service
is disabled by the following line: disable = yes . Note that the xinetd file for
telnet is not created automatically, therefore it might have different names. | Rationale: | The telnet protocol uses unencrypted network communication, which means that data from the
login session, including passwords and all other information transmitted during the session,
can be stolen by eavesdroppers on the network. The telnet protocol is also subject to
man-in-the-middle attacks. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_service_telnet_disabled | References: | cis-csc | 1, 11, 12, 14, 15, 16, 3, 5, 8, 9 | cobit5 | APO13.01, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS01.04, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.06, DSS06.10 | cui | 3.1.13, 3.4.7 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.18.1.4, A.6.2.1, A.6.2.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3 | nist | CM-7(a), CM-7(b), CM-6(a), IA-5(1)(c) | nist-csf | PR.AC-1, PR.AC-3, PR.AC-6, PR.AC-7, PR.IP-1, PR.PT-3, PR.PT-4 |
| |
|
Group
Network Routing
Group contains 1 group and 1 rule |
[ref]
A router is a very desirable target for a
potential adversary because they fulfill a variety of
infrastructure networking roles such as access to network segments,
gateways to other networks, filtering, etc. Therefore, if one is
required, the system acting as a router should be dedicated
to that purpose alone and be stored in a physically secure
location. The system's default routing software is Quagga, and
provided in an RPM package of the same name. |
Group
Disable Quagga if Possible
Group contains 1 rule |
[ref]
If Quagga was installed and activated, but the system
does not need to act as a router, then it should be disabled
and removed. |
Rule
Disable Quagga Service
[ref] |
The zebra service can be disabled with the following command:
$ sudo systemctl mask --now zebra.service
| Rationale: | Routing protocol daemons are typically used on routers to exchange network
topology information with other routers. If routing daemons are used when not
required, system network information may be unnecessarily transmitted across
the network. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_service_zebra_disabled | References: | cis-csc | 12, 15, 8 | cobit5 | APO13.01, DSS05.02 | disa | CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2013 | SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | iso27001-2013 | A.13.1.1, A.13.2.1, A.14.1.3 | nist | CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.PT-4 | os-srg | SRG-OS-000480-GPOS-00227 |
| |
|
Group
SSH Server
Group contains 1 group and 11 rules |
[ref]
The SSH protocol is recommended for remote login and
remote file transfer. SSH provides confidentiality and integrity
for data exchanged between two systems, as well as server
authentication, through the use of public key cryptography. The
implementation included with the system is called OpenSSH, and more
detailed documentation is available from its website,
https://www.openssh.com.
Its server program is called sshd and provided by the RPM package
openssh-server . |
Group
Configure OpenSSH Server if Necessary
Group contains 11 rules |
[ref]
If the system needs to act as an SSH server, then
certain changes should be made to the OpenSSH daemon configuration
file /etc/ssh/sshd_config . The following recommendations can be
applied to this file. See the sshd_config(5) man page for more
detailed information. |
Rule
Set SSH Client Alive Count Max to zero
[ref] | The SSH server sends at most ClientAliveCountMax messages
during a SSH session and waits for a response from the SSH client.
The option ClientAliveInterval configures timeout after
each ClientAliveCountMax message. If the SSH server does not
receive a response from the client, then the connection is considered unresponsive
and terminated.
To ensure the SSH timeout occurs precisely when the
ClientAliveInterval is set, set the ClientAliveCountMax to
value of 0 in
/etc/ssh/sshd_config : | Rationale: | This ensures a user login will be terminated as soon as the ClientAliveInterval
is reached. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_set_keepalive_0 | References: | cis-csc | 1, 12, 13, 14, 15, 16, 18, 3, 5, 7, 8 | cjis | 5.5.6 | cobit5 | APO13.01, BAI03.01, BAI03.02, BAI03.03, DSS01.03, DSS03.05, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10 | cui | 3.1.11 | disa | CCI-000879, CCI-001133, CCI-002361 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 6.2 | iso27001-2013 | A.12.4.1, A.12.4.3, A.14.1.1, A.14.2.1, A.14.2.5, A.18.1.4, A.6.1.2, A.6.1.5, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5 | nerc-cip | CIP-004-6 R2.2.3, CIP-007-3 R5.1, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3 | nist | AC-2(5), AC-12, AC-17(a), SC-10, CM-6(a) | nist-csf | DE.CM-1, DE.CM-3, PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.IP-2 | pcidss | Req-8.1.8 | os-srg | SRG-OS-000126-GPOS-00066, SRG-OS-000163-GPOS-00072, SRG-OS-000279-GPOS-00109 |
| |
|
Rule
Disable Host-Based Authentication
[ref] | SSH's cryptographic host-based authentication is
more secure than .rhosts authentication. However, it is
not recommended that hosts unilaterally trust one another, even
within an organization.
The default SSH configuration disables host-based authentication. The appropriate
configuration is used if no value is set for HostbasedAuthentication .
To explicitly disable host-based authentication, add or correct the
following line in
/etc/ssh/sshd_config :
HostbasedAuthentication no
| Rationale: | SSH trust relationships mean a compromise on one host
can allow an attacker to move trivially to other hosts. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_disable_host_auth | References: | cis-csc | 11, 12, 14, 15, 16, 18, 3, 5, 9 | cjis | 5.5.6 | cobit5 | BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.03, DSS06.06 | cui | 3.1.12 | disa | CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 7.6 | ism | 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561 | iso27001-2013 | A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4, A.6.1.2, A.7.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3 | nist | AC-3, AC-17(a), CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.AC-4, PR.AC-6, PR.IP-1, PR.PT-3 | ospp | FIA_UAU.1 | os-srg | SRG-OS-000480-GPOS-00229 | pcidss4 | 8.3.1, 8.3 |
| |
|
Rule
Allow Only SSH Protocol 2
[ref] | Only SSH protocol version 2 connections should be
permitted. The default setting in
/etc/ssh/sshd_config is correct, and can be
verified by ensuring that the following
line appears:
Protocol 2
Warning:
As of openssh-server version 7.4 and above, the only protocol
supported is version 2, and line Protocol 2 in
/etc/ssh/sshd_config is not necessary. | Rationale: | SSH protocol version 1 is an insecure implementation of the SSH protocol and
has many well-known vulnerability exploits. Exploits of the SSH daemon could provide
immediate root access to the system. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_allow_only_protocol2 | References: | cis-csc | 1, 12, 15, 16, 5, 8 | cjis | 5.5.6 | cobit5 | APO13.01, DSS01.04, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.03, DSS06.10 | cui | 3.1.13, 3.5.4 | disa | CCI-000197, CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.2, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.6, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 7.1, SR 7.6 | ism | 0487, 1449, 1506 | iso27001-2013 | A.11.2.6, A.13.1.1, A.13.2.1, A.14.1.3, A.18.1.4, A.6.2.1, A.6.2.2, A.7.1.1, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.2, A.9.4.3 | nerc-cip | CIP-003-8 R4.2, CIP-007-3 R5.1, CIP-007-3 R7.1 | nist | CM-6(a), AC-17(a), AC-17(2), IA-5(1)(c), SC-13, MA-4(6) | nist-csf | PR.AC-1, PR.AC-3, PR.AC-6, PR.AC-7, PR.PT-4 | os-srg | SRG-OS-000074-GPOS-00042, SRG-OS-000480-GPOS-00227 |
| |
|
Rule
Disable Compression Or Set Compression to delayed
[ref] | Compression is useful for slow network connections over long
distances but can cause performance issues on local LANs. If use of compression
is required, it should be enabled only after a user has authenticated; otherwise,
it should be disabled. To disable compression or delay compression until after
a user has successfully authenticated, add or correct the following line in the
/etc/ssh/sshd_config file:
Compression no
| Rationale: | If compression is allowed in an SSH connection prior to authentication,
vulnerabilities in the compression software could result in compromise of the
system from an unauthenticated connection, potentially with root privileges. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_disable_compression | References: | cis-csc | 11, 3, 9 | cobit5 | BAI10.01, BAI10.02, BAI10.03, BAI10.05 | cui | 3.1.12 | disa | CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 7.6 | iso27001-2013 | A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4 | nist | AC-17(a), CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.IP-1 | os-srg | SRG-OS-000480-GPOS-00227 |
| |
|
Rule
Disable SSH Access via Empty Passwords
[ref] | Disallow SSH login with empty passwords.
The default SSH configuration disables logins with empty passwords. The appropriate
configuration is used if no value is set for PermitEmptyPasswords .
To explicitly disallow SSH login from accounts with empty passwords,
add or correct the following line in
/etc/ssh/sshd_config :
PermitEmptyPasswords no
Any accounts with empty passwords should be disabled immediately, and PAM configuration
should prevent users from being able to assign themselves empty passwords. | Rationale: | Configuring this setting for the SSH daemon provides additional assurance
that remote login via SSH will require a password, even in the event of
misconfiguration elsewhere. | Severity: | high | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_disable_empty_passwords | References: | cis-csc | 11, 12, 13, 14, 15, 16, 18, 3, 5, 9 | cjis | 5.5.6 | cobit5 | APO01.06, BAI10.01, BAI10.02, BAI10.03, BAI10.05, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS06.02, DSS06.03, DSS06.06 | cui | 3.1.1, 3.1.5 | disa | CCI-000766, CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4, 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 5.2, SR 7.6 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.12.1.2, A.12.5.1, A.12.6.2, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.14.2.2, A.14.2.3, A.14.2.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nist | AC-17(a), CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.AC-4, PR.AC-6, PR.DS-5, PR.IP-1, PR.PT-3 | ospp | FIA_UAU.1 | pcidss | Req-2.2.4 | os-srg | SRG-OS-000106-GPOS-00053, SRG-OS-000480-GPOS-00229, SRG-OS-000480-GPOS-00227 | stigid | OL08-00-020330 | pcidss4 | 2.2.6, 2.2 | stigref | SV-248714r991589_rule |
| |
|
Rule
Disable GSSAPI Authentication
[ref] | Unless needed, SSH should not permit extraneous or unnecessary
authentication mechanisms like GSSAPI.
The default SSH configuration disallows authentications based on GSSAPI. The appropriate
configuration is used if no value is set for GSSAPIAuthentication .
To explicitly disable GSSAPI authentication, add or correct the following line in
/etc/ssh/sshd_config :
GSSAPIAuthentication no
| Rationale: | GSSAPI authentication is used to provide additional authentication mechanisms to
applications. Allowing GSSAPI authentication through SSH exposes the system's
GSSAPI to remote hosts, increasing the attack surface of the system. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_disable_gssapi_auth | References: | cis-csc | 11, 3, 9 | cobit5 | BAI10.01, BAI10.02, BAI10.03, BAI10.05 | cui | 3.1.12 | disa | CCI-000366, CCI-001813 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 7.6 | ism | 0418, 1055, 1402 | iso27001-2013 | A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4 | nist | CM-7(a), CM-7(b), CM-6(a), AC-17(a) | nist-csf | PR.IP-1 | ospp | FTP_ITC_EXT.1, FCS_SSH_EXT.1.2 | os-srg | SRG-OS-000364-GPOS-00151, SRG-OS-000480-GPOS-00227 | stigid | OL08-00-010522 | stigref | SV-248607r991589_rule |
| |
|
Rule
Disable Kerberos Authentication
[ref] | Unless needed, SSH should not permit extraneous or unnecessary
authentication mechanisms like Kerberos.
The default SSH configuration disallows authentication validation through Kerberos.
The appropriate configuration is used if no value is set for KerberosAuthentication .
To explicitly disable Kerberos authentication, add or correct the following line in
/etc/ssh/sshd_config :
KerberosAuthentication no
| Rationale: | Kerberos authentication for SSH is often implemented using GSSAPI. If Kerberos
is enabled through SSH, the SSH daemon provides a means of access to the
system's Kerberos implementation.
Configuring these settings for the SSH daemon provides additional assurance that remote logon via SSH will not use unused methods of authentication, even in the event of misconfiguration elsewhere. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_disable_kerb_auth | References: | cis-csc | 11, 3, 9 | cobit5 | BAI10.01, BAI10.02, BAI10.03, BAI10.05 | cui | 3.1.12 | disa | CCI-000366, CCI-001813 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 7.6 | ism | 0421, 0422, 0431, 0974, 1173, 1401, 1504, 1505, 1546, 1557, 1558, 1559, 1560, 1561 | iso27001-2013 | A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4 | nist | AC-17(a), CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.IP-1 | ospp | FTP_ITC_EXT.1, FCS_SSH_EXT.1.2 | os-srg | SRG-OS-000364-GPOS-00151, SRG-OS-000480-GPOS-00227 | stigid | OL08-00-010521 | stigref | SV-248606r991589_rule |
| |
|
Rule
Disable SSH Root Login
[ref] | The root user should never be allowed to login to a
system directly over a network.
To disable root login via SSH, add or correct the following line in
/etc/ssh/sshd_config :
PermitRootLogin no
| Rationale: | Even though the communications channel may be encrypted, an additional layer of
security is gained by extending the policy of not logging directly on as root.
In addition, logging in with a user-specific account provides individual
accountability of actions performed on the system and also helps to minimize
direct attack attempts on root's password. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_disable_root_login | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 18, 3, 5 | cjis | 5.5.6 | cobit5 | APO01.06, DSS05.02, DSS05.04, DSS05.05, DSS05.07, DSS05.10, DSS06.02, DSS06.03, DSS06.06, DSS06.10 | cui | 3.1.1, 3.1.5 | disa | CCI-000366, CCI-004045 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.2.2, 4.3.3.5.1, 4.3.3.5.2, 4.3.3.5.3, 4.3.3.5.4, 4.3.3.5.5, 4.3.3.5.6, 4.3.3.5.7, 4.3.3.5.8, 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9, 4.3.3.7.1, 4.3.3.7.2, 4.3.3.7.3, 4.3.3.7.4 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.11, SR 1.12, SR 1.13, SR 1.2, SR 1.3, SR 1.4, SR 1.5, SR 1.6, SR 1.7, SR 1.8, SR 1.9, SR 2.1, SR 2.2, SR 2.3, SR 2.4, SR 2.5, SR 2.6, SR 2.7, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.18.1.4, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.1, A.9.2.2, A.9.2.3, A.9.2.4, A.9.2.6, A.9.3.1, A.9.4.1, A.9.4.2, A.9.4.3, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.2.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2, CIP-007-3 R5.2, CIP-007-3 R5.3.1, CIP-007-3 R5.3.2, CIP-007-3 R5.3.3 | nist | AC-6(2), AC-17(a), IA-2, IA-2(5), CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.AC-1, PR.AC-4, PR.AC-6, PR.AC-7, PR.DS-5, PR.PT-3 | ospp | FAU_GEN.1 | pcidss | Req-2.2.4 | os-srg | SRG-OS-000109-GPOS-00056, SRG-OS-000480-GPOS-00227 | app-srg-ctr | SRG-APP-000148-CTR-000335, SRG-APP-000190-CTR-000500 | stigid | OL08-00-010550 | anssi | R33 | pcidss4 | 2.2.6, 2.2 | stigref | SV-248613r986343_rule |
| |
|
Rule
Do Not Allow SSH Environment Options
[ref] | Ensure that users are not able to override environment variables of the SSH daemon.
The default SSH configuration disables environment processing. The appropriate
configuration is used if no value is set for PermitUserEnvironment .
To explicitly disable Environment options, add or correct the following
/etc/ssh/sshd_config :
PermitUserEnvironment no
| Rationale: | SSH environment options potentially allow users to bypass
access restriction in some configurations. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_do_not_permit_user_env | References: | cis-csc | 11, 3, 9 | cjis | 5.5.6 | cobit5 | BAI10.01, BAI10.02, BAI10.03, BAI10.05 | cui | 3.1.12 | disa | CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.4.3.2, 4.3.4.3.3 | isa-62443-2013 | SR 7.6 | iso27001-2013 | A.12.1.2, A.12.5.1, A.12.6.2, A.14.2.2, A.14.2.3, A.14.2.4 | nist | AC-17(a), CM-7(a), CM-7(b), CM-6(a) | nist-csf | PR.IP-1 | pcidss | Req-2.2.4 | os-srg | SRG-OS-000480-GPOS-00229 | stigid | OL08-00-010830 | pcidss4 | 2.2.6, 2.2 | stigref | SV-248650r991591_rule |
| |
|
Rule
Enable Use of Strict Mode Checking
[ref] | SSHs StrictModes option checks file and ownership permissions in
the user's home directory .ssh folder before accepting login. If world-
writable permissions are found, logon is rejected.
The default SSH configuration has StrictModes enabled. The appropriate
configuration is used if no value is set for StrictModes .
To explicitly enable StrictModes in SSH, add or correct the following line in
/etc/ssh/sshd_config :
StrictModes yes
| Rationale: | If other users have access to modify user-specific SSH configuration files, they
may be able to log into the system as another user. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_enable_strictmodes | References: | cis-csc | 12, 13, 14, 15, 16, 18, 3, 5 | cobit5 | APO01.06, DSS05.04, DSS05.07, DSS06.02 | cui | 3.1.12 | disa | CCI-000366 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.7.3 | isa-62443-2013 | SR 2.1, SR 5.2 | iso27001-2013 | A.10.1.1, A.11.1.4, A.11.1.5, A.11.2.1, A.13.1.1, A.13.1.3, A.13.2.1, A.13.2.3, A.13.2.4, A.14.1.2, A.14.1.3, A.6.1.2, A.7.1.1, A.7.1.2, A.7.3.1, A.8.2.2, A.8.2.3, A.9.1.1, A.9.1.2, A.9.2.3, A.9.4.1, A.9.4.4, A.9.4.5 | nerc-cip | CIP-003-8 R5.1.1, CIP-003-8 R5.3, CIP-004-6 R2.3, CIP-007-3 R2.1, CIP-007-3 R2.2, CIP-007-3 R2.3, CIP-007-3 R5.1, CIP-007-3 R5.1.1, CIP-007-3 R5.1.2 | nist | AC-6, AC-17(a), CM-6(a) | nist-csf | PR.AC-4, PR.DS-5 | os-srg | SRG-OS-000480-GPOS-00227 | stigid | OL08-00-010500 | stigref | SV-248603r991589_rule |
| |
|
Rule
Enable SSH Warning Banner
[ref] | To enable the warning banner and ensure it is consistent
across the system, add or correct the following line in
/etc/ssh/sshd_config :
Banner /etc/issue
Another section contains information on how to create an
appropriate system-wide warning banner. | Rationale: | The warning message reinforces policy awareness during the logon process and
facilitates possible legal action against attackers. Alternatively, systems
whose ownership should not be obvious should ensure usage of a banner that does
not provide easy attribution. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_sshd_enable_warning_banner | References: | cis-csc | 1, 12, 15, 16 | cjis | 5.5.6 | cobit5 | DSS05.04, DSS05.10, DSS06.10 | cui | 3.1.9 | disa | CCI-001387, CCI-001384, CCI-000048, CCI-001386, CCI-001388, CCI-001385 | hipaa | 164.308(a)(4)(i), 164.308(b)(1), 164.308(b)(3), 164.310(b), 164.312(e)(1), 164.312(e)(2)(ii) | isa-62443-2009 | 4.3.3.6.1, 4.3.3.6.2, 4.3.3.6.3, 4.3.3.6.4, 4.3.3.6.5, 4.3.3.6.6, 4.3.3.6.7, 4.3.3.6.8, 4.3.3.6.9 | isa-62443-2013 | SR 1.1, SR 1.10, SR 1.2, SR 1.5, SR 1.7, SR 1.8, SR 1.9 | iso27001-2013 | A.18.1.4, A.9.2.1, A.9.2.4, A.9.3.1, A.9.4.2, A.9.4.3 | nist | AC-8(a), AC-8(c), AC-17(a), CM-6(a) | nist-csf | PR.AC-7 | ospp | FTA_TAB.1 | pcidss | Req-2.2.4 | os-srg | SRG-OS-000023-GPOS-00006, SRG-OS-000228-GPOS-00088 | stigid | OL08-00-010040 | stigref | SV-248526r958390_rule |
| |
|
Group
System Accounting with auditd
Group contains 10 groups and 70 rules |
[ref]
The audit service provides substantial capabilities
for recording system activities. By default, the service audits about
SELinux AVC denials and certain types of security-relevant events
such as system logins, account modifications, and authentication
events performed by programs such as sudo.
Under its default configuration, auditd has modest disk space
requirements, and should not noticeably impact system performance.
NOTE: The Linux Audit daemon auditd can be configured to use
the augenrules program to read audit rules files ( *.rules )
located in /etc/audit/rules.d location and compile them to create
the resulting form of the /etc/audit/audit.rules configuration file
during the daemon startup (default configuration). Alternatively, the auditd
daemon can use the auditctl utility to read audit rules from the
/etc/audit/audit.rules configuration file during daemon startup,
and load them into the kernel. The expected behavior is configured via the
appropriate ExecStartPost directive setting in the
/usr/lib/systemd/system/auditd.service configuration file.
To instruct the auditd daemon to use the augenrules program
to read audit rules (default configuration), use the following setting:
ExecStartPost=-/sbin/augenrules --load
in the /usr/lib/systemd/system/auditd.service configuration file.
In order to instruct the auditd daemon to use the auditctl
utility to read audit rules, use the following setting:
ExecStartPost=-/sbin/auditctl -R /etc/audit/audit.rules
in the /usr/lib/systemd/system/auditd.service configuration file.
Refer to [Service] section of the /usr/lib/systemd/system/auditd.service
configuration file for further details.
Government networks often have substantial auditing
requirements and auditd can be configured to meet these
requirements.
Examining some example audit records demonstrates how the Linux audit system
satisfies common requirements.
The following example from Red Hat Enterprise Linux 7 Documentation available at
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/selinux_users_and_administrators_guide/index#sect-Security-Enhanced_Linux-Fixing_Problems-Raw_Audit_Messages
shows the substantial amount of information captured in a
two typical "raw" audit messages, followed by a breakdown of the most important
fields. In this example the message is SELinux-related and reports an AVC
denial (and the associated system call) that occurred when the Apache HTTP
Server attempted to access the /var/www/html/file1 file (labeled with
the samba_share_t type):
type=AVC msg=audit(1226874073.147:96): avc: denied { getattr } for pid=2465 comm="httpd"
path="/var/www/html/file1" dev=dm-0 ino=284133 scontext=unconfined_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file
type=SYSCALL msg=audit(1226874073.147:96): arch=40000003 syscall=196 success=no exit=-13
a0=b98df198 a1=bfec85dc a2=54dff4 a3=2008171 items=0 ppid=2463 pid=2465 auid=502 uid=48
gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=6 comm="httpd"
exe="/usr/sbin/httpd" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
msg=audit(1226874073.147:96) - The number in parentheses is the unformatted time stamp (Epoch time)
for the event, which can be converted to standard time by using the
date command.
{ getattr } - The item in braces indicates the permission that was denied.
getattr
indicates the source process was trying to read the target file's status information.
This occurs before reading files. This action is denied due to the file being
accessed having the wrong label. Commonly seen permissions include getattr ,
read , and write .
comm="httpd" - The executable that launched the process. The full path of the executable is
found in the
exe= section of the system call (SYSCALL ) message,
which in this case, is exe="/usr/sbin/httpd" .
path="/var/www/html/file1" - The path to the object (target) the process attempted to access.
scontext="unconfined_u:system_r:httpd_t:s0" - The SELinux context of the process that attempted the denied action. In
this case, it is the SELinux context of the Apache HTTP Server, which is running
in the
httpd_t domain.
tcontext="unconfined_u:object_r:samba_share_t:s0" - The SELinux context of the object (target) the process attempted to access.
In this case, it is the SELinux context of
file1 . Note: the samba_share_t
type is not accessible to processes running in the httpd_t domain.
- From the system call (
SYSCALL ) message, two items are of interest:
success=no : indicates whether the denial (AVC) was enforced or not.
success=no indicates the system call was not successful (SELinux denied
access). success=yes indicates the system call was successful - this can
be seen for permissive domains or unconfined domains, such as initrc_t
and kernel_t .
exe="/usr/sbin/httpd" : the full path to the executable that launched
the process, which in this case, is exe="/usr/sbin/httpd" .
|
Group
Configure auditd Rules for Comprehensive Auditing
Group contains 8 groups and 66 rules |
[ref]
The auditd program can perform comprehensive
monitoring of system activity. This section describes recommended
configuration settings for comprehensive auditing, but a full
description of the auditing system's capabilities is beyond the
scope of this guide. The mailing list linux-audit@redhat.com exists
to facilitate community discussion of the auditing system.
The audit subsystem supports extensive collection of events, including:
- Tracing of arbitrary system calls (identified by name or number)
on entry or exit.
- Filtering by PID, UID, call success, system call argument (with
some limitations), etc.
- Monitoring of specific files for modifications to the file's
contents or metadata.
Auditing rules at startup are controlled by the file /etc/audit/audit.rules .
Add rules to it to meet the auditing requirements for your organization.
Each line in /etc/audit/audit.rules represents a series of arguments
that can be passed to auditctl and can be individually tested
during runtime. See documentation in /usr/share/doc/audit-VERSION
and
in the related man pages for more details.
If copying any example audit rulesets from /usr/share/doc/audit-VERSION ,
be sure to comment out the
lines containing arch= which are not appropriate for your system's
architecture. Then review and understand the following rules,
ensuring rules are activated as needed for the appropriate
architecture.
After reviewing all the rules, reading the following sections, and
editing as needed, the new rules can be activated as follows:
$ sudo service auditd restart
|
Group
Record Events that Modify the System's Discretionary Access Controls
Group contains 13 rules |
[ref]
At a minimum, the audit system should collect file permission
changes for all users and root. Note that the "-F arch=b32" lines should be
present even on a 64 bit system. These commands identify system calls for
auditing. Even if the system is 64 bit it can still execute 32 bit system
calls. Additionally, these rules can be configured in a number of ways while
still achieving the desired effect. An example of this is that the "-S" calls
could be split up and placed on separate lines, however, this is less efficient.
Add the following to /etc/audit/audit.rules :
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b32 -S chown,fchown,fchownat,lchown -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod
If your system is 64 bit then these lines should be duplicated and the
arch=b32 replaced with arch=b64 as follows:
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S chown,fchown,fchownat,lchown -F auid>=1000 -F auid!=unset -F key=perm_mod
-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=unset -F key=perm_mod
|
Rule
Record Events that Modify the System's Discretionary Access Controls - chmod
[ref] | At a minimum, the audit system should collect file permission
changes for all users and root. If the auditd daemon is configured to
use the augenrules program to read audit rules during daemon startup
(the default), add the following line to a file with suffix .rules in
the directory /etc/audit/rules.d :
-a always,exit -F arch=b32 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod
If the auditd daemon is configured to use the auditctl
utility to read audit rules during daemon startup, add the following line to
/etc/audit/audit.rules file:
-a always,exit -F arch=b32 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S chmod -F auid>=1000 -F auid!=unset -F key=perm_mod
Warning:
Note that these rules can be configured in a
number of ways while still achieving the desired effect. Here the system calls
have been placed independent of other system calls. Grouping these system
calls with others as identifying earlier in this guide is more efficient. | Rationale: | The changing of file permissions could indicate that a user is attempting to
gain access to information that would otherwise be disallowed. Auditing DAC modifications
can facilitate the identification of patterns of abuse among both authorized and
unauthorized users. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_audit_rules_dac_modification_chmod | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 19, 2, 3, 4, 5, 6, 7, 8, 9 | cjis | 5.4.1.1 | cobit5 | APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, APO12.06, APO13.01, BAI03.05, BAI08.02, DSS01.03, DSS01.04, DSS02.02, DSS02.04, DSS02.07, DSS03.01, DSS03.05, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01 | cui | 3.1.7 | disa | CCI-000172, CCI-000130, CCI-000135, CCI-000169, CCI-002884 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3)(ii)(A), 164.308(a)(5)(ii)(C), 164.312(a)(2)(i), 164.312(b), 164.312(d), 164.312(e) | isa-62443-2009 | 4.2.3.10, 4.3.2.6.7, 4.3.3.3.9, 4.3.3.5.8, 4.3.3.6.6, 4.3.4.4.7, 4.3.4.5.6, 4.3.4.5.7, 4.3.4.5.8, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 1.13, SR 2.10, SR 2.11, SR 2.12, SR 2.6, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.1, SR 6.2, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.7, A.15.2.1, A.15.2.2, A.16.1.4, A.16.1.5, A.16.1.7, A.6.2.1, A.6.2.2 | nist | AU-2(d), AU-12(c), CM-6(a) | nist-csf | DE.AE-3, DE.AE-5, DE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.AC-3, PR.PT-1, PR.PT-4, RS.AN-1, RS.AN-4 | pcidss | Req-10.5.5 | os-srg | SRG-OS-000037-GPOS-00015, SRG-OS-000042-GPOS-00020, SRG-OS-000062-GPOS-00031, SRG-OS-000392-GPOS-00172, SRG-OS-000462-GPOS-00206, SRG-OS-000471-GPOS-00215, SRG-OS-000064-GPOS-00033, SRG-OS-000466-GPOS-00210, SRG-OS-000458-GPOS-00203 | app-srg-ctr | SRG-APP-000091-CTR-000160, SRG-APP-000492-CTR-001220, SRG-APP-000493-CTR-001225, SRG-APP-000494-CTR-001230, SRG-APP-000500-CTR-001260, SRG-APP-000507-CTR-001295, SRG-APP-000495-CTR-001235, SRG-APP-000499-CTR-001255 | stigid | OL08-00-030490 | anssi | R73 | pcidss4 | 10.3.4, 10.3 | stigref | SV-248791r958412_rule |
| Remediation Ansible snippet ⇲Complexity: | low |
---|
Disruption: | low |
---|
Reboot: | true |
---|
Strategy: | restrict |
---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_chmod
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Set architecture for audit chmod tasks
set_fact:
audit_arch: b64
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- not ( ansible_architecture == "aarch64" )
- ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
== "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_chmod
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for chmod for 32bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- chmod
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of chmod in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- chmod
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of chmod in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- not ( ansible_architecture == "aarch64" )
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_chmod
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for chmod for 64bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- chmod
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of chmod in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- chmod
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of chmod in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- not ( ansible_architecture == "aarch64" )
- audit_arch == "b64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_chmod
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
Remediation Shell script ⇲# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && rpm --quiet -q audit && { ! ( grep -q aarch64 /proc/sys/kernel/osrelease ); }; then
# First perform the remediation of the syscall rule
# Retrieve hardware architecture of the underlying system
[ "$(getconf LONG_BIT)" = "32" ] && RULE_ARCHS=("b32") || RULE_ARCHS=("b32" "b64")
for ARCH in "${RULE_ARCHS[@]}"
do
ACTION_ARCH_FILTERS="-a always,exit -F arch=$ARCH"
OTHER_FILTERS=""
AUID_FILTERS="-F auid>=1000 -F auid!=unset"
SYSCALL="chmod"
KEY="perm_mod"
SYSCALL_GROUPING="chmod fchmod fchmodat"
# Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'augenrules', then check if the audit rule is defined
# If rule is defined, add '/etc/audit/rules.d/*.rules' to the list for inspection
# If rule isn't defined yet, add '/etc/audit/rules.d/$key.rules' to the list for inspection
default_file="/etc/audit/rules.d/$KEY.rules"
# As other_filters may include paths, lets use a different delimiter for it
# The "F" script expression tells sed to print the filenames where the expressions matched
readarray -t files_to_inspect < <(sed -s -n -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" -e "F" /etc/audit/rules.d/*.rules)
# Case when particular rule isn't defined in /etc/audit/rules.d/*.rules yet
if [ ${#files_to_inspect[@]} -eq "0" ]
then
file_to_inspect="/etc/audit/rules.d/$KEY.rules"
files_to_inspect=("$file_to_inspect")
if [ ! -e "$file_to_inspect" ]
then
touch "$file_to_inspect"
chmod 0640 "$file_to_inspect"
fi
fi
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'auditctl', then add '/etc/audit/audit.rules'
# file to the list of files to be inspected
default_file="/etc/audit/audit.rules"
files_to_inspect+=('/etc/audit/audit.rules' )
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
|
Rule
Record Events that Modify the System's Discretionary Access Controls - chown
[ref] | At a minimum, the audit system should collect file permission
changes for all users and root. If the auditd daemon is configured to
use the augenrules program to read audit rules during daemon startup
(the default), add the following line to a file with suffix .rules in
the directory /etc/audit/rules.d :
-a always,exit -F arch=b32 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod
If the auditd daemon is configured to use the auditctl
utility to read audit rules during daemon startup, add the following line to
/etc/audit/audit.rules file:
-a always,exit -F arch=b32 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S chown -F auid>=1000 -F auid!=unset -F key=perm_mod
Warning:
Note that these rules can be configured in a
number of ways while still achieving the desired effect. Here the system calls
have been placed independent of other system calls. Grouping these system
calls with others as identifying earlier in this guide is more efficient. | Rationale: | The changing of file permissions could indicate that a user is attempting to
gain access to information that would otherwise be disallowed. Auditing DAC modifications
can facilitate the identification of patterns of abuse among both authorized and
unauthorized users. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_audit_rules_dac_modification_chown | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 19, 2, 3, 4, 5, 6, 7, 8, 9 | cjis | 5.4.1.1 | cobit5 | APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, APO12.06, APO13.01, BAI03.05, BAI08.02, DSS01.03, DSS01.04, DSS02.02, DSS02.04, DSS02.07, DSS03.01, DSS03.05, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01 | cui | 3.1.7 | disa | CCI-000172, CCI-000130, CCI-000135, CCI-000169, CCI-002884 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3)(ii)(A), 164.308(a)(5)(ii)(C), 164.312(a)(2)(i), 164.312(b), 164.312(d), 164.312(e) | isa-62443-2009 | 4.2.3.10, 4.3.2.6.7, 4.3.3.3.9, 4.3.3.5.8, 4.3.3.6.6, 4.3.4.4.7, 4.3.4.5.6, 4.3.4.5.7, 4.3.4.5.8, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 1.13, SR 2.10, SR 2.11, SR 2.12, SR 2.6, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.1, SR 6.2, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.7, A.15.2.1, A.15.2.2, A.16.1.4, A.16.1.5, A.16.1.7, A.6.2.1, A.6.2.2 | nist | AU-2(d), AU-12(c), CM-6(a) | nist-csf | DE.AE-3, DE.AE-5, DE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.AC-3, PR.PT-1, PR.PT-4, RS.AN-1, RS.AN-4 | pcidss | Req-10.5.5 | os-srg | SRG-OS-000037-GPOS-00015, SRG-OS-000042-GPOS-00020, SRG-OS-000062-GPOS-00031, SRG-OS-000392-GPOS-00172, SRG-OS-000462-GPOS-00206, SRG-OS-000471-GPOS-00215, SRG-OS-000064-GPOS-00033, SRG-OS-000466-GPOS-00210, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219 | app-srg-ctr | SRG-APP-000091-CTR-000160, SRG-APP-000492-CTR-001220, SRG-APP-000493-CTR-001225, SRG-APP-000494-CTR-001230, SRG-APP-000500-CTR-001260, SRG-APP-000507-CTR-001295, SRG-APP-000495-CTR-001235, SRG-APP-000499-CTR-001255 | stigid | OL08-00-030480 | anssi | R73 | pcidss4 | 10.3.4, 10.3 | stigref | SV-248790r958412_rule |
| Remediation Ansible snippet ⇲Complexity: | low |
---|
Disruption: | low |
---|
Reboot: | true |
---|
Strategy: | restrict |
---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030480
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_chown
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Set architecture for audit chown tasks
set_fact:
audit_arch: b64
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- not ( ansible_architecture == "aarch64" )
- ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
== "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030480
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_chown
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for chown for 32bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- chown
syscall_grouping:
- chown
- fchown
- fchownat
- lchown
- name: Check existence of chown in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- chown
syscall_grouping:
- chown
- fchown
- fchownat
- lchown
- name: Check existence of chown in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- not ( ansible_architecture == "aarch64" )
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030480
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_chown
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for chown for 64bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- chown
syscall_grouping:
- chown
- fchown
- fchownat
- lchown
- name: Check existence of chown in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- chown
syscall_grouping:
- chown
- fchown
- fchownat
- lchown
- name: Check existence of chown in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- not ( ansible_architecture == "aarch64" )
- audit_arch == "b64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030480
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_chown
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
Remediation Shell script ⇲# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && rpm --quiet -q audit && { ! ( grep -q aarch64 /proc/sys/kernel/osrelease ); }; then
# First perform the remediation of the syscall rule
# Retrieve hardware architecture of the underlying system
[ "$(getconf LONG_BIT)" = "32" ] && RULE_ARCHS=("b32") || RULE_ARCHS=("b32" "b64")
for ARCH in "${RULE_ARCHS[@]}"
do
ACTION_ARCH_FILTERS="-a always,exit -F arch=$ARCH"
OTHER_FILTERS=""
AUID_FILTERS="-F auid>=1000 -F auid!=unset"
SYSCALL="chown"
KEY="perm_mod"
SYSCALL_GROUPING="chown fchown fchownat lchown"
# Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'augenrules', then check if the audit rule is defined
# If rule is defined, add '/etc/audit/rules.d/*.rules' to the list for inspection
# If rule isn't defined yet, add '/etc/audit/rules.d/$key.rules' to the list for inspection
default_file="/etc/audit/rules.d/$KEY.rules"
# As other_filters may include paths, lets use a different delimiter for it
# The "F" script expression tells sed to print the filenames where the expressions matched
readarray -t files_to_inspect < <(sed -s -n -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" -e "F" /etc/audit/rules.d/*.rules)
# Case when particular rule isn't defined in /etc/audit/rules.d/*.rules yet
if [ ${#files_to_inspect[@]} -eq "0" ]
then
file_to_inspect="/etc/audit/rules.d/$KEY.rules"
files_to_inspect=("$file_to_inspect")
if [ ! -e "$file_to_inspect" ]
then
touch "$file_to_inspect"
chmod 0640 "$file_to_inspect"
fi
fi
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'auditctl', then add '/etc/audit/audit.rules'
# file to the list of files to be inspected
default_file="/etc/audit/audit.rules"
files_to_inspect+=('/etc/audit/audit.rules' )
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
|
Rule
Record Events that Modify the System's Discretionary Access Controls - fchmod
[ref] | At a minimum, the audit system should collect file permission
changes for all users and root. If the auditd daemon is configured to
use the augenrules program to read audit rules during daemon startup
(the default), add the following line to a file with suffix .rules in
the directory /etc/audit/rules.d :
-a always,exit -F arch=b32 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod
If the auditd daemon is configured to use the auditctl
utility to read audit rules during daemon startup, add the following line to
/etc/audit/audit.rules file:
-a always,exit -F arch=b32 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S fchmod -F auid>=1000 -F auid!=unset -F key=perm_mod
Warning:
Note that these rules can be configured in a
number of ways while still achieving the desired effect. Here the system calls
have been placed independent of other system calls. Grouping these system
calls with others as identifying earlier in this guide is more efficient. | Rationale: | The changing of file permissions could indicate that a user is attempting to
gain access to information that would otherwise be disallowed. Auditing DAC modifications
can facilitate the identification of patterns of abuse among both authorized and
unauthorized users. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_audit_rules_dac_modification_fchmod | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 19, 2, 3, 4, 5, 6, 7, 8, 9 | cjis | 5.4.1.1 | cobit5 | APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, APO12.06, APO13.01, BAI03.05, BAI08.02, DSS01.03, DSS01.04, DSS02.02, DSS02.04, DSS02.07, DSS03.01, DSS03.05, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01 | cui | 3.1.7 | disa | CCI-000172, CCI-000130, CCI-000135, CCI-000169, CCI-002884 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3)(ii)(A), 164.308(a)(5)(ii)(C), 164.312(a)(2)(i), 164.312(b), 164.312(d), 164.312(e) | isa-62443-2009 | 4.2.3.10, 4.3.2.6.7, 4.3.3.3.9, 4.3.3.5.8, 4.3.3.6.6, 4.3.4.4.7, 4.3.4.5.6, 4.3.4.5.7, 4.3.4.5.8, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 1.13, SR 2.10, SR 2.11, SR 2.12, SR 2.6, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.1, SR 6.2, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.7, A.15.2.1, A.15.2.2, A.16.1.4, A.16.1.5, A.16.1.7, A.6.2.1, A.6.2.2 | nist | AU-2(d), AU-12(c), CM-6(a) | nist-csf | DE.AE-3, DE.AE-5, DE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.AC-3, PR.PT-1, PR.PT-4, RS.AN-1, RS.AN-4 | pcidss | Req-10.5.5 | os-srg | SRG-OS-000037-GPOS-00015, SRG-OS-000042-GPOS-00020, SRG-OS-000062-GPOS-00031, SRG-OS-000392-GPOS-00172, SRG-OS-000462-GPOS-00206, SRG-OS-000471-GPOS-00215, SRG-OS-000064-GPOS-00033, SRG-OS-000466-GPOS-00210, SRG-OS-000458-GPOS-00203 | app-srg-ctr | SRG-APP-000091-CTR-000160, SRG-APP-000492-CTR-001220, SRG-APP-000493-CTR-001225, SRG-APP-000494-CTR-001230, SRG-APP-000500-CTR-001260, SRG-APP-000507-CTR-001295, SRG-APP-000495-CTR-001235, SRG-APP-000499-CTR-001255 | stigid | OL08-00-030490 | anssi | R73 | pcidss4 | 10.3.4, 10.3 | stigref | SV-248791r958412_rule |
| Remediation Ansible snippet ⇲Complexity: | low |
---|
Disruption: | low |
---|
Reboot: | true |
---|
Strategy: | restrict |
---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchmod
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Set architecture for audit fchmod tasks
set_fact:
audit_arch: b64
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
== "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchmod
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for fchmod for 32bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- fchmod
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of fchmod in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- fchmod
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of fchmod in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchmod
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for fchmod for 64bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- fchmod
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of fchmod in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- fchmod
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of fchmod in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- audit_arch == "b64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchmod
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
Remediation Shell script ⇲# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && rpm --quiet -q audit; then
# First perform the remediation of the syscall rule
# Retrieve hardware architecture of the underlying system
[ "$(getconf LONG_BIT)" = "32" ] && RULE_ARCHS=("b32") || RULE_ARCHS=("b32" "b64")
for ARCH in "${RULE_ARCHS[@]}"
do
ACTION_ARCH_FILTERS="-a always,exit -F arch=$ARCH"
OTHER_FILTERS=""
AUID_FILTERS="-F auid>=1000 -F auid!=unset"
SYSCALL="fchmod"
KEY="perm_mod"
SYSCALL_GROUPING="chmod fchmod fchmodat"
# Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'augenrules', then check if the audit rule is defined
# If rule is defined, add '/etc/audit/rules.d/*.rules' to the list for inspection
# If rule isn't defined yet, add '/etc/audit/rules.d/$key.rules' to the list for inspection
default_file="/etc/audit/rules.d/$KEY.rules"
# As other_filters may include paths, lets use a different delimiter for it
# The "F" script expression tells sed to print the filenames where the expressions matched
readarray -t files_to_inspect < <(sed -s -n -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" -e "F" /etc/audit/rules.d/*.rules)
# Case when particular rule isn't defined in /etc/audit/rules.d/*.rules yet
if [ ${#files_to_inspect[@]} -eq "0" ]
then
file_to_inspect="/etc/audit/rules.d/$KEY.rules"
files_to_inspect=("$file_to_inspect")
if [ ! -e "$file_to_inspect" ]
then
touch "$file_to_inspect"
chmod 0640 "$file_to_inspect"
fi
fi
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'auditctl', then add '/etc/audit/audit.rules'
# file to the list of files to be inspected
default_file="/etc/audit/audit.rules"
files_to_inspect+=('/etc/audit/audit.rules' )
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
|
Rule
Record Events that Modify the System's Discretionary Access Controls - fchmodat
[ref] | At a minimum, the audit system should collect file permission
changes for all users and root. If the auditd daemon is configured to
use the augenrules program to read audit rules during daemon startup
(the default), add the following line to a file with suffix .rules in
the directory /etc/audit/rules.d :
-a always,exit -F arch=b32 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
If the auditd daemon is configured to use the auditctl
utility to read audit rules during daemon startup, add the following line to
/etc/audit/audit.rules file:
-a always,exit -F arch=b32 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S fchmodat -F auid>=1000 -F auid!=unset -F key=perm_mod
Warning:
Note that these rules can be configured in a
number of ways while still achieving the desired effect. Here the system calls
have been placed independent of other system calls. Grouping these system
calls with others as identifying earlier in this guide is more efficient. | Rationale: | The changing of file permissions could indicate that a user is attempting to
gain access to information that would otherwise be disallowed. Auditing DAC modifications
can facilitate the identification of patterns of abuse among both authorized and
unauthorized users. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_audit_rules_dac_modification_fchmodat | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 19, 2, 3, 4, 5, 6, 7, 8, 9 | cjis | 5.4.1.1 | cobit5 | APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, APO12.06, APO13.01, BAI03.05, BAI08.02, DSS01.03, DSS01.04, DSS02.02, DSS02.04, DSS02.07, DSS03.01, DSS03.05, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01 | cui | 3.1.7 | disa | CCI-000172, CCI-000130, CCI-000135, CCI-000169, CCI-002884 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3)(ii)(A), 164.308(a)(5)(ii)(C), 164.312(a)(2)(i), 164.312(b), 164.312(d), 164.312(e) | isa-62443-2009 | 4.2.3.10, 4.3.2.6.7, 4.3.3.3.9, 4.3.3.5.8, 4.3.3.6.6, 4.3.4.4.7, 4.3.4.5.6, 4.3.4.5.7, 4.3.4.5.8, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 1.13, SR 2.10, SR 2.11, SR 2.12, SR 2.6, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.1, SR 6.2, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.7, A.15.2.1, A.15.2.2, A.16.1.4, A.16.1.5, A.16.1.7, A.6.2.1, A.6.2.2 | nist | AU-2(d), AU-12(c), CM-6(a) | nist-csf | DE.AE-3, DE.AE-5, DE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.AC-3, PR.PT-1, PR.PT-4, RS.AN-1, RS.AN-4 | pcidss | Req-10.5.5 | os-srg | SRG-OS-000037-GPOS-00015, SRG-OS-000042-GPOS-00020, SRG-OS-000062-GPOS-00031, SRG-OS-000392-GPOS-00172, SRG-OS-000462-GPOS-00206, SRG-OS-000471-GPOS-00215, SRG-OS-000064-GPOS-00033, SRG-OS-000466-GPOS-00210, SRG-OS-000458-GPOS-00203 | app-srg-ctr | SRG-APP-000091-CTR-000160, SRG-APP-000492-CTR-001220, SRG-APP-000493-CTR-001225, SRG-APP-000494-CTR-001230, SRG-APP-000500-CTR-001260, SRG-APP-000507-CTR-001295, SRG-APP-000495-CTR-001235, SRG-APP-000499-CTR-001255 | stigid | OL08-00-030490 | anssi | R73 | pcidss4 | 10.3.4, 10.3 | stigref | SV-248791r958412_rule |
| Remediation Ansible snippet ⇲Complexity: | low |
---|
Disruption: | low |
---|
Reboot: | true |
---|
Strategy: | restrict |
---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchmodat
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Set architecture for audit fchmodat tasks
set_fact:
audit_arch: b64
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
== "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchmodat
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for fchmodat for 32bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- fchmodat
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of fchmodat in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- fchmodat
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of fchmodat in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchmodat
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for fchmodat for 64bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- fchmodat
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of fchmodat in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- fchmodat
syscall_grouping:
- chmod
- fchmod
- fchmodat
- name: Check existence of fchmodat in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- audit_arch == "b64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030490
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchmodat
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
Remediation Shell script ⇲# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && rpm --quiet -q audit; then
# First perform the remediation of the syscall rule
# Retrieve hardware architecture of the underlying system
[ "$(getconf LONG_BIT)" = "32" ] && RULE_ARCHS=("b32") || RULE_ARCHS=("b32" "b64")
for ARCH in "${RULE_ARCHS[@]}"
do
ACTION_ARCH_FILTERS="-a always,exit -F arch=$ARCH"
OTHER_FILTERS=""
AUID_FILTERS="-F auid>=1000 -F auid!=unset"
SYSCALL="fchmodat"
KEY="perm_mod"
SYSCALL_GROUPING="chmod fchmod fchmodat"
# Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'augenrules', then check if the audit rule is defined
# If rule is defined, add '/etc/audit/rules.d/*.rules' to the list for inspection
# If rule isn't defined yet, add '/etc/audit/rules.d/$key.rules' to the list for inspection
default_file="/etc/audit/rules.d/$KEY.rules"
# As other_filters may include paths, lets use a different delimiter for it
# The "F" script expression tells sed to print the filenames where the expressions matched
readarray -t files_to_inspect < <(sed -s -n -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" -e "F" /etc/audit/rules.d/*.rules)
# Case when particular rule isn't defined in /etc/audit/rules.d/*.rules yet
if [ ${#files_to_inspect[@]} -eq "0" ]
then
file_to_inspect="/etc/audit/rules.d/$KEY.rules"
files_to_inspect=("$file_to_inspect")
if [ ! -e "$file_to_inspect" ]
then
touch "$file_to_inspect"
chmod 0640 "$file_to_inspect"
fi
fi
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'auditctl', then add '/etc/audit/audit.rules'
# file to the list of files to be inspected
default_file="/etc/audit/audit.rules"
files_to_inspect+=('/etc/audit/audit.rules' )
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
|
Rule
Record Events that Modify the System's Discretionary Access Controls - fchown
[ref] | At a minimum, the audit system should collect file permission
changes for all users and root. If the auditd daemon is configured
to use the augenrules program to read audit rules during daemon
startup (the default), add the following line to a file with suffix
.rules in the directory /etc/audit/rules.d :
-a always,exit -F arch=b32 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod
If the auditd daemon is configured to use the auditctl
utility to read audit rules during daemon startup, add the following line to
/etc/audit/audit.rules file:
-a always,exit -F arch=b32 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S fchown -F auid>=1000 -F auid!=unset -F key=perm_mod
Warning:
Note that these rules can be configured in a
number of ways while still achieving the desired effect. Here the system calls
have been placed independent of other system calls. Grouping these system
calls with others as identifying earlier in this guide is more efficient. | Rationale: | The changing of file permissions could indicate that a user is attempting to
gain access to information that would otherwise be disallowed. Auditing DAC modifications
can facilitate the identification of patterns of abuse among both authorized and
unauthorized users. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_audit_rules_dac_modification_fchown | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 19, 2, 3, 4, 5, 6, 7, 8, 9 | cjis | 5.4.1.1 | cobit5 | APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, APO12.06, APO13.01, BAI03.05, BAI08.02, DSS01.03, DSS01.04, DSS02.02, DSS02.04, DSS02.07, DSS03.01, DSS03.05, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01 | cui | 3.1.7 | disa | CCI-000172, CCI-000130, CCI-000135, CCI-000169, CCI-002884 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3)(ii)(A), 164.308(a)(5)(ii)(C), 164.312(a)(2)(i), 164.312(b), 164.312(d), 164.312(e) | isa-62443-2009 | 4.2.3.10, 4.3.2.6.7, 4.3.3.3.9, 4.3.3.5.8, 4.3.3.6.6, 4.3.4.4.7, 4.3.4.5.6, 4.3.4.5.7, 4.3.4.5.8, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 1.13, SR 2.10, SR 2.11, SR 2.12, SR 2.6, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.1, SR 6.2, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.7, A.15.2.1, A.15.2.2, A.16.1.4, A.16.1.5, A.16.1.7, A.6.2.1, A.6.2.2 | nist | AU-2(d), AU-12(c), CM-6(a) | nist-csf | DE.AE-3, DE.AE-5, DE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.AC-3, PR.PT-1, PR.PT-4, RS.AN-1, RS.AN-4 | pcidss | Req-10.5.5 | os-srg | SRG-OS-000037-GPOS-00015, SRG-OS-000042-GPOS-00020, SRG-OS-000062-GPOS-00031, SRG-OS-000392-GPOS-00172, SRG-OS-000462-GPOS-00206, SRG-OS-000471-GPOS-00215, SRG-OS-000064-GPOS-00033, SRG-OS-000466-GPOS-00210, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219 | app-srg-ctr | SRG-APP-000091-CTR-000160, SRG-APP-000492-CTR-001220, SRG-APP-000493-CTR-001225, SRG-APP-000494-CTR-001230, SRG-APP-000500-CTR-001260, SRG-APP-000507-CTR-001295, SRG-APP-000495-CTR-001235, SRG-APP-000499-CTR-001255 | stigid | OL08-00-030480 | anssi | R73 | pcidss4 | 10.3.4, 10.3 | stigref | SV-248790r958412_rule |
| Remediation Ansible snippet ⇲Complexity: | low |
---|
Disruption: | low |
---|
Reboot: | true |
---|
Strategy: | restrict |
---|
- name: Gather the package facts
package_facts:
manager: auto
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030480
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchown
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Set architecture for audit fchown tasks
set_fact:
audit_arch: b64
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ansible_architecture == "aarch64" or ansible_architecture == "ppc64" or ansible_architecture
== "ppc64le" or ansible_architecture == "s390x" or ansible_architecture == "x86_64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030480
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchown
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for fchown for 32bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- fchown
syscall_grouping:
- chown
- fchown
- fchownat
- lchown
- name: Check existence of fchown in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- fchown
syscall_grouping:
- chown
- fchown
- fchownat
- lchown
- name: Check existence of fchown in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b32(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b32)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b32 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030480
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchown
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
- name: Perform remediation of Audit rules for fchown for 64bit platform
block:
- name: Declare list of syscalls
set_fact:
syscalls:
- fchown
syscall_grouping:
- chown
- fchown
- fchownat
- lchown
- name: Check existence of fchown in /etc/audit/rules.d/
find:
paths: /etc/audit/rules.d
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: '*.rules'
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Reset syscalls found per file
set_fact:
syscalls_per_file: {}
found_paths_dict: {}
- name: Declare syscalls found per file
set_fact: syscalls_per_file="{{ syscalls_per_file | combine( {item.files[0].path
:[item.item] + syscalls_per_file.get(item.files[0].path, []) } ) }}"
loop: '{{ find_command.results | selectattr(''matched'') | list }}'
- name: Declare files where syscalls were found
set_fact: found_paths="{{ find_command.results | map(attribute='files') | flatten
| map(attribute='path') | list }}"
- name: Count occurrences of syscalls in paths
set_fact: found_paths_dict="{{ found_paths_dict | combine({ item:1+found_paths_dict.get(item,
0) }) }}"
loop: '{{ find_command.results | map(attribute=''files'') | flatten | map(attribute=''path'')
| list }}'
- name: Get path with most syscalls
set_fact: audit_file="{{ (found_paths_dict | dict2items() | sort(attribute='value')
| last).key }}"
when: found_paths | length >= 1
- name: No file with syscall found, set path to /etc/audit/rules.d/perm_mod.rules
set_fact: audit_file="/etc/audit/rules.d/perm_mod.rules"
when: found_paths | length == 0
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_per_file[audit_file]
| join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k
|-F key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
- name: Declare list of syscalls
set_fact:
syscalls:
- fchown
syscall_grouping:
- chown
- fchown
- fchownat
- lchown
- name: Check existence of fchown in /etc/audit/audit.rules
find:
paths: /etc/audit
contains: -a always,exit -F arch=b64(( -S |,)\w+)*(( -S |,){{ item }})+(( -S
|,)\w+)* -F auid>=1000 -F auid!=unset (-k\s+|-F\s+key=)\S+\s*$
patterns: audit.rules
register: find_command
loop: '{{ (syscall_grouping + syscalls) | unique }}'
- name: Set path to /etc/audit/audit.rules
set_fact: audit_file="/etc/audit/audit.rules"
- name: Declare found syscalls
set_fact: syscalls_found="{{ find_command.results | selectattr('matched') | map(attribute='item')
| list }}"
- name: Declare missing syscalls
set_fact: missing_syscalls="{{ syscalls | difference(syscalls_found) }}"
- name: Replace the audit rule in {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
regexp: (-a always,exit -F arch=b64)(?=.*(?:(?:-S |,)(?:{{ syscalls_found |
join("|") }}))\b)((?:( -S |,)\w+)+)( -F auid>=1000 -F auid!=unset (?:-k |-F
key=)\w+)
line: \1\2\3{{ missing_syscalls | join("\3") }}\4
backrefs: true
state: present
when: syscalls_found | length > 0 and missing_syscalls | length > 0
- name: Add the audit rule to {{ audit_file }}
lineinfile:
path: '{{ audit_file }}'
line: -a always,exit -F arch=b64 -S {{ syscalls | join(',') }} -F auid>=1000
-F auid!=unset -F key=perm_mod
create: true
mode: o-rwx
state: present
when: syscalls_found | length == 0
when:
- '"audit" in ansible_facts.packages'
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- audit_arch == "b64"
tags:
- CJIS-5.4.1.1
- DISA-STIG-OL08-00-030480
- NIST-800-171-3.1.7
- NIST-800-53-AU-12(c)
- NIST-800-53-AU-2(d)
- NIST-800-53-CM-6(a)
- PCI-DSS-Req-10.5.5
- PCI-DSSv4-10.3
- PCI-DSSv4-10.3.4
- audit_rules_dac_modification_fchown
- low_complexity
- low_disruption
- medium_severity
- reboot_required
- restrict_strategy
Remediation Shell script ⇲# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && rpm --quiet -q audit; then
# First perform the remediation of the syscall rule
# Retrieve hardware architecture of the underlying system
[ "$(getconf LONG_BIT)" = "32" ] && RULE_ARCHS=("b32") || RULE_ARCHS=("b32" "b64")
for ARCH in "${RULE_ARCHS[@]}"
do
ACTION_ARCH_FILTERS="-a always,exit -F arch=$ARCH"
OTHER_FILTERS=""
AUID_FILTERS="-F auid>=1000 -F auid!=unset"
SYSCALL="fchown"
KEY="perm_mod"
SYSCALL_GROUPING="chown fchown fchownat lchown"
# Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'augenrules', then check if the audit rule is defined
# If rule is defined, add '/etc/audit/rules.d/*.rules' to the list for inspection
# If rule isn't defined yet, add '/etc/audit/rules.d/$key.rules' to the list for inspection
default_file="/etc/audit/rules.d/$KEY.rules"
# As other_filters may include paths, lets use a different delimiter for it
# The "F" script expression tells sed to print the filenames where the expressions matched
readarray -t files_to_inspect < <(sed -s -n -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" -e "F" /etc/audit/rules.d/*.rules)
# Case when particular rule isn't defined in /etc/audit/rules.d/*.rules yet
if [ ${#files_to_inspect[@]} -eq "0" ]
then
file_to_inspect="/etc/audit/rules.d/$KEY.rules"
files_to_inspect=("$file_to_inspect")
if [ ! -e "$file_to_inspect" ]
then
touch "$file_to_inspect"
chmod 0640 "$file_to_inspect"
fi
fi
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
unset syscall_a
unset syscall_grouping
unset syscall_string
unset syscall
unset file_to_edit
unset rule_to_edit
unset rule_syscalls_to_edit
unset other_string
unset auid_string
unset full_rule
# Load macro arguments into arrays
read -a syscall_a <<< $SYSCALL
read -a syscall_grouping <<< $SYSCALL_GROUPING
# Create a list of audit *.rules files that should be inspected for presence and correctness
# of a particular audit rule. The scheme is as follows:
#
# -----------------------------------------------------------------------------------------
# Tool used to load audit rules | Rule already defined | Audit rules file to inspect |
# -----------------------------------------------------------------------------------------
# auditctl | Doesn't matter | /etc/audit/audit.rules |
# -----------------------------------------------------------------------------------------
# augenrules | Yes | /etc/audit/rules.d/*.rules |
# augenrules | No | /etc/audit/rules.d/$key.rules |
# -----------------------------------------------------------------------------------------
#
files_to_inspect=()
# If audit tool is 'auditctl', then add '/etc/audit/audit.rules'
# file to the list of files to be inspected
default_file="/etc/audit/audit.rules"
files_to_inspect+=('/etc/audit/audit.rules' )
# After converting to jinja, we cannot return; therefore we skip the rest of the macro if needed instead
skip=1
for audit_file in "${files_to_inspect[@]}"
do
# Filter existing $audit_file rules' definitions to select those that satisfy the rule pattern,
# i.e, collect rules that match:
# * the action, list and arch, (2-nd argument)
# * the other filters, (3-rd argument)
# * the auid filters, (4-rd argument)
readarray -t similar_rules < <(sed -e "/^$ACTION_ARCH_FILTERS/!d" -e "\#$OTHER_FILTERS#!d" -e "/$AUID_FILTERS/!d" "$audit_file")
candidate_rules=()
# Filter out rules that have more fields then required. This will remove rules more specific than the required scope
for s_rule in "${similar_rules[@]}"
do
# Strip all the options and fields we know of,
# than check if there was any field left over
extra_fields=$(sed -E -e "s/^$ACTION_ARCH_FILTERS//" -e "s#$OTHER_FILTERS##" -e "s/$AUID_FILTERS//" -e "s/((:?-S [[:alnum:],]+)+)//g" -e "s/-F key=\w+|-k \w+//"<<< "$s_rule")
grep -q -- "-F" <<< "$extra_fields" || candidate_rules+=("$s_rule")
done
if [[ ${#syscall_a[@]} -ge 1 ]]
then
# Check if the syscall we want is present in any of the similar existing rules
for rule in "${candidate_rules[@]}"
do
rule_syscalls=$(echo "$rule" | grep -o -P '(-S [\w,]+)+' | xargs)
all_syscalls_found=0
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "$rule_syscalls" || {
# A syscall was not found in the candidate rule
all_syscalls_found=1
}
done
if [[ $all_syscalls_found -eq 0 ]]
then
# We found a rule with all the syscall(s) we want; skip rest of macro
skip=0
break
fi
# Check if this rule can be grouped with our target syscall and keep track of it
for syscall_g in "${syscall_grouping[@]}"
do
if grep -q -- "\b${syscall_g}\b" <<< "$rule_syscalls"
then
file_to_edit=${audit_file}
rule_to_edit=${rule}
rule_syscalls_to_edit=${rule_syscalls}
fi
done
done
else
# If there is any candidate rule, it is compliant; skip rest of macro
if [ "${#candidate_rules[@]}" -gt 0 ]
then
skip=0
fi
fi
if [ "$skip" -eq 0 ]; then
break
fi
done
if [ "$skip" -ne 0 ]; then
# We checked all rules that matched the expected resemblance pattern (action, arch & auid)
# At this point we know if we need to either append the $full_rule or group
# the syscall together with an exsiting rule
# Append the full_rule if it cannot be grouped to any other rule
if [ -z ${rule_to_edit+x} ]
then
# Build full_rule while avoid adding double spaces when other_filters is empty
if [ "${#syscall_a[@]}" -gt 0 ]
then
syscall_string=""
for syscall in "${syscall_a[@]}"
do
syscall_string+=" -S $syscall"
done
fi
other_string=$([[ $OTHER_FILTERS ]] && echo " $OTHER_FILTERS") || /bin/true
auid_string=$([[ $AUID_FILTERS ]] && echo " $AUID_FILTERS") || /bin/true
full_rule="$ACTION_ARCH_FILTERS${syscall_string}${other_string}${auid_string} -F key=$KEY" || /bin/true
echo "$full_rule" >> "$default_file"
chmod o-rwx ${default_file}
else
# Check if the syscalls are declared as a comma separated list or
# as multiple -S parameters
if grep -q -- "," <<< "${rule_syscalls_to_edit}"
then
delimiter=","
else
delimiter=" -S "
fi
new_grouped_syscalls="${rule_syscalls_to_edit}"
for syscall in "${syscall_a[@]}"
do
grep -q -- "\b${syscall}\b" <<< "${rule_syscalls_to_edit}" || {
# A syscall was not found in the candidate rule
new_grouped_syscalls+="${delimiter}${syscall}"
}
done
# Group the syscall in the rule
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi
|
|
Rule
Record Events that Modify the System's Discretionary Access Controls - fchownat
[ref] | At a minimum, the audit system should collect file permission
changes for all users and root. If the auditd daemon is configured
to use the augenrules program to read audit rules during daemon
startup (the default), add the following line to a file with suffix
.rules in the directory /etc/audit/rules.d :
-a always,exit -F arch=b32 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod
If the auditd daemon is configured to use the auditctl
utility to read audit rules during daemon startup, add the following line to
/etc/audit/audit.rules file:
-a always,exit -F arch=b32 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod
If the system is 64 bit then also add the following line:
-a always,exit -F arch=b64 -S fchownat -F auid>=1000 -F auid!=unset -F key=perm_mod
Warning:
Note that these rules can be configured in a
number of ways while still achieving the desired effect. Here the system calls
have been placed independent of other system calls. Grouping these system
calls with others as identifying earlier in this guide is more efficient. | Rationale: | The changing of file permissions could indicate that a user is attempting to
gain access to information that would otherwise be disallowed. Auditing DAC modifications
can facilitate the identification of patterns of abuse among both authorized and
unauthorized users. | Severity: | medium | Rule ID: | xccdf_org.ssgproject.content_rule_audit_rules_dac_modification_fchownat | References: | cis-csc | 1, 11, 12, 13, 14, 15, 16, 19, 2, 3, 4, 5, 6, 7, 8, 9 | cjis | 5.4.1.1 | cobit5 | APO10.01, APO10.03, APO10.04, APO10.05, APO11.04, APO12.06, APO13.01, BAI03.05, BAI08.02, DSS01.03, DSS01.04, DSS02.02, DSS02.04, DSS02.07, DSS03.01, DSS03.05, DSS05.02, DSS05.03, DSS05.04, DSS05.05, DSS05.07, MEA01.01, MEA01.02, MEA01.03, MEA01.04, MEA01.05, MEA02.01 | cui | 3.1.7 | disa | CCI-000172, CCI-000130, CCI-000135, CCI-000169, CCI-002884 | hipaa | 164.308(a)(1)(ii)(D), 164.308(a)(3)(ii)(A), 164.308(a)(5)(ii)(C), 164.312(a)(2)(i), 164.312(b), 164.312(d), 164.312(e) | isa-62443-2009 | 4.2.3.10, 4.3.2.6.7, 4.3.3.3.9, 4.3.3.5.8, 4.3.3.6.6, 4.3.4.4.7, 4.3.4.5.6, 4.3.4.5.7, 4.3.4.5.8, 4.4.2.1, 4.4.2.2, 4.4.2.4 | isa-62443-2013 | SR 1.13, SR 2.10, SR 2.11, SR 2.12, SR 2.6, SR 2.8, SR 2.9, SR 3.1, SR 3.5, SR 3.8, SR 4.1, SR 4.3, SR 5.1, SR 5.2, SR 5.3, SR 6.1, SR 6.2, SR 7.1, SR 7.6 | iso27001-2013 | A.11.2.6, A.12.4.1, A.12.4.2, A.12.4.3, A.12.4.4, A.12.7.1, A.13.1.1, A.13.2.1, A.14.1.3, A.14.2.7, A.15.2.1, A.15.2.2, A.16.1.4, A.16.1.5, A.16.1.7, A.6.2.1, A.6.2.2 | nist | AU-2(d), AU-12(c), CM-6(a) | nist-csf | DE.AE-3, DE.AE-5, DE.CM-1, DE.CM-3, DE.CM-7, ID.SC-4, PR.AC-3, PR.PT-1, PR.PT-4, RS.AN-1, RS.AN-4 | pcidss | Req-10.5.5 | os-srg | SRG-OS-000037-GPOS-00015, SRG-OS-000042-GPOS-00020, SRG-OS-000062-GPOS-00031, SRG-OS-000392-GPOS-00172, SRG-OS-000462-GPOS-00206, SRG-OS-000471-GPOS-00215, SRG-OS-000064-GPOS-00033, SRG-OS-000466-GPOS-00210, SRG-OS-000458-GPOS-00203, SRG-OS-000474-GPOS-00219 | app-srg-ctr | SRG-APP-000091-CTR-000160, SRG-APP-000492-CTR-001220, SRG-APP-000493-CTR-001225, SRG-APP-000494-CTR-001230, SRG-APP-000500-CTR-001260, SRG-APP-000507-CTR-001295, SRG-APP-000495-CTR-001235, SRG-APP-000499-CTR-001255 | stigid | OL08-00-030480 | anssi | R73 | pcidss4 | 10.3.4, 10.3 | stigref | SV-248790r958412_rule |
| |
|