Skip to content

Commit

Permalink
Merge pull request ComplianceAsCode#11332 from marcusburghardt/rpm_ve…
Browse files Browse the repository at this point in the history
…rify_hashes_review

Review rpm_verify_hashes rule
  • Loading branch information
jan-cerny authored Dec 7, 2023
2 parents bbe417f + 50f8a8a commit d868537
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,16 @@
# strategy = restrict
# complexity = high
# disruption = medium
- name: "Set fact: Package manager reinstall command (dnf)"
- name: "Set fact: Package manager reinstall command"
set_fact:
package_manager_reinstall_cmd: dnf reinstall -y
when: ansible_distribution == "Fedora"

- name: "Set fact: Package manager reinstall command (yum)"
set_fact:
package_manager_reinstall_cmd: yum reinstall -y
when: (ansible_distribution == "RedHat" or ansible_distribution == "CentOS" or ansible_distribution == "OracleLinux")
package_manager_reinstall_cmd: {{{ pkg_manager }}} reinstall -y
when: ansible_distribution in [ "Fedora", "RedHat", "CentOS", "OracleLinux" ]

- name: "Set fact: Package manager reinstall command (zypper)"
set_fact:
package_manager_reinstall_cmd: zypper in -f -y
when: ansible_distribution == "SLES"


- name: "Read files with incorrect hash"
command: rpm -Va --nodeps --nosize --nomtime --nordev --nocaps --nolinkto --nouser --nogroup --nomode --noghost --noconfig
register: files_with_incorrect_hash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
# Find which files have incorrect hash (not in /etc, because of the system related config files) and then get files names
files_with_incorrect_hash="$(rpm -Va --noconfig | grep -E '^..5' | awk '{print $NF}' )"

# From files names get package names and change newline to space, because rpm writes each package to new line
packages_to_reinstall="$(rpm -qf $files_with_incorrect_hash | tr '\n' ' ')"
if [ -n "$files_with_incorrect_hash" ]; then
# From files names get package names and change newline to space, because rpm writes each package to new line
packages_to_reinstall="$(rpm -qf $files_with_incorrect_hash | tr '\n' ' ')"

{{% if product in ["sle12", "sle15"] %}}
{{{ pkg_manager }}} install -f -y $packages_to_reinstall
{{% else %}}
{{{ pkg_manager }}} reinstall -y $packages_to_reinstall
{{% endif %}}
{{% if product in ["sle12", "sle15"] %}}
{{{ pkg_manager }}} install -f -y $packages_to_reinstall
{{% else %}}
{{{ pkg_manager }}} reinstall -y $packages_to_reinstall
{{% endif %}}
fi
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
<def-group>
<definition class="compliance" id="rpm_verify_hashes" version="3">
<definition class="compliance" id="{{{ rule_id }}}" version="3">
{{{ oval_metadata("Verify the RPM digests of system binaries using the RPM database.") }}}
<criteria>
<criterion test_ref="test_files_fail_md5_hash" comment="verify file md5 hashes" />
<criterion test_ref="test_rpm_verify_hashes" comment="verify file md5 hashes"/>
</criteria>
</definition>
<!-- NOTE: If you examine the regex below you notice that we are interested in /bin, /sbin, /lib, /lib64 -->
<!-- and /usr directories. This narrows the search down to executables, libraries and supporting content. -->
<!-- If you look at the state below you will notice that I -->
<!-- commented out several attributes. The current rpmverify object has methods to distinguish between -->
<!-- configuration files, documentation files, etc. Using these discriminators in the state reduced -->
<!-- the number of false positives, but it did not eliminate them. I left them commented out to serve -->
<!-- as an example of what they look like. -->
<linux:rpmverifyfile_test check_existence="none_exist" id="test_files_fail_md5_hash" version="1" check="all" comment="verify file md5 hashes">
<linux:object object_ref="object_files_fail_md5_hash"/>
</linux:rpmverifyfile_test>
<linux:rpmverifyfile_object id="object_files_fail_md5_hash" version="1" comment="rpm verify of all files">

