{
  "id": "CB-UBU-AUDIT-016",
  "standard": "ubuntu",
  "version": "main",
  "url": "https://baselines.cirsec.org/b/ubuntu/CB-UBU-AUDIT-016",
  "json": "https://baselines.cirsec.org/b/ubuntu/CB-UBU-AUDIT-016.json",
  "yaml": "https://baselines.cirsec.org/b/ubuntu/CB-UBU-AUDIT-016.yml",
  "profiles_effective": [
    "server-hardened",
    "desktop-hardened"
  ],
  "license": "Text CC BY 4.0, code Apache-2.0",
  "attribution": "CIRSEC Baselines, https://baselines.cirsec.org",
  "control": {
    "id": "CB-UBU-AUDIT-016",
    "title": "Audit changes to sudo rights and commands run as another user",
    "finding": {
      "title": "Changes to administrator rights and use of other identities are not recorded",
      "description": "Without these records, nobody can tell who granted sudo rights or who acted under another account."
    },
    "status": "active",
    "profiles": [
      "server-hardened",
      "desktop-hardened"
    ],
    "risk": {
      "severity": "medium"
    },
    "assessment": "automated",
    "tags": [
      "auditd",
      "sudo"
    ],
    "description": "Three groups of auditd rules, written to `/etc/audit/rules.d/60-cirsec-scope.rules`:\n\n- writes and attribute changes on `/etc/sudoers` and `/etc/sudoers.d/` (key `scope`);\n- every program started with an effective user different from the real user, by a user who\n  logged in (`execve` with `uid!=euid`, 64 and 32-bit calls, key `user_emulation`), which covers\n  `sudo`, `su` and other setuid programs;\n- writes to the sudo log file `{{ sudo_log_file }}` (key `sudo_log_file`).\n",
    "rationale": "Granting oneself sudo rights is a classic persistence and privilege escalation step. Recording\neach change to the sudo policy, each command run under another identity and each attempt to\nedit the sudo log keeps administrative actions attributable to the person who logged in.\n",
    "impact": "Busy systems where users run many setuid programs produce more audit records.\n",
    "notes": "For each system call the kernel keeps the key of the first matching rule. Running `sudo` or `su` is usually recorded with the key `privileged` (CB-UBU-AUDIT-026), whose rules load first; `user_emulation` catches the other cases.\n",
    "setting": {
      "location": "/etc/audit/rules.d/60-cirsec-scope.rules",
      "default_value": "No audit rules",
      "recommended_value": "Rules loaded (auditctl -l) and present in /etc/audit/rules.d/60-cirsec-scope.rules"
    },
    "parameters": [
      {
        "name": "sudo_log_file",
        "type": "string",
        "description": "Path of the sudo log file to watch (the logfile option of sudoers, see CB-UBU-AUTH-005).",
        "default": "/var/log/sudo.log"
      }
    ],
    "audit": {
      "manual": "1. Run `auditctl -l` as root. It must list the rules shown below (keys `scope`, `sudo_log_file`, `user_emulation`).\n2. Run `grep -h . /etc/audit/rules.d/*.rules`. The same rules must be present, so they load at boot.\n\nExpected rules, as `auditctl -l` prints them:\n```\n-w /etc/sudoers -p wa -k scope\n-w /etc/sudoers.d -p wa -k scope\n-a always,exit -F arch=b64 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation\n-a always,exit -F arch=b32 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation\n```\n",
      "checks": [
        {
          "id": "rules",
          "engine": "shell",
          "description": "Rules loaded in the kernel and present in /etc/audit/rules.d.",
          "spec": {
            "script": "command -v auditctl >/dev/null 2>&1 || { echo \"auditctl not found: auditd is not installed\"; exit 1; }\nwant() {\ncat <<'RULES'\n-w /etc/sudoers -p wa -k scope\n-w /etc/sudoers.d -p wa -k scope\n-a always,exit -F arch=b64 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation\n-a always,exit -F arch=b32 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation\nRULES\nprintf -- '-w %s -p wa -k sudo_log_file\\n' \"$CB_SUDO_LOG_FILE\"\n}\nloaded=$(auditctl -l 2>&1) || { echo \"$loaded\"; exit 3; }\ndisk=$(cat /etc/audit/rules.d/*.rules 2>/dev/null)\nn=0 rc=0\nwhile IFS= read -r r; do\n  [ -n \"$r\" ] || continue\n  n=$((n + 1))\n  printf '%s\\n' \"$loaded\" | grep -Fxq -- \"$r\" || { echo \"not loaded: $r\"; rc=1; }\n  printf '%s\\n' \"$disk\" | grep -Fxq -- \"$r\" || { echo \"not in /etc/audit/rules.d: $r\"; rc=1; }\ndone <<EOF\n$(want)\nEOF\n[ \"$rc\" = 1 ] || echo \"$n rules loaded and present in /etc/audit/rules.d\"\nexit \"$rc\"\n"
          }
        }
      ]
    },
    "remediation": {
      "manual": "1. Write the expected rules to `/etc/audit/rules.d/60-cirsec-scope.rules` (mode 0640).\n2. Run `augenrules --load`. If `auditctl -s` shows `enabled 2`, the configuration is locked:\n   reboot to load the new rules.\n",
      "effects": {
        "restart": "none",
        "disruption": "none",
        "lockout_risk": false
      },
      "rollback": "Delete `/etc/audit/rules.d/60-cirsec-scope.rules` and run `augenrules --load` (or reboot if the configuration is locked).\n",
      "scripts": [
        {
          "id": "rules-file",
          "engine": "shell",
          "content": "command -v augenrules >/dev/null 2>&1 || { echo \"auditd is not installed\" >&2; exit 1; }\nwant() {\ncat <<'RULES'\n-w /etc/sudoers -p wa -k scope\n-w /etc/sudoers.d -p wa -k scope\n-a always,exit -F arch=b64 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation\n-a always,exit -F arch=b32 -S execve -C uid!=euid -F auid!=-1 -F key=user_emulation\nRULES\nprintf -- '-w %s -p wa -k sudo_log_file\\n' \"$CB_SUDO_LOG_FILE\"\n}\nf=/etc/audit/rules.d/60-cirsec-scope.rules\nt=$(mktemp)\n{ echo '# Written by CIRSEC Baselines CB-UBU-AUDIT-016'; want; } >\"$t\"\nif ! cmp -s \"$t\" \"$f\"; then\n  cb_backup \"$f\"\n  cat \"$t\" >\"$f\"\nfi\nrm -f \"$t\"\nchmod 640 \"$f\"\nif auditctl -s | grep -q '^enabled 2'; then\n  echo \"audit rules are locked (-e 2): reboot to load $f\"\nelse\n  augenrules --load >/dev/null\nfi\n"
        }
      ]
    },
    "references": [
      {
        "title": "audit.rules(7), Ubuntu manual pages",
        "url": "https://manpages.ubuntu.com/manpages/noble/man7/audit.rules.7.html",
        "publisher": "Canonical",
        "kind": "vendor-doc",
        "accessed": "2026-10-19"
      },
      {
        "title": "auditctl(8), Ubuntu manual pages",
        "url": "https://manpages.ubuntu.com/manpages/noble/man8/auditctl.8.html",
        "publisher": "Canonical",
        "kind": "vendor-doc",
        "accessed": "2026-10-19"
      },
      {
        "title": "ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R73)",
        "url": "https://messervices.cyber.gouv.fr/documents-guides/fr_np_linux_configuration-v2.0.pdf",
        "publisher": "ANSSI",
        "kind": "guide",
        "accessed": "2026-10-19"
      }
    ],
    "mappings": [
      {
        "framework": "anssi-linux",
        "framework_version": "2.0",
        "id": "R33",
        "relation": "partial",
        "note": "R33 asks for accountability of administration actions; this control records them."
      },
      {
        "framework": "anssi-linux",
        "framework_version": "2.0",
        "id": "R73",
        "relation": "partial"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AU-12",
        "relation": "related"
      },
      {
        "framework": "nist-800-53r5",
        "framework_version": "5.1.1",
        "id": "AC-6(9)",
        "relation": "related"
      }
    ],
    "threats": [
      {
        "framework": "mitre-attack",
        "id": "T1548.003"
      },
      {
        "framework": "mitre-attack",
        "id": "T1070.002"
      }
    ],
    "related_controls": [
      {
        "id": "CB-UBU-AUDIT-011",
        "type": "requires"
      },
      {
        "id": "CB-UBU-AUDIT-029",
        "type": "related"
      },
      {
        "id": "CB-UBU-AUTH-005",
        "type": "related"
      }
    ],
    "authors": [
      {
        "name": "Alice",
        "github": "Sn0wAlice"
      }
    ],
    "verified": [
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "20.04"
        ],
        "environment": "Proxmox VM, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic",
        "notes": "Fails after auditd install; rules written and loaded (augenrules), all present in auditctl -l with auditd 2.8.5; passes after reboot with enabled 2."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "22.04"
        ],
        "environment": "Proxmox VM, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic",
        "notes": "Fails after auditd install; rules written and loaded (augenrules), all present in auditctl -l with auditd 3.0.7; passes after reboot with enabled 2."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "24.04"
        ],
        "environment": "Proxmox VM, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic",
        "notes": "Fails after auditd install; rules written and loaded (augenrules), all present in auditctl -l with auditd 3.1.2; passes after reboot with enabled 2."
      },
      {
        "date": "2026-10-19",
        "by": "Sn0wAlice",
        "versions": [
          "26.04"
        ],
        "environment": "Proxmox VM, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic",
        "notes": "Fails after auditd install; rules written and loaded (augenrules), all present in auditctl -l with auditd 4.1.2; passes after reboot with enabled 2."
      }
    ],
    "introduced_in": "0.1.0",
    "created": "2026-10-19",
    "updated": "2026-10-19"
  }
}