Skip to main content

Reducing Attack Surface

Attack surface is considered everything that is exposed and may contain security risks that can be exploited by someone or malicious code. If we were to create categories they could be:

  • Applications
  • Networks
  • Identity Management (IAM)

How to reduce the attack surface?

  • Applications

    • Keep them updated.
    • Keep the Linux kernel updated.
    • Remove unnecessary packages and applications.
      • print services
      • ftp
      • others
    • The fewer packages, the lower the risk.
  • Networks

    • Check and close unnecessary open ports.
    • Put the network behind a firewall.
      • the apiserver should be protected by a firewall so it can't be reached from outside.
  • IAM

    • Restriction of user permissions.
    • Run applications as user and not as root.

Nodes

  • Should only run Kubernetes components.
    • Masters should run control plane components.
    • Workers should run worker components.
    • Except for some applications like Falco for behavioral analysis and related things.
    • Avoid using unprepared distributions, i.e., a standard Ubuntu that comes full of unnecessary enabled services.
  • Node Recycling
    • Nodes should be ephemeral, just like containers. At any time we should be able to get rid of a node and replace it with a new one.
    • Should be created through images to make replacement quick.

From now on we'll do a basic Linux overview that allows us to do the minimum in the exam.

  • netstat - plnt (analyze ports in use)
  • lsof -i :22 (analyze processes using a specific port, in this case 22)
  • systemctl status|start|restart|stop servicename (manipulate services)
  • ps -aux (see running processes)

Ubuntu comes with a service type package manager called snap. It's an "alternative" for installing applications in a specific format that are not .deb packages.

root@cks-master:~# systemctl list-units --type=service --state=running | grep snap
snapd.service loaded active running Snap Daemon
# Stopping the service is momentary. If the system restarts it will come back active.
root@cks-master:~# systemctl stop snapd.service
Warning: Stopping snapd.service, but it can still be activated by:
snapd.socket
# Disabling it won't come back.
root@cks-master:~# systemctl disable snapd.service
Removed /etc/systemd/system/multi-user.target.wants/snapd.service.
root@cks-master:~# systemctl status snapd.service
● snapd.service - Snap Daemon
Loaded: loaded (/lib/systemd/system/snapd.service; disabled; vendor preset: enabled)
Active: inactive (dead) since Fri 2024-09-13 16:08:01 UTC; 39s ago
TriggeredBy: ● snapd.socket
Main PID: 2948020 (code=exited, status=0/SUCCESS)

Sep 13 16:07:16 cks-master snapd[2948020]: overlord.go:276: Acquired state lock file
Sep 13 16:07:16 cks-master snapd[2948020]: daemon.go:247: started snapd/2.63+20.04ubuntu0.1 (series 16; classic) ubuntu/20.04 (amd64) linux/5.15.0-1067-gcp.
Sep 13 16:07:16 cks-master snapd[2948020]: daemon.go:340: adjusting startup timeout by 50s (pessimistic estimate of 30s plus 5s per snap)
Sep 13 16:07:16 cks-master snapd[2948020]: backends.go:58: AppArmor status: apparmor is enabled and all features are available
Sep 13 16:07:20 cks-master systemd[1]: Started Snap Daemon.
Sep 13 16:07:58 cks-master systemd[1]: Stopping Snap Daemon...
Sep 13 16:07:58 cks-master snapd[2948020]: main.go:151: Exiting on terminated signal.
Sep 13 16:08:01 cks-master snapd[2948020]: overlord.go:515: Released state lock file
Sep 13 16:08:01 cks-master systemd[1]: snapd.service: Succeeded.
Sep 13 16:08:01 cks-master systemd[1]: Stopped Snap Daemon.

Analyzing ports being used and by which processes.

root@cks-master:~# netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:46441 0.0.0.0:* LISTEN 10884/containerd
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 455/systemd-resolve
tcp 0 0 127.0.0.1:9099 0.0.0.0:* LISTEN 12372/calico-node
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 938/sshd: /usr/sbin
tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 11595/etcd
tcp 0 0 127.0.0.1:2381 0.0.0.0:* LISTEN 11595/etcd
tcp 0 0 127.0.0.1:10248 0.0.0.0:* LISTEN 11660/kubelet
tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 11808/kube-proxy
tcp 0 0 127.0.0.1:10257 0.0.0.0:* LISTEN 1594246/kube-contro
tcp 0 0 127.0.0.1:10259 0.0.0.0:* LISTEN 1594243/kube-schedu
tcp 0 0 10.128.0.6:2379 0.0.0.0:* LISTEN 11595/etcd
tcp 0 0 10.128.0.6:2380 0.0.0.0:* LISTEN 11595/etcd
tcp6 0 0 :::6443 :::* LISTEN 1604406/kube-apiser
tcp6 0 0 :::22 :::* LISTEN 938/sshd: /usr/sbin
tcp6 0 0 :::10256 :::* LISTEN 11808/kube-proxy
tcp6 0 0 :::10250 :::* LISTEN 11660/kubelet

