Verbessern des Datenverständnisses
Rocco Gagliardi
Wenn wir ein Stück Software einsetzen, dann sind wir alle plötzlich streng gläubig: Wir glauben dann nicht nur an die Entwickler der Software, sondern auch an alle anderen Entwickler, die Einfluss auf das komplexe System gehabt haben. Wenn wir ein Stück Software einsetzen, dann sind wir vielleicht vorsichtig, wenn es um den Netzwerkanschluss geht, wir installieren Firewalls und andere Abwehrmechanismen. Einmal im Netz, befindet sich die Software aber im Kern – Wir tendieren dazu, der Software bedingungslos zu glauben.
Es gibt verschiedene Möglichkeiten, wie praktisch sämtliche Eigenschaften einer Software im Betrieb kontrolliert werden kann. Betrachtet man die verschiedenen Sicherheitsmodelle im IT-Bereich, dann findet man Klassiker wie DAC, MAC, RBAC – und daneben auch einige exotische Varianten. Unter Linux wurde Discretionary Access Control (DAC) durch die Kernel-Extensions von SELinux/AppArmor abgelöst, die Mandatory Access Control (MAC) unterstützen. In den letzten Jahren wurden sie zu einem festen Bestandteil moderner Distributionen.
Um Zugriffe einschränken zu können, wurden Sandboxen entwickelt. Eine Sandbox ist grundsätzlich für die Entkoppelung von Programmen zuständig: Es kann das Dateisystem, Netzwerk, Ressourcen voneinander trennen.
Das Capabilities Security Model fokussiert sich auf privilegierte Benutzer. Die Vielzahl der Rechte eines Superusers werden geteilt und mit Labels versehen. Diese Labels werden dann Prozessen zugewiesen, die die entsprechenden Möglichkeiten innerhalb des Betriebssystems zulassen. Capabilities dürfen nicht als Syscalls, sondern als Sammlung von Ressourcen verstanden werden. Als Beispiel ziehen wir CAP_SYS_RAWIO
heran (benutzen Sie man 7 capabilities
):
CAP_SYS_RAWIO * Perform I/O port operations (iopl(2) and ioperm(2)); * access /proc/kcore; * employ the FIBMAP ioctl(2) operation; * open devices for accessing x86 model-specific registers (MSRs, see msr(4)); * update /proc/sys/vm/mmap_min_addr; * create memory mappings at addresses below the value specified by /proc/sys/vm/mmap_min_addr; * map files in /proc/bus/pci; * open /dev/mem and /dev/kmem; * perform various SCSI device commands; * perform certain operations on hpsa(4) and cciss(4) devices; * perform a range of device-specific operations on other devices.
seccomp-bpf ist eine Extension von seccomp, das das Filtern von Syscalls mittels einer frei konfigurierbaren Policy auf der Basis von Berkeley Packet Filter Rules zulässt. Es wird von OpenSSH und vsftpd sowie Google Chrome und Chromium verwendet. Es fungiert dabei quasi als Firewall, die bestimmt, welche Funktionalität durch den Kernel (System-Calls) für einen Prozess zur Verfügung gestellt wird. Dadurch wird die Exponiertheit des Kernels gegenüber einem Prozess eingeschränkt.
Die Anzahl der Syscalls kann variieren; auf meinem System werden 380/332[32/64] Syscalls unterstützt (benutzen Sie man 2 syscalls
and take a look into /usr/src/linux-headers-<ver>/include/uapi/asm-generic/unistd.h
zur Anzeige einer kompletten Liste).
Firejail greift auf die Funktionalität von Capabilities und Seccomp-bpf zurück, um Anwendungen in eine Sandbox zu setzen.
Nehmen wir folgendes Beispiel des Executables ping
, dessen Exponiertheit mittels der Firejail Sandbox eingeschränkt werden soll. Wir werden:
ping
genutzten Syscalls identifizierenAls ersten Schritt werden wir versuchen herauszufinden, welche Ressourcen durch ping
genutzt werden. Die grundlegenden Syscalls können wie folgt herausgefunden werden:
root@ubunthin:~# strace -qcf ping -c1 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=46 time=24.1 ms --- 8.8.8.8 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 24.110/24.110/24.110/0.000 ms % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 0.00 0.000000 0 8 read 0.00 0.000000 0 6 write 0.00 0.000000 0 35 13 open 0.00 0.000000 0 23 close 0.00 0.000000 0 23 fstat 0.00 0.000000 0 31 mmap 0.00 0.000000 0 14 mprotect 0.00 0.000000 0 1 munmap 0.00 0.000000 0 3 brk 0.00 0.000000 0 3 rt_sigaction 0.00 0.000000 0 1 rt_sigprocmask 0.00 0.000000 0 2 ioctl 0.00 0.000000 0 8 8 access 0.00 0.000000 0 1 setitimer 0.00 0.000000 0 1 getpid 0.00 0.000000 0 5 2 socket 0.00 0.000000 0 1 connect 0.00 0.000000 0 1 sendto 0.00 0.000000 0 1 recvmsg 0.00 0.000000 0 1 getsockname 0.00 0.000000 0 7 setsockopt 0.00 0.000000 0 1 getsockopt 0.00 0.000000 0 1 execve 0.00 0.000000 0 2 getuid 0.00 0.000000 0 1 setuid 0.00 0.000000 0 1 geteuid 0.00 0.000000 0 7 capget 0.00 0.000000 0 3 capset 0.00 0.000000 0 2 prctl 0.00 0.000000 0 1 arch_prctl ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000000 195 23 total
Wir können ping
innerhalb von Firejail ohne ein spezifisches Profil oder eine Konfiguration aufrufen, um minimale Sicherheit zu erreichen. Firejail lässt alle Capabilities zu, führt aber ein Blacklisting für bestimmte Syscalls durch:
root@ubunthin:/home/rcc# firejail --name=ping ping 8.8.8.8 root@ubunthin:/home/rcc# firejail --list 11971:rcc:firejail --name=ping ping 8.8.8.8 root@ubunthin:/home/rcc# firejail --seccomp.print=ping SECCOMP Filter: VALIDATE_ARCHITECTURE EXAMINE_SYSCAL UNKNOWN ENTRY!!! UNKNOWN ENTRY!!! UNKNOWN ENTRY!!! BLACKLIST 165 mount BLACKLIST 166 umount2 BLACKLIST 101 ptrace BLACKLIST 246 kexec_load BLACKLIST 320 kexec_file_load BLACKLIST 304 open_by_handle_at BLACKLIST 303 name_to_handle_at BLACKLIST 175 init_module BLACKLIST 313 finit_module BLACKLIST 174 create_module BLACKLIST 176 delete_module BLACKLIST 172 iopl BLACKLIST 173 ioperm BLACKLIST 251 ioprio_set BLACKLIST 167 swapon BLACKLIST 168 swapoff BLACKLIST 103 syslog BLACKLIST 310 process_vm_readv BLACKLIST 311 process_vm_writev BLACKLIST 139 sysfs BLACKLIST 156 _sysctl BLACKLIST 159 adjtimex BLACKLIST 305 clock_adjtime BLACKLIST 212 lookup_dcookie BLACKLIST 298 perf_event_open BLACKLIST 300 fanotify_init BLACKLIST 312 kcmp BLACKLIST 248 add_key BLACKLIST 249 request_key BLACKLIST 250 keyctl BLACKLIST 134 uselib BLACKLIST 163 acct BLACKLIST 154 modify_ldt BLACKLIST 155 pivot_root BLACKLIST 206 io_setup BLACKLIST 207 io_destroy BLACKLIST 208 io_getevents BLACKLIST 209 io_submit BLACKLIST 210 io_cancel BLACKLIST 216 remap_file_pages BLACKLIST 237 mbind BLACKLIST 239 get_mempolicy BLACKLIST 238 set_mempolicy BLACKLIST 256 migrate_pages BLACKLIST 279 move_pages BLACKLIST 278 vmsplice BLACKLIST 161 chroot BLACKLIST 184 tuxcall BLACKLIST 169 reboot BLACKLIST 180 nfsservctl BLACKLIST 177 get_kernel_syms RETURN_ALLOW root@ubunthin:/home/rcc# firejail --caps.print=ping chown - enabled dac_override - enabled dac_read_search - enabled fowner - enabled fsetid - enabled kill - enabled setgid - enabled setuid - enabled setpcap - enabled linux_immutable - enabled net_bind_service - enabled net_broadcast - enabled net_admin - enabled net_raw - enabled ipc_lock - enabled ipc_owner - enabled sys_module - enabled sys_rawio - enabled sys_chroot - enabled sys_ptrace - enabled sys_pacct - enabled sys_admin - enabled sys_boot - enabled sys_nice - enabled sys_resource - enabled sys_time - enabled sys_tty_config - enabled mknod - enabled lease - enabled audit_write - enabled audit_control - enabled setfcap - enabled mac_override - enabled mac_admin - enabled syslog - enabled wake_alarm - enabled block_suspend - enabled audit_read - enabled
Beim Durchgehen der Capabilities fragt sich, warum ping
das Recht haben soll, einen Node auf dem Dateisystem zu erstellen. Grundsätzlich können wir sämtliche Capabilities bis auf CAP_NET_RAW
entfernen, um alle unnötigen Zugriffe einzuschränken:
CAP_NET_RAW * use RAW and PACKET sockets; * bind to any address for transparent proxying.
Nun wieder Firejail starten:
root@ubunthin:/home/rcc# firejail --name=ping --caps.keep=net_raw ping 8.8.8.8 root@ubunthin:/home/rcc# firejail --list 12121:rcc:firejail --name=ping --caps.keep=net_raw ping 8.8.8.8 root@ubunthin:/home/rcc# firejail --caps.print=ping ... net_admin - disabled net_raw - enabled ipc_lock - disabled ...
Wir haben alle Capabilities bis auf CAP_NET_RAW
entfernen lassen, wodurch der Aufruf der entsprechenden Syscalls verboten wird. Dennoch pflegt ping
nach wie vor 23 Syscalls einzusetzen. Mittels seccomp-bpf ist es nun möglich, granulare Filter durchzusetzen und so eine Minimierung der Syscalls zu etablieren. Hierbei wird von einer Blacklist auf eine Whitelist gewechselt.
Um die Syscalls in die Whitelist zu übertragen, die von ping
genutzt können werden sollen, wird ein strace auf die erforderlichen Syscalls angesetzt. Ein Blick in Syslog zeigt dann die Resultate:
root@ubunthin:/home/rcc# firejail --caps.keep=net_raw --shell=none --noprofile --debug --seccomp.keep=read,write,open,close,fstat,mmap,mprotect,munmap,brk,rt_sigaction,rt_sigprocmask,ioctl,access,setitimer,getpid,socket,connect,sendto,recvmsg,getsockname,setsockopt,getsockopt,execve,getuid,setuid,geteuid,capget,capset,prctl,arch_prctl,setresuid,setresgid,getgid,fcntl,clone,set_robust_list,stat,nanosleep,wait4,getdents,exit_group ping -c1 8.8.8.8
Syslog reklamiert den letzten Syscall als Problem (blocked by Firejail):
Aug 7 21:09:57 ubunthin firejail[28419]: firejail --shell=none --noprofile --seccomp.keep=read,write,open,close,fstat,mmap,mprotect,munmap,brk,rt_sigaction,rt_sigprocmask,ioctl,access,setitimer,getpid,socket,connect,sendto,recvmsg,getsockname,setsockopt,getsockopt,execve,getuid,setuid,geteuid,capget,capset,prctl,arch_prctl,setresuid,setresgid,getgid,fcntl --debug ping -c1 8.8.8.8 Aug 7 21:09:58 ubunthin kernel: [98202.176765] audit: type=1326 audit(1502132998.041:55): auid=1000 uid=0 gid=0 ses=2 pid=28420 comm="firejail" exe="/usr/bin/firejail" sig=31 arch=c000003e syscall=56 compat=0 ip=0x7ff72e5ca40a code=0x0 Aug 7 21:09:58 ubunthin firejail[28419]: exiting...
In diesem Fall versucht ping
auf Syscall 56 zuzugreifen, der nicht in der Whitelist ist, wodurch Firejail den Prozess killt. Den Namen eines Syscalls anhand dessen Nummer kann mit folgender Eingabe herausgefunden werden:
root@ubunthin:/home/rcc# firejail --debug-syscalls | grep 56 56 - clone
Die Whitelist der Syscalls muss um clone
and retry
erweitert werden. Somit wird setresuid,setresgid,getgid,fcntl,clone,set_robust_list,stat,nanosleep,wait4,getdents,exit_group
hinzugefügt:
root@ubunthin:/home/rcc# firejail --caps.keep=net_raw --shell=none --noprofile --debug --seccomp.keep=read,write,open,close,fstat,mmap,mprotect,munmap,brk,rt_sigaction,rt_sigprocmask,ioctl,access,setitimer,getpid,socket,connect,sendto,recvmsg,getsockname,setsockopt,getsockopt,execve,getuid,setuid,geteuid,capget,capset,prctl,arch_prctl,setresuid,setresgid,getgid,fcntl,clone,set_robust_list,stat,nanosleep,wait4,getdents,exit_group ping -c1 8.8.8.8 Command name #ping# DISPLAY :0, 0 Enabling IPC namespace Using the local network stack Parent pid 28503, child pid 28504 The new log directory is /proc/28504/root/var/log Initializing child process Host network configured PID namespace installed Mounting tmpfs on /run/firejail/mnt directory Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr, /etc, /var Mounting tmpfs on /dev/shm Mounting tmpfs on /var/lock Mounting tmpfs on /var/tmp Mounting tmpfs on /var/log Mounting tmpfs on /var/lib/dhcp Mounting tmpfs on /var/lib/snmp Mounting tmpfs on /var/lib/sudo Create the new utmp file Mount the new utmp file Remounting /proc and /proc/sys filesystems Remounting /sys directory Disable /sys/firmware Disable /sys/hypervisor Disable /sys/module Disable /sys/power Disable /sys/kernel/debug Disable /sys/kernel/vmcoreinfo Disable /sys/kernel/uevent_helper Disable /proc/sys/fs/binfmt_misc Disable /proc/sys/kernel/core_pattern Disable /proc/sys/kernel/modprobe Disable /proc/sysrq-trigger Disable /proc/sys/kernel/hotplug Disable /proc/sys/vm/panic_on_oom Disable /proc/irq Disable /proc/bus Disable /proc/sched_debug Disable /proc/timer_list Disable /proc/timer_stats Disable /proc/kcore Disable /proc/kallsyms Disable /lib/modules Disable /usr/lib/debug Disable /boot Disable /dev/port Disable /sys/fs DISPLAY :0, 0 Set caps filter 2000 Ending syscall filter SECCOMP Filter: VALIDATE_ARCHITECTURE EXAMINE_SYSCAL UNKNOWN ENTRY!!! UNKNOWN ENTRY!!! UNKNOWN ENTRY!!! WHITELIST 105 setuid WHITELIST 106 setgid WHITELIST 116 setgroups WHITELIST 32 dup WHITELIST 0 read WHITELIST 1 write WHITELIST 2 open WHITELIST 3 close WHITELIST 5 fstat WHITELIST 9 mmap WHITELIST 10 mprotect WHITELIST 11 munmap WHITELIST 12 brk WHITELIST 13 rt_sigaction WHITELIST 14 rt_sigprocmask WHITELIST 16 ioctl WHITELIST 21 access WHITELIST 38 setitimer WHITELIST 39 getpid WHITELIST 41 socket WHITELIST 42 connect WHITELIST 44 sendto WHITELIST 47 recvmsg WHITELIST 51 getsockname WHITELIST 54 setsockopt WHITELIST 55 getsockopt WHITELIST 59 execve WHITELIST 102 getuid WHITELIST 105 setuid WHITELIST 107 geteuid WHITELIST 125 capget WHITELIST 126 capset WHITELIST 157 prctl WHITELIST 158 arch_prctl WHITELIST 117 setresuid WHITELIST 119 setresgid WHITELIST 104 getgid WHITELIST 72 fcntl WHITELIST 56 clone WHITELIST 273 set_robust_list WHITELIST 4 stat WHITELIST 35 nanosleep WHITELIST 61 wait4 WHITELIST 78 getdents WHITELIST 231 exit_group KILL_PROCESS Save seccomp filter, size 784 bytes seccomp enabled Username root, no supplementary groups starting application LD_PRELOAD=(null) execvp argument 0: ping execvp argument 1: -c1 execvp argument 2: 8.8.8.8 Child process initialized PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. monitoring pid 2 64 bytes from 8.8.8.8: icmp_seq=1 ttl=45 time=28.6 ms --- 8.8.8.8 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 28.614/28.614/28.614/0.000 ms Sandbox monitor: waitpid 2 retval 2 status 0 Parent is shutting down, bye...
Jetzt können wir ein Profil für ping
erstellen, wodurch die Exponiertheit im System gänzlich reduziert wird. Falls ping
andere Zugriffe anstreben will, wird es unmittelbar gekillt.
Das Security In-Depth Paradigma erfordert verschiedene Schichten von Security-Controls. Falls eine versagt, kann die andere die Anforderungen durchsetzen.
Firejail kann als zusätzliche Line of Defense genutzt werden, vor allem im Zusammenhang mit Webbrowsern. Es kommt mit einigen vordefinierten Profilen daher und lässt sich so relativ einfach für zusätzliche Anwendungen einsetzen.
Ich benutze Firejail für Browsing, Software-Analyse und ausgewählte temporäre Einstellungen (z.B. DNS-spezifisch), um Installationen simulieren zu können.
Der Unterschied zwischen Sandboxen und Containern kann auf das Dateisystem reduziert werden:
Eine Sandbox funktioniert auf einem bestehenden Dateisystem, während ein Container ein eigenes Dateisystem hat.
Der Fokus auf Sicherheit der beiden Technologien unterscheidet sich:
Sandboxing fokussiert sich vollständig auf Sicherheit, während Container in erster Linie für Virtualisierung und Entwicklung eingesetzt wird.
In jedem Fall ist das eingesetzte Sicherheitsmodell das Gleiche. Das Verständnis für seccomp-bpf und Capabilities hilft dabei, ein Container-Environment (aka. Docker) absichern zu können.
Das Absichern eines Computers endet nicht bei der Netzwerkschnittstelle. Einmal installierte und als vertrauenswürdig verstandene Software kann nach Belieben auf eine Vielzahl von Ressourcen zugreifen. Selbst dann, wenn es nicht erforderlich wäre (denken Sie dabei nur mal an X).
Diese Überexponiertheit muss vor allem bei Container-Technologien eine hohe Kritikalität beigemessen werden. Dort, wo Grenzen zwischen Ressourcen und Virtuellen Ressourcen verschwimmen.
Durch den Einsatz von Firejail kann ein Quickwin für sämtliche Applikationen, vor allem Browser ohne Sandboxing, erreicht werden. Es ist einfach zu nutzen und zu konfigurieren – Und der Impact auf das System ist sehr gering.
Andere empfohlene Tools:
Unsere Spezialisten kontaktieren Sie gern!
Rocco Gagliardi
Rocco Gagliardi
Rocco Gagliardi
Rocco Gagliardi
Unsere Spezialisten kontaktieren Sie gern!