From a7756f855ecbb58e45fb243c9f0696c0cf4af489 Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Wed, 1 Aug 2018 18:08:18 +0200 Subject: [PATCH 1/9] Modified controls to use the built in kernel_module --- controls/1_1_filesystem_configuration.rb | 32 +++++----- controls/3_5_uncommon_network_protocols.rb | 18 +++--- libraries/linux_module.rb | 72 ---------------------- 3 files changed, 25 insertions(+), 97 deletions(-) delete mode 100644 libraries/linux_module.rb diff --git a/controls/1_1_filesystem_configuration.rb b/controls/1_1_filesystem_configuration.rb index f9886ef..d0c1814 100644 --- a/controls/1_1_filesystem_configuration.rb +++ b/controls/1_1_filesystem_configuration.rb @@ -27,9 +27,9 @@ tag cis: 'distribution-independent-linux:1.1.1.1' tag level: 1 - describe linux_module('cramfs') do + describe kernel_module('cramfs') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -41,9 +41,9 @@ tag cis: 'distribution-independent-linux:1.1.1.2' tag level: 1 - describe linux_module('freevxfs') do + describe kernel_module('freevxfs') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -55,9 +55,9 @@ tag cis: 'distribution-independent-linux:1.1.1.3' tag level: 1 - describe linux_module('jffs2') do + describe kernel_module('jffs2') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -69,9 +69,9 @@ tag cis: 'distribution-independent-linux:1.1.1.4' tag level: 1 - describe linux_module('hfs') do + describe kernel_module('hfs') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -83,9 +83,9 @@ tag cis: 'distribution-independent-linux:1.1.1.5' tag level: 1 - describe linux_module('hfsplus') do + describe kernel_module('hfsplus') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -97,9 +97,9 @@ tag cis: 'distribution-independent-linux:1.1.1.6' tag level: 1 - describe linux_module('squashfs') do + describe kernel_module('squashfs') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -111,9 +111,9 @@ tag cis: 'distribution-independent-linux:1.1.1.7' tag level: 1 - describe linux_module('udf') do + describe kernel_module('udf') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -125,9 +125,9 @@ tag cis: 'distribution-independent-linux:1.1.1.8' tag level: 1 - describe linux_module('vfat') do + describe kernel_module('vfat') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end diff --git a/controls/3_5_uncommon_network_protocols.rb b/controls/3_5_uncommon_network_protocols.rb index 98bc834..087b96c 100644 --- a/controls/3_5_uncommon_network_protocols.rb +++ b/controls/3_5_uncommon_network_protocols.rb @@ -17,7 +17,7 @@ title '3.5 Uncommon Network Protocols' -control 'cis-dil-benchmark-3.5.1' do +control ' ' do title 'Ensure DCCP is disabled' desc "The Datagram Congestion Control Protocol (DCCP) is a transport layer protocol that supports streaming media and telephony. DCCP provides a way to gain access to congestion control, without having to do it at the application layer, but does not provide in-sequence delivery.\n\nRationale: If the protocol is not required, it is recommended that the drivers not be installed to reduce the potential attack surface." impact 0.0 @@ -25,9 +25,9 @@ tag cis: 'distribution-independent-linux:3.5.1' tag level: 1 - describe linux_module('dccp') do + describe kernel_module('dccp') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -39,9 +39,9 @@ tag cis: 'distribution-independent-linux:3.5.2' tag level: 1 - describe linux_module('sctp') do + describe kernel_module('sctp') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -53,9 +53,9 @@ tag cis: 'distribution-independent-linux:3.5.3' tag level: 1 - describe linux_module('rds') do + describe kernel_module('rds') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end @@ -67,8 +67,8 @@ tag cis: 'distribution-independent-linux:3.5.4' tag level: 1 - describe linux_module('tipc') do + describe kernel_module('tipc') do it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true$}) } + it { should be_disabled } end end diff --git a/libraries/linux_module.rb b/libraries/linux_module.rb deleted file mode 100644 index aa680c2..0000000 --- a/libraries/linux_module.rb +++ /dev/null @@ -1,72 +0,0 @@ -# -# Copyright 2017, Schuberg Philis B.V. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# author: Kristian Vlaardingerbroek - -class LinuxModule < Inspec.resource(1) - name 'linux_module' - desc 'Custom resource to audit Linux kernel modules (based on official kernel_module resource in inspec 1.27.0)' - example " - describe linux_module('cramfs') do - it { should_not be_loaded } - its(:command) { should match(%r{^install /bin/true%}) } - end - " - - def initialize(modulename = nil) - @module = modulename - end - - def loaded? - lsmod_cmd = if inspec.os.redhat? || inspec.os.name == 'fedora' - '/sbin/lsmod' - else - 'lsmod' - end - - # get list of all modules - cmd = inspec.command(lsmod_cmd) - return false if cmd.exit_status != 0 - - # check if module is loaded - re = Regexp.new('^' + Regexp.quote(@module) + '\s') - found = cmd.stdout.match(re) - !found.nil? - end - - def version - modinfo_cmd = if inspec.os.redhat? || inspec.os.name == 'fedora' - "/sbin/modinfo -F version #{@module}" - else - "modinfo -F version #{@module}" - end - - cmd = inspec.command(modinfo_cmd) - cmd.exit_status.zero? ? cmd.stdout.delete("\n") : nil - end - - def command - # Lets just ensure the last line in the kernel module's configuration is 'install /bin/true' - # this is enough to be sure the module will not be loaded on next reboot or run of modprobe - modinfo_cmd = "/sbin/modprobe -n -v #{@module} | tail -n 1 | awk '{$1=$1;print}'" - - cmd = inspec.command(modinfo_cmd) - cmd.exit_status.zero? ? cmd.stdout.delete("\n") : nil - end - - def to_s - "Kernel Module #{@module}" - end -end From 4ab9f2559fffdf5b69a455fa84921bd85d495c85 Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Thu, 2 Aug 2018 10:57:55 +0200 Subject: [PATCH 2/9] Added back accidentaly deleted control id --- controls/3_5_uncommon_network_protocols.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controls/3_5_uncommon_network_protocols.rb b/controls/3_5_uncommon_network_protocols.rb index 087b96c..a37f0a5 100644 --- a/controls/3_5_uncommon_network_protocols.rb +++ b/controls/3_5_uncommon_network_protocols.rb @@ -17,7 +17,7 @@ title '3.5 Uncommon Network Protocols' -control ' ' do +control 'cis-dil-benchmark-3.5.1' do title 'Ensure DCCP is disabled' desc "The Datagram Congestion Control Protocol (DCCP) is a transport layer protocol that supports streaming media and telephony. DCCP provides a way to gain access to congestion control, without having to do it at the application layer, but does not provide in-sequence delivery.\n\nRationale: If the protocol is not required, it is recommended that the drivers not be installed to reduce the potential attack surface." impact 0.0 From b417d548f7efbf75ea34a45ab058c8c84cbf17a9 Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Tue, 28 Aug 2018 18:26:01 +0200 Subject: [PATCH 3/9] Updating section 1.1.* to CIS version 1.1.0 --- controls/1_1_filesystem_configuration.rb | 106 +++++++++++++++++------ 1 file changed, 79 insertions(+), 27 deletions(-) diff --git a/controls/1_1_filesystem_configuration.rb b/controls/1_1_filesystem_configuration.rb index d0c1814..6d36abe 100644 --- a/controls/1_1_filesystem_configuration.rb +++ b/controls/1_1_filesystem_configuration.rb @@ -250,13 +250,65 @@ end end +control 'cis-dil-benchmark-1.1.11' do + title 'Ensure noexec option set on /var/tmp partition' + desc "The noexec mount option specifies that the filesystem cannot contain executable binaries.\n\nRationale: Since the /var/tmp filesystem is only intended for temporary file storage, set this option to ensure that users cannot run executable binaries from /var/tmp." + impact 1.0 + + tag cis: 'distribution-independent-linux:1.1.11' + tag level: 1 + + describe mount('/var/tmp') do + its(:options) { should include 'noexec' } + end +end + +control 'cis-dil-benchmark-1.1.12' do + title 'Ensure noexec option set on /var/tmp partition' + desc "The noexec mount option specifies that the filesystem cannot contain executable binaries.\n\nRationale: Since the /var/tmp filesystem is only intended for temporary file storage, set this option to ensure that users cannot run executable binaries from /var/tmp." + impact 1.0 + + tag cis: 'distribution-independent-linux:1.1.12' + tag level: 1 + + describe mount('/var/tmp') do + its(:options) { should include 'noexec' } + end +end + +control 'cis-dil-benchmark-1.1.13' do + title 'Ensure noexec option set on /var/tmp partition' + desc "The noexec mount option specifies that the filesystem cannot contain executable binaries.\n\nRationale: Since the /var/tmp filesystem is only intended for temporary file storage, set this option to ensure that users cannot run executable binaries from /var/tmp." + impact 1.0 + + tag cis: 'distribution-independent-linux:1.1.13' + tag level: 1 + + describe mount('/var/tmp') do + its(:options) { should include 'noexec' } + end +end + +control 'cis-dil-benchmark-1.1.14' do + title 'Ensure noexec option set on /var/tmp partition' + desc "The noexec mount option specifies that the filesystem cannot contain executable binaries.\n\nRationale: Since the /var/tmp filesystem is only intended for temporary file storage, set this option to ensure that users cannot run executable binaries from /var/tmp." + impact 1.0 + + tag cis: 'distribution-independent-linux:1.1.14' + tag level: 1 + + describe mount('/var/tmp') do + its(:options) { should include 'noexec' } + end +end + if cis_level == '2' - control 'cis-dil-benchmark-1.1.11' do + control 'cis-dil-benchmark-1.1.15' do title 'Ensure separate partition exists for /var/log' desc "The /var/log directory is used by system services to store log data .\n\nRationale: There are two important reasons to ensure that system logs are stored on a separate partition: protection against resource exhaustion (since logs can grow quite large) and protection of audit data." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.11' + tag cis: 'distribution-independent-linux:1.1.15' tag level: 2 describe mount('/var/log') do @@ -264,12 +316,12 @@ end end - control 'cis-dil-benchmark-1.1.12' do + control 'cis-dil-benchmark-1.1.16' do title 'Ensure separate partition exists for /var/log/audit' desc "The auditing daemon, auditd, stores log data in the /var/log/audit directory.\n\nRationale: There are two important reasons to ensure that data gathered by auditd is stored on a separate partition: protection against resource exhaustion (since the audit.log file can grow quite large) and protection of audit data. The audit daemon calculates how much free space is left and performs actions based on the results. If other processes (such as syslog) consume space in the same partition as auditd, it may not perform as desired." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.12' + tag cis: 'distribution-independent-linux:1.1.16' tag level: 2 describe mount('/var/log/audit') do @@ -277,12 +329,12 @@ end end - control 'cis-dil-benchmark-1.1.13' do + control 'cis-dil-benchmark-1.1.17' do title 'Ensure separate partition exists for /home' desc "The /home directory is used to support disk storage needs of local users.\n\nRationale: If the system is intended to support local users, create a separate partition for the /home directory to protect against resource exhaustion and restrict the type of files that can be stored under /home." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.13' + tag cis: 'distribution-independent-linux:1.1.17' tag level: 2 describe mount('/home') do @@ -291,12 +343,12 @@ end end -control 'cis-dil-benchmark-1.1.14' do +control 'cis-dil-benchmark-1.1.18' do title 'Ensure nodev option set on /home partition' desc "The nodev mount option specifies that the filesystem cannot contain special devices.\n\nRationale: Since the user partitions are not intended to support devices, set this option to ensure that users cannot attempt to create block or character special devices." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.14' + tag cis: 'distribution-independent-linux:1.1.18' tag level: 1 describe mount('/home') do @@ -304,12 +356,12 @@ end end -control 'cis-dil-benchmark-1.1.15' do +control 'cis-dil-benchmark-1.1.19' do title 'Ensure nodev option set on /dev/shm partition' desc "The nodev mount option specifies that the filesystem cannot contain special devices.\n\nRationale: Since the /run/shm filesystem is not intended to support devices, set this option to ensure that users cannot attempt to create special devices in /dev/shm partitions." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.15' + tag cis: 'distribution-independent-linux:1.1.19' tag level: 1 describe mount('/dev/shm') do @@ -317,12 +369,12 @@ end end -control 'cis-dil-benchmark-1.1.16' do +control 'cis-dil-benchmark-1.1.20' do title 'Ensure nosuid option set on /dev/shm partitionrun' desc "The nosuid mount option specifies that the filesystem cannot contain setuid files.\n\nRationale: Setting this option on a file system prevents users from introducing privileged programs onto the system and allowing non-root users to execute them." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.16' + tag cis: 'distribution-independent-linux:1.1.20' tag level: 1 describe mount('/dev/shm') do @@ -330,12 +382,12 @@ end end -control 'cis-dil-benchmark-1.1.17' do +control 'cis-dil-benchmark-1.1.21' do title 'Ensure noexec option set on /dev/shm partition' desc "The noexec mount option specifies that the filesystem cannot contain executable binaries.\n\nRationale: Setting this option on a file system prevents users from executing programs from shared memory. This deters users from introducing potentially malicious software on the system." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.17' + tag cis: 'distribution-independent-linux:1.1.21' tag level: 1 describe mount('/dev/shm') do @@ -343,51 +395,51 @@ end end -control 'cis-dil-benchmark-1.1.18' do +control 'cis-dil-benchmark-1.1.22' do title 'Ensure nodev option set on removable media partitions' desc "The nodev mount option specifies that the filesystem cannot contain special devices.\n\nRationale: Removable media containing character and block special devices could be used to circumvent security controls by allowing non-root users to access sensitive device files such as /dev/kmem or the raw disk partitions." impact 0.0 - tag cis: 'distribution-independent-linux:1.1.18' + tag cis: 'distribution-independent-linux:1.1.22' tag level: 1 - describe 'cis-dil-benchmark-1.1.18' do + describe 'cis-dil-benchmark-1.1.22' do skip 'Not implemented' end end -control 'cis-dil-benchmark-1.1.19' do +control 'cis-dil-benchmark-1.1.23' do title 'Ensure nosuid option set on removable media partitions' desc "The nosuid mount option specifies that the filesystem cannot contain setuid files.\n\nRationale: Setting this option on a file system prevents users from introducing privileged programs onto the system and allowing non-root users to execute them." impact 0.0 - tag cis: 'distribution-independent-linux:1.1.19' + tag cis: 'distribution-independent-linux:1.1.23' tag level: 1 - describe 'cis-dil-benchmark-1.1.19' do + describe 'cis-dil-benchmark-1.1.23' do skip 'Not implemented' end end -control 'cis-dil-benchmark-1.1.20' do +control 'cis-dil-benchmark-1.1.24' do title 'Ensure noexec option set on removable media partitions' desc "The noexec mount option specifies that the filesystem cannot contain executable binaries.\n\nRationale: Setting this option on a file system prevents users from executing programs from the removable media. This deters users from being able to introduce potentially malicious software on the system." impact 0.0 - tag cis: 'distribution-independent-linux:1.1.20' + tag cis: 'distribution-independent-linux:1.1.24' tag level: 1 - describe 'cis-dil-benchmark-1.1.20' do + describe 'cis-dil-benchmark-1.1.24' do skip 'Not implemented' end end -control 'cis-dil-benchmark-1.1.21' do +control 'cis-dil-benchmark-1.1.25' do title 'Ensure sticky bit is set on all world-writable directories' desc "Setting the sticky bit on world writable directories prevents users from deleting or renaming files in that directory that are not owned by them.\n\nRationale: This feature prevents the ability to delete or rename files in world writable directories (such as /tmp) that are owned by another user." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.21' + tag cis: 'distribution-independent-linux:1.1.25' tag level: 1 describe command("df --local -P | awk '{ if (NR!=1) print $6 }' | xargs -I '{}' find '{}' -xdev -type d \( -perm -0002 -a ! -perm -1000 \)") do @@ -395,12 +447,12 @@ end end -control 'cis-dil-benchmark-1.1.22' do +control 'cis-dil-benchmark-1.1.26' do title 'Disable Automounting' desc "autofs allows automatic mounting of devices, typically including CD/DVDs and USB drives.\n\nRationale: With automounting enabled anyone with physical access could attach a USB drive or disc and have its contents available in system even if they lacked permissions to mount it themselves." impact 1.0 - tag cis: 'distribution-independent-linux:1.1.22' + tag cis: 'distribution-independent-linux:1.1.26' tag level: 1 describe.one do From 6116fc9c35167b33fbd45227f3f5079737511759 Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Wed, 29 Aug 2018 10:35:01 +0200 Subject: [PATCH 4/9] Modifed 1.1.10-1.1.14 to skip because they are only duplocates pf 1.1.9 --- controls/1_1_filesystem_configuration.rb | 25 +++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/controls/1_1_filesystem_configuration.rb b/controls/1_1_filesystem_configuration.rb index 6d36abe..28b16dd 100644 --- a/controls/1_1_filesystem_configuration.rb +++ b/controls/1_1_filesystem_configuration.rb @@ -237,6 +237,8 @@ end end +# There is a mistake in the official CIS DIL documentaion 1.1.10-1.1.14 are +# duplicates of 1.1.9. So I used "skipped" to keep the order of the numbering. control 'cis-dil-benchmark-1.1.10' do title 'Ensure noexec option set on /var/tmp partition' desc "The noexec mount option specifies that the filesystem cannot contain executable binaries.\n\nRationale: Since the /var/tmp filesystem is only intended for temporary file storage, set this option to ensure that users cannot run executable binaries from /var/tmp." @@ -245,8 +247,8 @@ tag cis: 'distribution-independent-linux:1.1.10' tag level: 1 - describe mount('/var/tmp') do - its(:options) { should include 'noexec' } + describe 'cis-dil-benchmark-1.1.10' do + skip 'Duplicate of cis-dil-benchmark-1.1.9' end end @@ -258,8 +260,9 @@ tag cis: 'distribution-independent-linux:1.1.11' tag level: 1 - describe mount('/var/tmp') do - its(:options) { should include 'noexec' } + + describe 'cis-dil-benchmark-1.1.11' do + skip 'Duplicate of cis-dil-benchmark-1.1.9' end end @@ -271,8 +274,8 @@ tag cis: 'distribution-independent-linux:1.1.12' tag level: 1 - describe mount('/var/tmp') do - its(:options) { should include 'noexec' } + describe 'cis-dil-benchmark-1.1.12' do + skip 'Duplicate of cis-dil-benchmark-1.1.9' end end @@ -284,8 +287,8 @@ tag cis: 'distribution-independent-linux:1.1.13' tag level: 1 - describe mount('/var/tmp') do - its(:options) { should include 'noexec' } + describe 'cis-dil-benchmark-1.1.13' do + skip 'Duplicate of cis-dil-benchmark-1.1.9' end end @@ -296,9 +299,9 @@ tag cis: 'distribution-independent-linux:1.1.14' tag level: 1 - - describe mount('/var/tmp') do - its(:options) { should include 'noexec' } + + describe 'cis-dil-benchmark-1.1.14' do + skip 'Duplicate of cis-dil-benchmark-1.1.9' end end From 6b895decbe69001077ae4a97cf59fa3efb4c0626 Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Wed, 5 Sep 2018 14:15:17 +0200 Subject: [PATCH 5/9] Updateing 4.1.* CIS rules to v1.1.0 --- .../4_1_configure_system_accounting_auditd.rb | 22 +++++++++---------- inspec.lock | 3 +++ 2 files changed, 14 insertions(+), 11 deletions(-) create mode 100644 inspec.lock diff --git a/controls/4_1_configure_system_accounting_auditd.rb b/controls/4_1_configure_system_accounting_auditd.rb index b642fe5..df18d63 100644 --- a/controls/4_1_configure_system_accounting_auditd.rb +++ b/controls/4_1_configure_system_accounting_auditd.rb @@ -191,7 +191,7 @@ control 'cis-dil-benchmark-4.1.8' do title 'Ensure login and logout events are collected' - desc "Monitor login and logout events. The parameters below track changes to files associated with login/logout events. The file /var/log/faillog tracks failed events from login. The file /var/log/lastlog maintain records of the last time a user successfully logged in. The file /var/log/tallylog maintains records of failures via the pam_tally2 module\n\nRationale: Monitoring login/logout events could provide a system administrator with information associated with brute force attacks against user logins." + desc "Monitor login and logout events. The parameters below track changes to files associated with login/logout events. The file /var/log/lastlog maintain records of the last time a user successfully logged in. The /var/run/failock directory maintains records of login failures via the pam_faillock module\n\nRationale: Monitoring login/logout events could provide a system administrator with information associated with brute force attacks against user logins." impact 1.0 tag cis: 'distribution-independent-linux:4.1.8' @@ -200,7 +200,7 @@ describe file('/etc/audit/audit.rules') do its(:content) { should match(%r{^-w /var/log/faillog -p wa -k logins$}) } its(:content) { should match(%r{^-w /var/log/lastlog -p wa -k logins$}) } - its(:content) { should match(%r{^-w /var/log/tallylog -p wa -k logins$}) } + its(:content) { should match(%r{^-w /var/log/tallylog -p wa -k logins$}) } end end @@ -251,14 +251,14 @@ tag level: 2 describe file('/etc/audit/audit.rules') do - its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=#{uid_min} -F auid!=4294967295 -k access$/) } - its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b32 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=#{uid_min} -F auid!=4294967295 -k access$/) } + its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b32 (-S creat -S open -S openat -S truncate -S ftruncate|-S creat,open,openat,open_by_handle_at,truncate,ftruncate) -F exit=-EACCES -F auid>=#{uid_min} -F auid!=4294967295 (-F key=access$|-k access$)/) } + its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b32 (-S creat -S open -S openat -S truncate -S ftruncate|-S creat,open,openat,open_by_handle_at,truncate,ftruncate) -F exit=-EPERM -F auid>=#{uid_min} -F auid!=4294967295 (-F key=access$|-k access$)/) } end if command('uname -m').stdout.strip == 'x86_64' describe file('/etc/audit/audit.rules') do - its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EACCES -F auid>=#{uid_min} -F auid!=4294967295 -k access$/) } - its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b64 -S creat -S open -S openat -S truncate -S ftruncate -F exit=-EPERM -F auid>=#{uid_min} -F auid!=4294967295 -k access$/) } + its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b64 (-S creat -S open -S openat -S truncate -S ftruncate|-S creat,open,openat,open_by_handle_at,truncate,ftruncate) -F exit=-EACCES -F auid>=#{uid_min} -F auid!=4294967295 (-F key=access$|-k access$)/) } + its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b64 (-S creat -S open -S openat -S truncate -S ftruncate|-S creat,open,openat,open_by_handle_at,truncate,ftruncate) -F exit=-EPERM -F auid>=#{uid_min} -F auid!=4294967295 (-F key=access$|-k access$)/) } end end end @@ -306,12 +306,12 @@ tag level: 2 describe file('/etc/audit/audit.rules') do - its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=#{uid_min} -F auid!=4294967295 -k delete$/) } + its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b32 -S unlink -S unlinkat -S rename -S renameat -F auid>=#{uid_min} -F auid!=4294967295 (-k delete|-F key=delete)$/) } end if command('uname -m').stdout.strip == 'x86_64' describe file('/etc/audit/audit.rules') do - its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=#{uid_min} -F auid!=4294967295 -k delete$/) } + its(:content) { should match(/^-a (always,exit|exit,always) -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F auid>=#{uid_min} -F auid!=4294967295 (-k delete|-F key=delete)$/) } end end end @@ -352,9 +352,9 @@ tag level: 2 describe file('/etc/audit/audit.rules') do - its(:content) { should match(%r{^-w /sbin/insmod -p x -k modules$}) } - its(:content) { should match(%r{^-w /sbin/rmmod -p x -k modules$}) } - its(:content) { should match(%r{^-w /sbin/modprobe -p x -k modules$}) } + its(:content) { should match(%r{^-w (/sbin/insmod|/usr/sbin/insmod) -p x -k modules$}) } + its(:content) { should match(%r{^-w (/sbin/rmmod|/usr/sbin/rmmod) -p x -k modules$}) } + its(:content) { should match(%r{^-w (/sbin/modprobe|/usr/sbin/modprobe) -p x -k modules$}) } end if command('uname -m').stdout.strip == 'x86_64' diff --git a/inspec.lock b/inspec.lock new file mode 100644 index 0000000..e687b9b --- /dev/null +++ b/inspec.lock @@ -0,0 +1,3 @@ +--- +lockfile_version: 1 +depends: [] From 10298df99e860a2e2ad45d926bc8e99d123ae30c Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Thu, 6 Sep 2018 14:36:00 +0200 Subject: [PATCH 6/9] Updateing 4.2.* check to match CIS version 1.1.0 --- controls/4_2_configure_logging.rb | 45 ++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/controls/4_2_configure_logging.rb b/controls/4_2_configure_logging.rb index 666a1b4..ba7785b 100644 --- a/controls/4_2_configure_logging.rb +++ b/controls/4_2_configure_logging.rb @@ -37,7 +37,7 @@ control 'cis-dil-benchmark-4.2.1.2' do title 'Ensure logging is configured' - desc "The /etc/rsyslog.conf file specifies rules for logging and which files are to be used to log certain classes of messages.\n\nRationale: A great deal of important security-related information is sent via rsyslog (e.g., successful and failed su attempts, failed login attempts, root login attempts, etc.)." + desc "The /etc/rsyslog.conf and /etc/rsyslog.d/*.conf files specifies rules for logging and which files are to be used to log certain classes of messages.\n\nRationale: A great deal of important security-related information is sent via rsyslog (e.g., successful and failed su attempts, failed login attempts, root login attempts, etc.)." impact 0.0 tag cis: 'distribution-independent-linux:4.2.1.2' @@ -50,6 +50,49 @@ describe file('/etc/rsyslog.conf') do it { should exist } end + + describe.one do + command('find /etc/rsyslog.d -name "*.conf"').stdout.split.each do |conf_file| + describe file(conf_file) do + its(:content) { should match(%r{^\*.emerg(\s)+:omusrmsg:\*}) } + its(:content) { should match(%r{^mail.\*(\s)+-/var/log/mail}) } + its(:content) { should match(%r{^mail.info(\s)+-/var/log/mail.info}) } + its(:content) { should match(%r{^mail.warning(\s)+-/var/log/mail.warn}) } + its(:content) { should match(%r{^mail.err(\s)+/var/log/mail.err}) } + its(:content) { should match(%r{^news.crit(\s)+-/var/log/news/news.crit}) } + its(:content) { should match(%r{^news.crit(\s)+-/var/log/news/news.crit}) } + its(:content) { should match(%r{^news.notice(\s)+-/var/log/news/news.notice}) } + its(:content) { should match(%r{^\*.=warning;\*.=err(\s)+-/var/log/warn}) } + its(:content) { should match(%r{^\*.crit(\s)+/var/log/warn}) } + its(:content) { should match(%r{^\*.\*;mail.none;news.none(\s)+-/var/log/messages}) } + its(:content) { should match(%r{^local0,local1.\*(\s)+-/var/log/localmessages}) } + its(:content) { should match(%r{^local2,local3.\*(\s)+-/var/log/localmessages}) } + its(:content) { should match(%r{^local2,local3.\*(\s)+-/var/log/localmessages}) } + its(:content) { should match(%r{^local4,local5.\*(\s)+-/var/log/localmessages}) } + its(:content) { should match(%r{^local6,local7.\*(\s)+-/var/log/localmessages}) } + end + end + + describe file('/etc/rsyslog.conf') do + its(:content) { should match(%r{^\*.emerg(\s)+:omusrmsg:\*}) } + its(:content) { should match(%r{^mail.\*(\s)+-/var/log/mail}) } + its(:content) { should match(%r{^mail.info(\s)+-/var/log/mail.info}) } + its(:content) { should match(%r{^mail.warning(\s)+-/var/log/mail.warn}) } + its(:content) { should match(%r{^mail.err(\s)+/var/log/mail.err}) } + its(:content) { should match(%r{^news.crit(\s)+-/var/log/news/news.crit}) } + its(:content) { should match(%r{^news.crit(\s)+-/var/log/news/news.crit}) } + its(:content) { should match(%r{^news.notice(\s)+-/var/log/news/news.notice}) } + its(:content) { should match(%r{^\*.=warning;\*.=err(\s)+-/var/log/warn}) } + its(:content) { should match(%r{^\*.crit(\s)+/var/log/warn}) } + its(:content) { should match(%r{^\*.\*;mail.none;news.none(\s)+-/var/log/messages}) } + its(:content) { should match(%r{^local0,local1.\*(\s)+-/var/log/localmessages}) } + its(:content) { should match(%r{^local2,local3.\*(\s)+-/var/log/localmessages}) } + its(:content) { should match(%r{^local2,local3.\*(\s)+-/var/log/localmessages}) } + its(:content) { should match(%r{^local4,local5.\*(\s)+-/var/log/localmessages}) } + its(:content) { should match(%r{^local6,local7.\*(\s)+-/var/log/localmessages}) } + end + end + end control 'cis-dil-benchmark-4.2.1.3' do From 057158ec92bd12c8ab67e369d634134ad82a48ef Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Fri, 7 Sep 2018 13:27:45 +0200 Subject: [PATCH 7/9] Updating section 5 to CIS v1.1.0 --- controls/5_2_ssh_server_configuration.rb | 27 ++--------- .../5_4_user_accounts_and_environments.rb | 46 +++++++++++++++++++ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/controls/5_2_ssh_server_configuration.rb b/controls/5_2_ssh_server_configuration.rb index 022c5a0..8d31346 100644 --- a/controls/5_2_ssh_server_configuration.rb +++ b/controls/5_2_ssh_server_configuration.rb @@ -156,25 +156,6 @@ end control 'cis-dil-benchmark-5.2.11' do - title 'Ensure only approved ciphers are used' - desc "This variable limits the types of ciphers that SSH can use during communication.\n\nRationale: Based on research conducted at various institutions, it was determined that the symmetric portion of the SSH Transport Protocol (as described in RFC 4253) has security weaknesses that allowed recovery of up to 32 bits of plaintext from a block of ciphertext that was encrypted with the Cipher Block Chaining (CBD) method. From that research, new Counter mode algorithms (as described in RFC4344) were designed that are not vulnerable to these types of attacks and these algorithms are now recommended for standard use." - impact 1.0 - - tag cis: 'distribution-independent-linux:5.2.11' - tag level: 1 - - describe sshd_config do - its(:Ciphers) { should_not be_nil } - end - - if sshd_config.Ciphers - describe sshd_config.Ciphers.split(',').each do - it { should_not match(/-cbc$/) } - end - end -end - -control 'cis-dil-benchmark-5.2.12' do title 'Ensure only approved MAC algorithms are used' desc "This variable limits the types of MAC algorithms that SSH can use during communication.\n\nRationale: MD5 and 96-bit MAC algorithms are considered weak and have been shown to increase exploitability in SSH downgrade attacks. Weak algorithms continue to have a great deal of attention as a weak spot that can be exploited with expanded computing power. An attacker that breaks the algorithm could take advantage of a MiTM position to decrypt the SSH tunnel and capture credentials and information" impact 1.0 @@ -206,7 +187,7 @@ end end -control 'cis-dil-benchmark-5.2.13' do +control 'cis-dil-benchmark-5.2.12' do title 'Ensure SSH Idle Timeout Interval is configured' desc "The two options ClientAliveInterval and ClientAliveCountMax control the timeout of ssh sessions. When the ClientAliveInterval variable is set, ssh sessions that have no activity for the specified length of time are terminated. When the ClientAliveCountMax variable is set, sshd will send client alive messages at every ClientAliveInterval interval. When the number of consecutive client alive messages are sent with no response from the client, the ssh session is terminated. For example, if the ClientAliveInterval is set to 15 seconds and the ClientAliveCountMax is set to 3, the client ssh session will be terminated after 45 seconds of idle time.\n\nRationale: Having no timeout value associated with a connection could allow an unauthorized user access to another user's ssh session (e.g. user walks away from their computer and doesn't lock the screen). Setting a timeout value at least reduces the risk of this happening.. While the recommended setting is 300 seconds (5 minutes), set this timeout value based on site policy. The recommended setting for ClientAliveCountMax is 0. In this case, the client session will be terminated after 5 minutes of idle time and no keepalive messages will be sent." impact 1.0 @@ -220,7 +201,7 @@ end end -control 'cis-dil-benchmark-5.2.14' do +control 'cis-dil-benchmark-5.2.13' do title 'Ensure SSH LoginGraceTime is set to one minute or less' desc "The LoginGraceTime parameter specifies the time allowed for successful authentication to the SSH server. The longer the Grace period is the more open unauthenticated connections can exist. Like other session controls in this session the Grace Period should be limited to appropriate organizational limits to ensure the service is available for needed access.\n\nRationale: Setting the LoginGraceTime parameter to a low number will minimize the risk of successful brute force attacks to the SSH server. It will also limit the number of concurrent unauthenticated connections While the recommended setting is 60 seconds (1 Minute), set the number based on site policy." impact 1.0 @@ -233,7 +214,7 @@ end end -control 'cis-dil-benchmark-5.2.15' do +control 'cis-dil-benchmark-5.2.14' do title 'Ensure SSH access is limited' desc "There are several options available to limit which users and group can access the system via SSH. It is recommended that at least one of the following options be leveraged: AllowUsers\nThe AllowUsers variable gives the system administrator the option of allowing specific users to ssh into the system. The list consists of comma separated user names. Numeric user IDs are not recognized with this variable. If a system administrator wants to restrict user access further by only allowing the allowed users to log in from a particular host, the entry can be specified in the form of user@host. AllowGroups\nThe AllowGroups variable gives the system administrator the option of allowing specific groups of users to ssh into the system. The list consists of comma separated group names. Numeric group IDs are not recognized with this variable. DenyUsers\nThe DenyUsers variable gives the system administrator the option of denying specific users to ssh into the system. The list consists of comma separated user names. Numeric user IDs are not recognized with this variable. If a system administrator wants to restrict user access further by specifically denying a user's access from a particular host, the entry can be specified in the form of user@host. DenyGroups\nThe DenyGroups variable gives the system administrator the option of denying specific groups of users to ssh into the system. The list consists of comma separated group names. Numeric group IDs are not recognized with this variable.\n\nRationale: Restricting which users can remotely access the system via SSH will help ensure that only authorized users access the system." @@ -251,7 +232,7 @@ end end -control 'cis-dil-benchmark-5.2.16' do +control 'cis-dil-benchmark-5.2.15' do title 'Ensure SSH warning banner is configured' desc "The Banner parameter specifies a file whose contents must be sent to the remote user before authentication is permitted. By default, no banner is displayed.\n\nRationale: Banners are used to warn connecting users of the particular site's policy regarding connection. Presenting a warning message prior to the normal user login may assist the prosecution of trespassers on the computer system." impact 1.0 diff --git a/controls/5_4_user_accounts_and_environments.rb b/controls/5_4_user_accounts_and_environments.rb index a9a798a..03dd7d8 100644 --- a/controls/5_4_user_accounts_and_environments.rb +++ b/controls/5_4_user_accounts_and_environments.rb @@ -15,6 +15,8 @@ # # author: Kristian Vlaardingerbroek +cis_level = attribute('cis_level', default: '2', description: 'CIS profile level to audit', required: true) + title '5.4 User Accounts and Environments' shadow_files = ['/etc/shadow'] @@ -23,6 +25,12 @@ passwd_files = ['/etc/passwd'] passwd_files << '/usr/share/baselayout/passwd' if file('/etc/nsswitch.conf').content =~ /^passwd:\s+(\S+\s+)*usrfiles/ +time_now = Time.now.to_i + + + +# The official documentation specifying 365 days in the description but, using +# 90 as an example settings control 'cis-dil-benchmark-5.4.1.1' do title 'Ensure password expiration is 90 days or less' desc "The PASS_MAX_DAYS parameter in /etc/login.defs allows an administrator to force passwords to expire once they reach a defined age. It is recommended that the PASS_MAX_DAYS parameter be set to less than or equal to 90 days.\n\nRationale: The window of opportunity for an attacker to leverage compromised credentials or successfully compromise credentials via an online brute force attack is limited by the age of the password. Therefore, reducing the maximum age of a password also reduces an attacker's window of opportunity." @@ -115,6 +123,21 @@ end end +control 'cis-dil-benchmark-5.4.1.5' do + title 'Ensure all users last password change date is in the past' + desc "All users should have a password change date in the past.\n\nRationale: If a users recorded password change date is in the future then they could bypass any set password expiration." + impact 1.0 + + tag cis: 'distribution-independent-linux:5.4.1.5' + tag level: 1 + + command("cat /etc/shadow | cut -d: -f1").stdout.split.each do |username| + describe command('date -d "`export LANG="en_US.UTF-8" ; chage --list root | grep "Last password" | cut -d: -f2`" +%s') do + its(:stdout) { should cmp <= time_now } + end + end +end + control 'cis-dil-benchmark-5.4.2' do title 'Ensure system accounts are non-login' desc "There are a number of accounts provided with Ubuntu that are used to manage applications and are not intended to provide an interactive shell.\n\nRationale: It is important to make sure that accounts that are not being used by regular users are prevented from being used to provide an interactive shell. By default, Ubuntu sets the password field for these accounts to an invalid string, but it is also recommended that the shell field in the password file be set to /sbin/nologin. This prevents the account from potentially being used to run any commands." @@ -177,6 +200,29 @@ end end +if cis_level == '2' + control 'cis-dil-benchmark-5.4.5' do + title 'Ensure default user shell timeout is 900 seconds or less' + desc "The default TMOUT determines the shell timeout for users. The TMOUT value is measured in seconds.\n\nRationale: Having no timeout value associated with a shell could allow an unauthorized user access to another user's shell session (e.g. user walks away from their computer and doesn't lock the screen). Setting a timeout value at least reduces the risk of this happening." + impact 1.0 + + tag cis: 'distribution-independent-linux:5.4.5' + tag level: 2 + + command("sudo find /etc/ -maxdepth 1 -name *bashrc*").stdout.split.each do |bashrc_file| + describe command("grep '^TMOUT' #{bashrc_file} | cut -d= -f2") do + its(:stdout) { should cmp <= 900 } + end + end + + %w(profile).each do |f| + describe command("grep '^TMOUT' /etc/#{f} | cut -d= -f2") do + its(:stdout) { should cmp <= 900 } + end + end + end +end + control 'cis-dil-benchmark-5.5' do title 'Ensure root login is restricted to system console' desc "The file /etc/securetty contains a list of valid terminals that may be logged in directly as root.\n\nRationale: Since the system console has special properties to handle emergency situations, it is important to ensure that the console is in a physically secure location and that unauthorized consoles have not been defined." From 500036e655b042bb8b036eea5c1864dcd8176264 Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Fri, 7 Sep 2018 14:27:38 +0200 Subject: [PATCH 8/9] Modified cis-dil-benchmark-5.4.2 to avoid deprecation warning --- controls/5_4_user_accounts_and_environments.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controls/5_4_user_accounts_and_environments.rb b/controls/5_4_user_accounts_and_environments.rb index 03dd7d8..b0fdd5d 100644 --- a/controls/5_4_user_accounts_and_environments.rb +++ b/controls/5_4_user_accounts_and_environments.rb @@ -157,7 +157,7 @@ end describe shadow(user.user) do - its(:password) { should be_all { |m| m == '*' } } + its(:passwords) { should be_all { |m| m == '*' } } end end end From eefb9bd60411d61f3f7d327cffef7877ff1dd6bf Mon Sep 17 00:00:00 2001 From: Csaba Patyi Date: Fri, 7 Sep 2018 14:31:28 +0200 Subject: [PATCH 9/9] Updating README.md file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2322ea0..e13c661 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # CIS Distribution Independent Linux Benchmark - InSpec Profile ## Description -This profile implements the [CIS Distribution Independent Linux 1.0.1 Benchmark](https://www.cisecurity.org/benchmark/distribution_independent_linux/). +This profile implements the [CIS Distribution Independent Linux 1.1.0 Benchmark](https://www.cisecurity.org/benchmark/distribution_independent_linux/). ## Attributes