From 5d29e31dd3d3a918fd4012ceaee32d39c4b4c15f Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Mon, 25 Oct 2021 09:17:30 +0200 Subject: [PATCH 1/2] feat: expand security control to check for other shadow files Currently only `/etc/shadow` is checked to have the right permissions, but there are other files that can/could contain password hashes as well, which are not checked yet: - /etc/shadow- (a backup file for /etc/shadow) - /etc/gshadow (contains group password hashes) - /etc/gshadow- (a backup file for /etc/gshadow-) While the control requires `/etc/shadow` and `/etc/gshadow` to exist, the rules for their backup counterparts are a bit more relaxed. The checks will be skipped, if those files do not exist. Signed-off-by: Claudius Heine --- controls/os_spec.rb | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index ec2bbf9..327fcac 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -282,3 +282,55 @@ end end end + +control 'os-14' do + impact 1.0 + title 'Check owner and permissions for /etc/gshadow' + desc 'Check periodically the owner and permissions for /etc/gshadow' + describe file('/etc/gshadow') do + it { should exist } + it { should be_file } + it { should be_owned_by 'root' } + its('group') { should eq shadow_group } + it { should_not be_executable } + it { should_not be_writable.by('group') } + it { should_not be_writable.by('other') } + it { should_not be_readable.by('other') } + end +end + +control 'os-15' do + impact 1.0 + title 'Check owner and permissions for /etc/shadow-' + desc 'Check periodically the owner and permissions for /etc/shadow-' + only_if('/etc/shadow- exists') do + file('/etc/shadow-').exist? + end + describe file('/etc/shadow-') do + it { should be_file } + it { should be_owned_by 'root' } + its('group') { should eq shadow_group } + it { should_not be_executable } + it { should_not be_writable.by('group') } + it { should_not be_writable.by('other') } + it { should_not be_readable.by('other') } + end +end + +control 'os-16' do + impact 1.0 + title 'Check owner and permissions for /etc/gshadow-' + desc 'Check periodically the owner and permissions for /etc/gshadow-' + only_if('/etc/gshadow- exists') do + file('/etc/gshadow-').exist? + end + describe file('/etc/gshadow-') do + it { should be_file } + it { should be_owned_by 'root' } + its('group') { should eq shadow_group } + it { should_not be_executable } + it { should_not be_writable.by('group') } + it { should_not be_writable.by('other') } + it { should_not be_readable.by('other') } + end +end From 4b67c2dc31d64a24ed30f382fac66741dffed722 Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Mon, 25 Oct 2021 09:22:51 +0200 Subject: [PATCH 2/2] feat: expand security check: add other passwd and group files Currently only `/etc/passwd` is checked to have the right permissions, but there are other files that contain unix account related configuration: - /etc/passwd- (a backup file for /etc/passwd) - /etc/group (contains group configuration and membership) - /etc/group- (a backup file for /etc/group-) While the control requires `/etc/passwd` and `/etc/group` to exist, the rules for their backup counterparts are a bit more relaxed. The checks will be skipped, if those files do not exist. Signed-off-by: Claudius Heine --- controls/os_spec.rb | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index 327fcac..904a99f 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -334,3 +334,63 @@ it { should_not be_readable.by('other') } end end + +control 'os-17' do + impact 1.0 + title 'Check owner and permissions for /etc/group' + desc 'Check periodically the owner and permissions for /etc/group' + describe file('/etc/group') do + it { should exist } + it { should be_file } + it { should be_owned_by 'root' } + its('group') { should eq 'root' } + it { should_not be_executable } + it { should be_writable.by('owner') } + it { should be_readable.by('owner') } + it { should_not be_writable.by('group') } + it { should be_readable.by('group') } + it { should_not be_writable.by('other') } + it { should be_readable.by('other') } + end +end + +control 'os-18' do + impact 1.0 + title 'Check owner and permissions for /etc/passwd-' + desc 'Check periodically the owner and permissions for /etc/passwd-' + only_if('/etc/passwd- exists') do + file('/etc/passwd-').exist? + end + describe file('/etc/passwd-') do + it { should be_file } + it { should be_owned_by 'root' } + its('group') { should eq 'root' } + it { should_not be_executable } + it { should be_writable.by('owner') } + it { should be_readable.by('owner') } + it { should_not be_writable.by('group') } + it { should be_readable.by('group') } + it { should_not be_writable.by('other') } + it { should be_readable.by('other') } + end +end + +control 'os-19' do + impact 1.0 + title 'Check owner and permissions for /etc/group-' + desc 'Check periodically the owner and permissions for /etc/group-' + only_if('/etc/group- exists') do + file('/etc/group-').exist? + end + describe file('/etc/group-') do + it { should be_owned_by 'root' } + its('group') { should eq 'root' } + it { should_not be_executable } + it { should be_writable.by('owner') } + it { should be_readable.by('owner') } + it { should_not be_writable.by('group') } + it { should be_readable.by('group') } + it { should_not be_writable.by('other') } + it { should be_readable.by('other') } + end +end