# yaml-language-server: $schema=../../../../schema/control.schema.json id: CB-UBU-AUTH-002 title: Keep system details out of the message of the day finding: title: The message of the day shows the operating system version and kernel release to every user who logs in description: Every login session, including a compromised account, learns the exact release and kernel to target. status: active profiles: [core] risk: severity: low assessment: automated tags: [banner, login, motd] description: | After login, `pam_motd` shows `/etc/motd` and a dynamic message built by running the executable scripts of `/etc/update-motd.d/` with `run-parts`. On Ubuntu, `00-header` prints the full distribution version and the kernel name, release and architecture (`Welcome to Ubuntu 24.04.5 LTS (GNU/Linux 6.8.0-147-generic x86_64)`), and some other scripts can repeat the version (on 20.04, the ESM notice of `91-contract-ua-esm-status`). This control runs the dynamic message as `pam_motd` does and checks that its output names neither the running kernel release nor the `Ubuntu ` of the system. rationale: | The kernel release and the exact distribution version tell an attacker who reached a shell, or who only watches a session, which local privilege escalation exploits apply. There is no need to show them to every user at every login. impact: | Users no longer see the welcome line with the version and kernel at login, nor any other script that printed them. They can still run `uname -a` or `lsb_release -a`. The other parts of the message (help links, system load, pending updates) are kept. notes: | The fix records the new mode with `dpkg-statoverride`, so a package upgrade (for example of `base-files`, which owns `00-header`) does not make the script executable again. Ubuntu ships no `/etc/motd`; its check only applies when an administrator created one. setting: location: /etc/motd, /etc/update-motd.d/00-header default_value: 00-header executable, no /etc/motd recommended_value: Scripts that print the version or kernel not executable, /etc/motd without OS details audit: manual: | 1. If `/etc/motd` exists, it must not contain the escape sequences `\m`, `\r`, `\s`, `\v` or `Ubuntu` followed by a version. 2. Run `run-parts --lsbsysinit /etc/update-motd.d` as root. The output must not contain the result of `uname -r`, nor `Ubuntu` followed by the `VERSION_ID` of `/etc/os-release`. checks: - id: motd-no-os engine: file-content description: /etc/motd does not reveal the system version (not applicable when absent). spec: { path: /etc/motd, pattern: "\\\\[mrsv]|Ubuntu [0-9]", expect: no_match } - id: dynamic-motd engine: shell description: Output of the dynamic MOTD scripts, as built by pam_motd. spec: script: | [ -d /etc/update-motd.d ] || { echo "no /etc/update-motd.d"; exit 2; } v=$(. /etc/os-release && printf '%s' "$VERSION_ID") k=$(uname -r) hits=$(timeout 120 run-parts --lsbsysinit /etc/update-motd.d 2>/dev/null | grep -F -e "$k" -e "Ubuntu $v") if [ -n "$hits" ]; then printf '%s\n' "$hits" | head -n 3; exit 1; fi echo "no kernel release or Ubuntu $v in the dynamic MOTD" remediation: manual: | 1. For each script of `/etc/update-motd.d/` whose output shows the version or the kernel (`00-header` by default), remove the execute bit in a way that survives upgrades: `dpkg-statoverride --update --add root root 0644 /etc/update-motd.d/00-header`. 2. Remove OS names, versions and escape sequences from `/etc/motd`, if it exists. effects: restart: none disruption: none lockout_risk: false rollback: | For each changed script: `dpkg-statoverride --remove /etc/update-motd.d/