<!-- The current rpmverify object has methods to distinguish between configuration files,
documentation files, etc. Using these discriminators in the state reduced the number of
false positives, but it did not eliminate them. So they were kept commented out as
examples. -->
<linux:rpmverifyfile_state id="state_rpm_verify_hashes_fail_md5_hash" version="1"
operator="AND">
<linux:md5_differs>fail</linux:md5_differs>
<linux:configuration_file datatype="boolean">false</linux:configuration_file>
<linux:ghost_file datatype="boolean">false</linux:ghost_file>
<!-- <linux:documentation_file datatype="boolean">false</linux:documentation_file> -->
<!-- <linux:license_file datatype="boolean">false</linux:license_file> -->
<!-- <linux:readme_file datatype="boolean">false</linux:readme_file> -->
</linux:rpmverifyfile_state>

<!-- The search is focused in /bin, /sbin, /lib, /lib64 and /usr directories. It means that
executables, libraries and supporting content are considered. -->
<linux:rpmverifyfile_object id="object_rpm_verify_hashes_fail_md5_hash" version="1"
comment="rpm verify of all files">
<linux:behaviors nomd5="false"/>
<linux:name operation="pattern match">.*</linux:name>
<linux:epoch operation="pattern match">.*</linux:epoch>
<linux:version operation="pattern match">.*</linux:version>
<linux:release operation="pattern match">.*</linux:release>
<linux:arch operation="pattern match">.*</linux:arch>
<linux:filepath operation="pattern match">^/(bin|sbin|lib|lib64|usr)/.+$</linux:filepath>
<filter action="include">state_files_fail_md5_hash</filter>
<filter action="include">state_rpm_verify_hashes_fail_md5_hash</filter>
</linux:rpmverifyfile_object>
<linux:rpmverifyfile_state id="state_files_fail_md5_hash" version="1" operator="AND">
<linux:md5_differs>fail</linux:md5_differs>
<linux:configuration_file datatype="boolean">false</linux:configuration_file>
<!-- <linux:documentation_file datatype="boolean">false</linux:documentation_file> -->
<linux:ghost_file datatype="boolean">false</linux:ghost_file>
<!-- <linux:license_file datatype="boolean">false</linux:license_file> -->
<!-- <linux:readme_file datatype="boolean">false</linux:readme_file> -->
</linux:rpmverifyfile_state>

<linux:rpmverifyfile_test id="test_rpm_verify_hashes" version="2"
check="all" check_existence="none_exist" comment="verify file md5 hashes">
<linux:object object_ref="object_rpm_verify_hashes_fail_md5_hash"/>
</linux:rpmverifyfile_test>
</def-group>
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,23 @@ prodtype: alinux2,alinux3,anolis23,anolis8,fedora,ol7,ol8,ol9,rhel7,rhel8,rhel9,
title: 'Verify File Hashes with RPM'

description: |-
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:
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:
<pre>$ rpm -Va --noconfig | grep '^..5'</pre>
A "c" in the second column indicates that a file is a configuration file, which
may appropriately be expected to change. 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:
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:
<pre>$ rpm -qf <i>FILENAME</i></pre>
The package can be reinstalled from a {{{ pkg_manager }}} repository using the command:
<pre>$ sudo {{{ pkg_manager }}} reinstall <i>PACKAGENAME</i></pre>
Alternatively, the package can be reinstalled from trusted media using the command:
<pre>$ sudo rpm -Uvh <i>PACKAGENAME</i></pre>
Expand Down Expand Up @@ -64,9 +63,9 @@ references:
ocil_clause: 'there is output'

ocil: |-
The following command will list which files on the system
have file hashes different from what is expected by the RPM database.
<pre>$ rpm -Va --noconfig | awk '$1 ~ /..5/ &amp;&amp; $2 != "c"'</pre>
The following command will list which files on the system have file hashes different from what
is expected by the RPM database.
<pre>$ rpm -Va --noconfig | awk '$1 ~ /..5/'</pre>
fixtext: |-
Run the following command to determine which package owns the file:
Expand All @@ -82,3 +81,13 @@ fixtext: |-
$ sudo rpm -Uvh [PATH TO RPM]
srg_requirement: '{{{ full_name }}} must be configured so that the cryptographic hash of system files and commands matches vendor values.'

warnings:
- general: |-
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.
{{% if "rhel" in product %}}
See <code>https://access.redhat.com/articles/6999111</code>.
{{% endif %}}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

echo "# CaC rpm_verify_hashes test" >> /bin/ls

0 comments on commit d868537

Please sign in to comment.