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¶
- Install
telnetd, find it running, stop and disable it, then purge it. - Write a unit file in
/etc/systemd/systemthat runssleep 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.