Skip to content

Services

systemd starts and supervises services. A service that's enabled starts at boot; one that's active is running now. Both matter: stopping a service without disabling it just means it's back after a reboot.

List them

systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service --state=enabled

The first is what's running; the second is what will run next boot. Compare each against the README's required services and against what Linux needs.

Stop and disable

sudo systemctl disable --now telnet.socket
sudo systemctl disable --now vsftpd
sudo systemctl mask cups

disable --now stops it and removes it from boot. mask goes further: the service can't be started even by hand or by another unit, useful for something an attacker's script keeps starting.

If the README doesn't need the software at all, remove the package instead (Installed Packages); a removed package can't be re-enabled.

Services to stop unless the README needs them

The benchmark lists these as "not in use" (CIS 2.1.1 to 2.1.21). Each one is Level 1 except where marked.

Service Package Why
autofs autofs Automatic mounting of removable and network filesystems (Level 2, 2.1.1)
isc-dhcp-server, kea DHCP server (2.1.3); a rogue one hands out bad gateways
dnsmasq dnsmasq Small DNS/DHCP server (2.1.5)
slapd slapd LDAP server (2.1.7)
dovecot, cyrus IMAP/POP mail access (2.1.8)
ypserv nis NIS, an ancient network password database (2.1.10)
rsync rsync (the daemon, not the command) Unauthenticated file sync service (2.1.14)
bluetooth bluez Radio nobody on a server or contest VM needs (Level 2, 3.1.2)
telnet.socket, telnetd telnetd Clear-text remote login (2.1.20 covers xinetd, which usually starts it)
rsh, rlogin, rexec rsh-server Same, older
vsftpd, proftpd, pure-ftpd Clear-text FTP unless TLS is configured (vsftpd)
tftpd-hpa tftpd-hpa Unauthenticated file transfer (2.1.17)
nfs-server, rpcbind nfs-kernel-server File shares with host-based trust (2.1.9, 2.1.13)
smbd, nmbd samba Windows file sharing (2.1.15; Samba)
apache2, nginx Web server (2.1.19; Apache, nginx)
mysql, mariadb, postgresql Database (MySQL, PostgreSQL)
cups, cups-browsed cups Printing (Level 2, 2.1.12); cups-browsed has had remote code execution bugs
avahi-daemon avahi-daemon Network service discovery (Level 2, 2.1.2)
snmpd snmpd Management protocol with default community strings (2.1.16)
xinetd, inetd Super-servers that can start anything listed in their config
x11vnc, vncserver, tightvncserver Remote desktop; rarely legitimate
bind9, named bind9 DNS server (2.1.4; DNS)
squid squid Web proxy (2.1.18)
vsftpd and friends FTP (2.1.6; vsftpd)
ssh openssh-server The benchmark treats a workstation's SSH server as unneeded (2.1.11); the README decides, and if it stays it's hardened on the SSH page
xserver-common The benchmark's 2.1.21 is for servers with no desktop; a Mint or Debian desktop image keeps its GUI
postfix, exim4 Mail. If a mail agent must stay for local delivery, it listens on localhost only (2.1.22): inet_interfaces = loopback-only in /etc/postfix/main.cf, then systemctl restart postfix.
squid, nmap, hydra, john Not services, but packages that show up next to them; see Installed Packages

Services to keep

ssh (if the README allows remote administration), ufw, systemd-resolved, systemd-timesyncd, cron, rsyslog, auditd, NetworkManager, lightdm (Mint) or gdm3 (Debian), unattended-upgrades. Stopping one of these to "close a door" breaks the machine or the audit trail.

Two the benchmark specifically wants running: cron (CIS 2.4.1.1), because scheduled jobs are how updates and log rotation happen, and exactly one time service, systemd-timesyncd (2.3.1.1, 2.3.2.2), pointed at a real server (2.3.2.1):

sudo mkdir -p /etc/systemd/timesyncd.conf.d
printf '[Time]\nNTP=time.nist.gov\nFallbackNTP=time-a-g.nist.gov time-b-g.nist.gov\n' | sudo tee /etc/systemd/timesyncd.conf.d/60-timesyncd.conf
sudo systemctl enable --now systemd-timesyncd
timedatectl status

If chrony or ntp is also installed alongside timesyncd, remove one; two time daemons fight. The Debian benchmark accepts either daemon; the STIG wants chrony specifically and systemd-timesyncd and ntp removed (UBTU-22-215015 to 215025, CAT III), with maxpoll 16 on the server line and makestep 1 -1 so the clock is stepped whenever it drifts more than a second (UBTU-22-252010, 252015). On a contest image either daemon is fine as long as there's exactly one and it's pointed at a real server. If the image uses chrony (systemctl is-active chrony), the equivalent is a pool line in /etc/chrony/sources.d/60-sources.sources (pool time.nist.gov iburst maxsources 4, Debian CIS 2.3.3.1), the service enabled (2.3.3.3), and ps -o user -C chronyd showing _chrony, not root (2.3.3.2).

Client programs to remove

Not services, but the benchmark lists them next to the services (CIS 2.2.1 to 2.2.6) because each is a clear-text or obsolete protocol an attacker on the box would use: nis, rsh-client, talk, telnet, ldap-utils, ftp (and tnftp).

sudo apt purge -y nis rsh-client talk telnet ldap-utils ftp tnftp 2>/dev/null

Cron and at permissions

A user who can write to a cron directory runs code as root on a schedule (CIS 2.4.1.2 to 2.4.2.1):

sudo chown root:root /etc/crontab /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly /etc/cron.yearly /etc/cron.d
sudo chmod 600 /etc/crontab; sudo chmod 700 /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly /etc/cron.yearly /etc/cron.d
sudo touch /etc/cron.allow /etc/at.allow; sudo chmod 640 /etc/cron.allow /etc/at.allow; sudo chown root:root /etc/cron.allow /etc/at.allow
sudo rm -f /etc/cron.deny /etc/at.deny

With cron.allow and at.allow present and empty, only root can create scheduled jobs. Add a username to cron.allow if the README says that user runs cron jobs.

Unknown services

systemctl list-unit-files --type=service --state=enabled | grep -v '@'
ls -l /etc/systemd/system/*.service

A unit file in /etc/systemd/system/ (rather than /lib/systemd/system/) was added by an administrator or an attacker. Read it; ExecStart= says what it runs.

Verify

systemctl is-active telnet.socket vsftpd    # inactive
systemctl is-enabled telnet.socket vsftpd   # disabled
systemctl list-units --type=service --state=running | wc -l

Example

The README says the machine is a web server (Apache) and nothing else. list-units --state=running shows apache2, vsftpd, telnet.socket, x11vnc, and updater.service. Stop and disable vsftpd, telnet, and x11vnc, then remove their packages. updater.service lives in /etc/systemd/system/ and its ExecStart is /usr/local/bin/.upd -c 10.0.0.5; that's a backdoor. Disable it, delete the unit and the binary, systemctl daemon-reload.

Try it

  1. Install telnetd, find it running, stop and disable it, then purge it.
  2. Write a unit file in /etc/systemd/system that runs sleep 1000, enable it, find it with the listing commands, remove it.

Build it

A services.sh with a list of service names that prints is-active and is-enabled for each; a --disable switch that stops and disables them. Report mode first.

Next

The Firewall