From b1fa8c11a90a580d83c8e60959531da80d9a19ac Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Wed, 3 Nov 2021 15:12:35 +0100 Subject: [PATCH 1/7] feat: add rule to check for password change dates in the past A password changed date in the future could be used to circumvent password expiration dates. This rule checks that any password change dates are in the past. Signed-off-by: Claudius Heine --- controls/os_spec.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index ec2bbf9..e8984ec 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -282,3 +282,12 @@ end end end + +control 'os-14' do + impact 1.0 + title 'All password change dates are in the past' + desc 'The password change date is used to detect expired passwords. Entering future dates might circumvent that.' + describe shadow.where { last_change.to_i > (Date.today - Date.new(1970, 1, 1)).to_i } do + its('users') { should be_empty } + end +end From 458a6e70ea3e716d2d14a2d45ee8e4c14ce936a3 Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Wed, 3 Nov 2021 15:55:38 +0100 Subject: [PATCH 2/7] feat: add control to check if system user are non-login System users should be prevented from login with exceptions for applications that are non-interactive. Signed-off-by: Claudius Heine --- controls/os_spec.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index e8984ec..0d148e4 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -25,6 +25,14 @@ login_defs_passmindays = attribute('login_defs_passmindays', value: '7', description: 'Default password mindays to set in login.defs') login_defs_passwarnage = attribute('login_defs_passwarnage', value: '7', description: 'Default password warnage (days) to set in login.defs') +system_users = passwd.params ? passwd.params.select { |x| x['uid'].to_i < login_defs.UID_MIN.to_i && x['uid'].to_i.positive? } : [] + +system_users_non_login_permitlist = attribute( + 'system_users_non_login_permitlist', + value: %w[sync halt shutdown], + description: 'List of system users which are allowed to log in' +) + shadow_group = 'root' shadow_group = 'shadow' if os.debian? || os.suse? || os.name == 'alpine' container_execution = begin @@ -291,3 +299,16 @@ its('users') { should be_empty } end end + +control 'os-15' do + impact 1.0 + title 'All system users are non-login' + desc 'The login of system users should be disabled' + system_users.each do |user| + next if system_users_non_login_permitlist.include? user['user'] + + describe OpenStruct.new(user) do + its('shell') { should be_in ['/bin/false', '/sbin/nologin', '/usr/bin/false', '/usr/sbin/nologin'] } + end + end +end From 49b94e6203cea789ed87f45167d979f23be4b953 Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Thu, 4 Nov 2021 13:16:26 +0100 Subject: [PATCH 3/7] feat: add rule to check root user is member of group root This rule makes sure that the assumptions of user `root` being uid=0 is the sole member of group `root` with gid=0 are true. This prevents access to any root-owned files by non-privileged users. Signed-off-by: Claudius Heine --- controls/os_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index 0d148e4..6632bc2 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -312,3 +312,17 @@ end end end + +control 'os-16' do + impact 1.0 + title 'User \'root\' should be member of group \'root\' with gid \'0\'' + desc 'This prevents root-owned files and directories to be accessible to non-privileged users' + describe passwd.uids(0) do + its('users') { should cmp 'root' } + its('gids') { should cmp 0 } + end + describe etc_group.where(gid: 0) do + its('groups') { should cmp 'root' } + its('users') { should be_empty } + end +end From 18a5383bd7b3e628e89d9c257ec4776449c8f170 Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Thu, 4 Nov 2021 13:45:26 +0100 Subject: [PATCH 4/7] feat: add control to check for legacy NIS entries in account files '+' and '-' where prepended to lines in account files (/etc/passwd, /etc/group, /etc/shadow) to signify if fields should be overwritten or inserted from a NIS server. Since NIS is a insecure and legacy technology, that is replaced by other software, this check makes sure that no such entries exist anymore. Signed-off-by: Claudius Heine --- controls/os_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index 6632bc2..b2eb98d 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -326,3 +326,18 @@ its('users') { should be_empty } end end + +control 'os-17' do + impact 1.0 + title 'Prevent + or - fields in passwd an related files used by NIS' + desc 'NIS is insecure and should not be used' + describe file('/etc/passwd') do + its('content') { should_not match(/^[+-]/) } + end + describe file('/etc/shadow') do + its('content') { should_not match(/^[+-]/) } + end + describe file('/etc/group') do + its('content') { should_not match(/^[+-]/) } + end +end From 29211f206b5730bd28aa223ec843618170e55b77 Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Thu, 4 Nov 2021 13:55:27 +0100 Subject: [PATCH 5/7] feat: add rule to check users and groups are unique Signed-off-by: Claudius Heine --- controls/os_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index b2eb98d..18bdd0f 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -341,3 +341,17 @@ its('content') { should_not match(/^[+-]/) } end end + +control 'os-18' do + impact 1.0 + title 'Users and groups should be unique' + desc 'In order to avoid confusion or identity theft, every group and user should be unique' + describe passwd do + its('users') { should_not contain_duplicates } + its('uids') { should_not contain_duplicates } + end + describe etc_group do + its('groups') { should_not contain_duplicates } + its('gids') { should_not contain_duplicates } + end +end From 137b5735129d76ba8d015a20bbc3734b6252f213 Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Thu, 4 Nov 2021 14:14:25 +0100 Subject: [PATCH 6/7] feat: add rule to ensure shadow group does not have any members Members of the shadow group could have access to password hashes and other content of the shadow files. Signed-off-by: Claudius Heine --- controls/os_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index 18bdd0f..fc32cfc 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -355,3 +355,18 @@ its('gids') { should_not contain_duplicates } end end + +control 'os-19' do + impact 1.0 + title 'Shadow group should not have any users' + desc 'Members of the shadow group could have access to password hashes, so no user should be a member of that group' + shadow_group_entry = etc_group.where(name: shadow_group) + + describe passwd.gids(shadow_group_entry.gids) do + its('count') { should eq 0 } + end + + describe shadow_group_entry do + its('users') { should be_empty } + end +end From 4c607b050a3082442c048995b15a96798c9c6103 Mon Sep 17 00:00:00 2001 From: Claudius Heine Date: Thu, 4 Nov 2021 14:29:05 +0100 Subject: [PATCH 7/7] feat: add rules to ensure that all referred users and gids exist Signed-off-by: Claudius Heine --- controls/os_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/controls/os_spec.rb b/controls/os_spec.rb index fc32cfc..597cf28 100644 --- a/controls/os_spec.rb +++ b/controls/os_spec.rb @@ -370,3 +370,19 @@ its('users') { should be_empty } end end + +control 'os-20' do + impact 1.0 + title 'All users and gids referred in /etc/group and /etc/passwd should exist' + desc 'Errors in system administration can lead to a case where gids or uids referred to do not exist' + + gids = etc_group.gids.map(&:to_s) + describe passwd do + its('gids') { should be_in gids } + end + + users = passwd.users + describe etc_group do + its('users') { should be_in users } + end +end