Hitchhiker's Guide — Hardening Linux, Windows, and macOS Services

The operational companion to the Phase 05 WARMUP. The WARMUP compares the four OS security models (DAC/capabilities/LSM, tokens/ACLs/integrity, sandbox/entitlements/TCC); this guide is the how — the platform-native hardening config, the verification commands, the service-hardening method, and the detection validation that prove the controls hold without silently breaking the service. Generate telemetry with benign admin actions only.

Table of Contents


The Service Hardening Method

The repeatable procedure, applied identically across platforms:

  1. Record exact operations and dependencies the service actually performs.
  2. Trace files, registry/plist state, sockets, devices, child processes, and destinations.
  3. Inventory identity, privilege, inherited handles, and update authority.
  4. Remove authority incrementally with functional and denial tests after each removal.
  5. Add resource ceilings, restart behavior, health checks, and rollback.
  6. Generate benign misuse and prove telemetry reaches an owner.

One happy-path trace is incomplete. Exercise startup, shutdown, upgrade, errors, locale, DNS failure, log rotation, backup, and recovery — these are where a too-tight policy breaks the service in production (Phase 05 WARMUP, Chapter 3 — seccomp must allow the error/locale/DNS paths).

Linux Hardening and Verification

Use systemd directives matched to measured requirements (Phase 05 WARMUP, Chapter 4):

[Service]
User=svc-app
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
PrivateDevices=yes
RestrictSUIDSGID=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE      # only what it needs; drop the rest
SystemCallFilter=@system-service                 # seccomp allowlist
RestrictAddressFamilies=AF_INET AF_INET6
MemoryMax=256M
TasksMax=64

Verify the effective configuration, not the file:

systemd-analyze security svc-app        # exposure score + per-directive findings
systemctl show svc-app -p CapabilityBoundingSet -p NoNewPrivileges

Then test denied operations fail: system writes, home access, unexpected address families, privilege gain, fork pressure, egress. Use denial logs (auditd / journalctl) to refine the policy narrowly — add back only what the service genuinely needs.

Windows Hardening and Verification

  • a dedicated virtual/service account, not a broad administrator identity (Phase 05 WARMUP, Chapter 5 — token = SIDs + privileges);
  • quote executable paths and secure service binary/config ACLs (unquoted-path and weak-ACL hijacks);
  • remove unnecessary privileges and interactive logon;
  • protect PowerShell/script execution; collect Script Block + operational logs per policy;
  • deploy Sysmon with a tested, tuned configuration (Phase 05 WARMUP, Chapter 8);
  • protect recovery and update paths.

Verify: service config, binary/config ACLs, account rights, token privileges, integrity level, RPC/named-pipe ACLs, firewall rules, and event subscriptions (sc qc, accesschk, whoami /priv, Process Explorer). Test whether an unprivileged user can replace the executable/DLL/config/recovery content or influence privileged IPC. (Remember UAC is not a boundary — Phase 05 WARMUP, Chapter 6.)

macOS Hardening and Verification

  • validate code signature, hardened runtime, notarization/Gatekeeper path;
  • minimize entitlements and TCC-protected data access (Phase 05 WARMUP, Chapters 9–10);
  • secure launchd plist and executable ownership;
  • store secrets via Keychain APIs, never plist/environment;
  • prefer documented Endpoint Security / system extensions over kernel extensions.

Verify: codesign -dvvv, spctl -a -vv, entitlement dump, notarization, launchd ownership, UID, sandbox/TCC assumptions, Keychain groups, system extensions, and update signatures. Test helper/config replacement, unauthorized XPC callers, and leakage into the unified log or crash reports. (Not every entitlement is a vuln — flag unjustified ones.)

Attack Fixtures

The flagship normalized evaluator should catch these across platforms; the platform labs collect the evidence to populate it:

  • a service executable writable by its own identity (self-replace → persistence/escalation);
  • wildcard outbound network;
  • a secret canary in environment/log;
  • a missing process/memory ceiling;
  • a privileged service performing no privileged operation (over-privilege);
  • a hardening change with no rollback.

Detection Validation

Generate, with benign actions: a service-configuration change, a privileged start, an unexpected child process, protected-file access, an unusual outbound connection, and a rollback. Assert the normalized event has identity, process, action, target, time, and host. Then drop one source and prove a health alert fires (a silent source is a blind spot — Phase 09 preview). Each detection needs a benign positive fixture and a negative fixture.