Notice we have nothing out of the ordinary. But port 22 is available to the internet, because we're on the machine. Ideally it should only be available within the network and we'd be on a VPN to access this machine.

Let's install some FTP service to see what happens.

root@cks-master:~# apt install vsftpd -y

● vsftpd.service - vsftpd FTP server
Loaded: loaded (/lib/systemd/system/vsftpd.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2024-09-13 17:16:24 UTC; 15s ago
Main PID: 2981767 (vsftpd)
Tasks: 1 (limit: 4680)
Memory: 516.0K
CGroup: /system.slice/vsftpd.service
└─2981767 /usr/sbin/vsftpd /etc/vsftpd.conf

Sep 13 17:16:24 cks-master systemd[1]: Starting vsftpd FTP server...
Sep 13 17:16:24 cks-master systemd[1]: Started vsftpd FTP server.
root@cks-master:~#

root@cks-master:~# netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:46441 0.0.0.0:* LISTEN 10884/containerd
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 455/systemd-resolve
tcp 0 0 127.0.0.1:9099 0.0.0.0:* LISTEN 12372/calico-node
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 938/sshd: /usr/sbin
tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 11595/etcd
tcp 0 0 127.0.0.1:2381 0.0.0.0:* LISTEN 11595/etcd
tcp 0 0 127.0.0.1:10248 0.0.0.0:* LISTEN 11660/kubelet
tcp 0 0 127.0.0.1:10249 0.0.0.0:* LISTEN 11808/kube-proxy
tcp 0 0 127.0.0.1:10257 0.0.0.0:* LISTEN 1594246/kube-contro
tcp 0 0 127.0.0.1:10259 0.0.0.0:* LISTEN 1594243/kube-schedu
tcp 0 0 10.128.0.6:2379 0.0.0.0:* LISTEN 11595/etcd
tcp 0 0 10.128.0.6:2380 0.0.0.0:* LISTEN 11595/etcd
tcp6 0 0 :::6443 :::* LISTEN 1604406/kube-apiser
tcp6 0 0 :::22 :::* LISTEN 938/sshd: /usr/sbin
tcp6 0 0 :::21 :::* LISTEN 2981767/vsftpd # <<<<
tcp6 0 0 :::10256 :::* LISTEN 11808/kube-proxy
tcp6 0 0 :::10250 :::* LISTEN 11660/kubelet

# When we have :::Port it means we're listening on ALL interfaces. If the machine has a public address then yes, it's exposed.
# Notice we have the port right after the interface it's using. In the case of vsftpd it's port 21.

# Here's the process running
root@cks-master:~# ps -aux | grep vsf
root 2981767 0.0 0.0 6816 2956 ? Ss 17:16 0:00 /usr/sbin/vsftpd /etc/vsftpd.conf
root 2983246 0.0 0.0 8168 660 pts/0 S+ 17:19 0:00 grep --color=auto vsf

# if we find a process we should stop using to do hardening.
root@cks-master:~# systemctl list-units --type=service | grep vsf
vsftpd.service loaded active running vsftpd FTP server
# Remember that disabling doesn't stop what's already running
root@cks-master:~# systemctl disable vsftpd.service
Synchronizing state of vsftpd.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable vsftpd
Removed /etc/systemd/system/multi-user.target.wants/vsftpd.service.
root@cks-master:~# systemctl status vsftpd.service
● vsftpd.service - vsftpd FTP server
Loaded: loaded (/lib/systemd/system/vsftpd.service; disabled; vendor preset: enabled)
Active: active (running) since Fri 2024-09-13 17:16:24 UTC; 8min ago
Main PID: 2981767 (vsftpd)
Tasks: 1 (limit: 4680)
Memory: 516.0K
CGroup: /system.slice/vsftpd.service
└─2981767 /usr/sbin/vsftpd /etc/vsftpd.conf

root@cks-master:~# systemctl stop vsftpd.service
root@cks-master:~# systemctl status vsftpd.service
● vsftpd.service - vsftpd FTP server
Loaded: loaded (/lib/systemd/system/vsftpd.service; disabled; vendor preset: enabled)
Active: inactive (dead)

Sep 13 17:16:24 cks-master systemd[1]: Starting vsftpd FTP server...
Sep 13 17:16:24 cks-master systemd[1]: Started vsftpd FTP server.
Sep 13 17:26:11 cks-master systemd[1]: Stopping vsftpd FTP server...
Sep 13 17:26:11 cks-master systemd[1]: vsftpd.service: Succeeded.
Sep 13 17:26:11 cks-master systemd[1]: Stopped vsftpd FTP server.

If we want to find the service running on a specific port we can use lsof.

# looking for who's using port 22
# sshd process
root@cks-master:~# lsof -i :22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 938 root 3u IPv4 27062 0t0 TCP *:ssh (LISTEN)
sshd 938 root 4u IPv6 27064 0t0 TCP *:ssh (LISTEN)
sshd 2989010 root 4u IPv4 15489187 0t0 TCP cks-master.us-central1-c.c.refined-byte-432619-k6.internal:ssh->138.99.34.208:59144 (ESTABLISHED)
sshd 2989116 david 4u IPv4 15489187 0t0 TCP cks-master.us-central1-c.c.refined-byte-432619-k6.internal:ssh->138.99.34.208:59144 (ESTABLISHED)

It's also necessary to understand a bit about users in Linux and investigate them.

# current user
root@cks-master:~# whoami
root

# Here contains the system users
# Some users are created during tool installation processes, but don't have any associated shell so it's just internal use.
root@cks-master:~# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash # has shell
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
sshd:x:109:65534::/run/sshd:/usr/sbin/nologin
landscape:x:110:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:111:1::/var/cache/pollinate:/bin/false
fwupd-refresh:x:112:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
_chrony:x:113:120:Chrony daemon,,,:/var/lib/chrony:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash # has shell
david:x:1001:1002::/home/david:/bin/bash # has shell
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
dnsmasq:x:114:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
ftp:x:115:123:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
root@cks-master:~#

# logging in as ubuntu
root@cks-master:~# su ubuntu
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@cks-master:/root$ whoami
ubuntu

# can ubuntu log in as root? On this system yes.
# Let's check the bash processes we have
ubuntu@cks-master:/root$ sudo -i
# Checking by time we can analyze these bash.
root@cks-master:~# ps aux | grep bash
david 2989120 0.0 0.1 10180 5324 pts/0 Ss 17:30 0:00 -bash # my user when I opened the session
root 2990358 0.0 0.1 10568 5632 pts/0 S 17:33 0:00 -bash # when I left my user and logged in as root
ubuntu 2992167 0.0 0.1 10008 5100 pts/0 S 17:36 0:00 bash # when we logged in with ubuntu
root 2992416 0.0 0.1 10436 5464 pts/0 S 17:37 0:00 -bash # when we logged in now with root again.
root 2992600 0.0 0.0 8168 720 pts/0 R+ 17:37 0:00 grep --color=auto bash

# Let's exit the terminals and see them closing.
root@cks-master:~# exit
logout
ubuntu@cks-master:/root$ ps aux | grep bash
david 2989120 0.0 0.1 10180 5324 pts/0 Ss 17:30 0:00 -bash
root 2990358 0.0 0.1 10568 5632 pts/0 S 17:33 0:00 -bash
ubuntu 2992167 0.0 0.1 10008 5100 pts/0 S 17:36 0:00 bash
ubuntu 2992923 0.0 0.0 8168 656 pts/0 S+ 17:38 0:00 grep --color=auto bash
ubuntu@cks-master:/root$ exit
exit
root@cks-master:~# ps aux | grep bash
david 2989120 0.0 0.1 10180 5324 pts/0 Ss 17:30 0:00 -bash
root 2990358 0.0 0.1 10568 5632 pts/0 S 17:33 0:00 -bash
root 2993072 0.0 0.0 8168 660 pts/0 S+ 17:38 0:00 grep --color=auto bash

# Adding a user it takes the default shell
root@cks-master:~# adduser test
Adding user `test' ...
Adding new group `test' (1003) ...
Adding new user `test' (1002) with group `test' ...
Creating home directory `/home/test' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for test
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] y

root@cks-master:~# cat /etc/passwd | grep test
test:x:1002:1003:,,,:/home/test:/bin/bash

#test user can't become root because it's not in the sudo group
root@cks-master:~# su test
test@cks-master:/root$ sudo -i
[sudo] password for test:
test@cks-master:/root$ exit
exit

# Here's the file that defines permissions.
# Whoever is in the sudo or admin group has permission to everything.

root@cks-master:~# cat /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

# ubuntu is in the groups below
root@cks-master:~# groups ubuntu
ubuntu : ubuntu adm dialout cdrom floppy sudo audio dip video plugdev netdev lxd
# test is only in its group, that's why it couldn't do anything.
root@cks-master:~# groups test
test : test

# Adding user test to sudo group
root@cks-master:~# usermod -aG sudo test
root@cks-master:~# su test
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

# Now it was possible to escalate privilege.
test@cks-master:/root$ sudo -i
[sudo] password for test:
root@cks-master:~# groups test
test : test sudo
root@cks-master:~#