Ensure that System Accounts Do Not Run a Shell Upon Login

Description

Some accounts are not associated with a human user of the system, and exist to perform some administrative functions. Should an attacker be able to log into these accounts, they should not be granted access to a shell.

The login shell for each local account is stored in the last field of each line in /etc/passwd. System accounts are those user accounts with a user ID less than 1000. The user ID is stored in the third field. If any system account other than root has a login shell, disable it with the command:

$ sudo usermod -s /sbin/nologin account
         

Rationale

Ensuring shells are not given to system accounts upon login makes it more difficult for attackers to make use of system accounts.

Remediation

Shell script

The following script can be run on the host to remediate the issue.

#!/bin/bash

readarray -t systemaccounts < <(awk -F: '($3 < 1000 && $3 != root \
  && $7 != "\/sbin\/shutdown" && $7 != "\/sbin\/halt" && $7 != "\/bin\/sync") \
  { print $1 }' /etc/passwd)

for systemaccount in "${systemaccounts[@]}"; do
    usermod -s /sbin/nologin "$systemaccount"
done

Ansible playbook

The following playbook can be run with Ansible to remediate the issue.

- name: Ensure that System Accounts Do Not Run a Shell Upon Login - Get All Local
    Users From /etc/passwd
  ansible.builtin.getent:
    database: passwd
    split: ':'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-8.2.2
  - low_complexity
  - medium_disruption
  - medium_severity
  - no_reboot_needed
  - no_shelllogin_for_systemaccounts
  - restrict_strategy

- name: Ensure that System Accounts Do Not Run a Shell Upon Login - Create local_users
    Variable From getent_passwd Facts
  ansible.builtin.set_fact:
    local_users: '{{ ansible_facts.getent_passwd | dict2items }}'
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-8.2.2
  - low_complexity
  - medium_disruption
  - medium_severity
  - no_reboot_needed
  - no_shelllogin_for_systemaccounts
  - restrict_strategy

- name: Ensure that System Accounts Do Not Run a Shell Upon Login -  Disable Login
    Shell for System Accounts
  ansible.builtin.user:
    name: '{{ item.key }}'
    shell: /sbin/nologin
  loop: '{{ local_users }}'
  when:
  - item.key not in ['root']
  - item.value[1]|int < 1000
  - item.value[5] not in ['/sbin/shutdown', '/sbin/halt', '/bin/sync']
  tags:
  - NIST-800-53-AC-6
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-6(b)
  - NIST-800-53-CM-6.1(iv)
  - PCI-DSSv4-8.2.2
  - low_complexity
  - medium_disruption
  - medium_severity
  - no_reboot_needed
  - no_shelllogin_for_systemaccounts
  - restrict_strategy

Warning

Do not perform the steps in this section on the root account. Doing so might cause the system to become inaccessible.