Deliverables

  • a before/after authority graph per service;
  • platform-native configuration (systemd unit / Windows service config / launchd plist);
  • functional / denial / load / restart / upgrade / rollback results;
  • an open-handle (descriptor) inventory;
  • canary evidence (secrets absent from logs/telemetry);
  • incident-recovery runbooks;
  • honest limitations where a platform can't express the desired policy (state what needs EDR/MDM).

Worked Examples

Reading systemd-analyze security

systemd-analyze security svc-app
NAME                     EXPOSURE PREDICATE
PrivateNetwork           ✗        Service has access to the host's network
CapabilityBoundingSet    ✓ 0.1    No capabilities
SystemCallFilter         ✗        Service has no system call filter
...
→ Overall exposure level for svc-app: 7.8 EXPOSED 🙁

Read it as a to-do list, not a grade: the ✗ rows are the missing controls. Here, add a SystemCallFilter=@system-service and, if the service doesn't need raw networking, tighten RestrictAddressFamilies — then re-run and watch the score drop. The interviewer wants you to (a) inventory the service's actual needs first and (b) add controls without breaking it (re-test startup/error/DNS paths — Phase 05 WARMUP, Chapter 3).

Reading a Windows token

C:\> whoami /priv
Privilege Name                Description                          State
============================= ==================================== =======
SeDebugPrivilege              Debug programs                       Enabled   ← can open ANY process
SeBackupPrivilege             Back up files and directories        Enabled   ← bypasses file DACLs
SeImpersonatePrivilege        Impersonate a client after auth      Enabled   ← classic LPE primitive

These three privileges are near-equivalent to "owns the box" — flag them on a service account that doesn't need them. Note: this is the token's power, separate from object ACLs (Phase 05 WARMUP, Chapter 5). And remember UAC is not the boundary standing between a medium-integrity admin and SYSTEM (Chapter 6) — a favorite interview trap.

A seccomp deny in the wild

A service that worked in dev breaks in prod after you add SystemCallFilter:

audit: type=SECCOMP ... syscall=16(ioctl) ...    ← the locale/tty path needs ioctl

The lesson (WARMUP Chapter 3): build the allowlist from observed + reviewed behavior across error, locale, DNS, and threading paths — not one happy-path trace. Add ioctl only after confirming it's legitimate, with a regression test.

Interview Drills

  1. "Investigate a suspicious service creation on Windows." Security/System log + Sysmon (EID 1 process create with command line + hashes, 7045 service install): who (token/SID), with what privileges, installed what binary (path/signature), that then did what (network). Reconstruct the chain; check whether that account should be able to install services.
  2. "Design isolation for a Linux network service." Dedicated non-root user; drop all capabilities except (e.g.) CAP_NET_BIND_SERVICE; NoNewPrivileges; seccomp allowlist of its real syscalls; ProtectSystem/PrivateTmp or an AppArmor/SELinux profile; restrict address families. Inventory needs first, then minimal policy, then prove denied ops fail without breaking the service.
  3. "Explain Kerberos tickets." Authenticate once to the KDC → Ticket-Granting Ticket; exchange the TGT for a service ticket scoped to one service; present it, the service validates locally without the DC. Time-limited, audience-scoped bearer tokens — SSO with delegation. Risks: weak service-account keys, long lifetimes, unconstrained delegation.
  4. "Compare ETW, auditd, and Endpoint Security." All are the platform's kernel-level activity feed. ETW = Windows high-volume tracing (Sysmon curates a useful subset). auditd = Linux rule-driven syscall/file/auth audit (eBPF for richer/cheaper). Endpoint Security = Apple's authorized monitoring/EDR framework. Same detection role, different richness and consumption model.
  5. "Is UAC a security boundary?" No — Microsoft says so explicitly; it has by-design elevation paths and known bypasses. The real boundaries are the kernel, integrity levels, and the user/SYSTEM divide. Don't model UAC as a control in a threat assessment.

References

  • The Linux Programming Interface (Kerrisk); systemd, auditd, capabilities(7), seccomp docs.
  • Windows Internals (Russinovich et al.); Sysinternals (Sysmon, accesschk, Process Explorer); Microsoft "UAC is not a security boundary" guidance.
  • Apple Platform Security Guide; codesign/spctl/Endpoint Security documentation.
  • CIS Benchmarks (apply with workload context); MITRE ATT&CK (per-platform techniques + telemetry).
  • Sigma rule project (portable detections — Phase 09).