Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
When you run a container as privileged these are the protections you are disabling:
Mount /dev
In a privileged container, all the devices can be accessed in /dev/. Therefore you can escape by mounting the disk of the host.
# docker run --rm -it alpine shls/devconsolefdmqueueptmxrandomstderrstdouturandomcorefullnullptsshmstdinttyzero
# docker run --rm --privileged -it alpine shls/devcachefilesmapperportshmtty24tty44tty7consolemempsauxstderrtty25tty45tty8coremqueueptmxstdintty26tty46tty9cpunbd0ptsstdouttty27tty47ttyS0[...]
Read-only kernel file systems
Kernel file systems provide a mechanism for a process to modify the behavior of the kernel. However, when it comes to container processes, we want to prevent them from making any changes to the kernel. Therefore, we mount kernel file systems as read-only within the container, ensuring that the container processes cannot modify the kernel.
# docker run --rm --privileged -it alpine shmount|grep'(ro'
Masking over kernel file systems
The /proc file system is selectively writable but for security, certain parts are shielded from write and read access by overlaying them with tmpfs, ensuring container processes can't access sensitive areas.
tmpfs is a file system that stores all the files in virtual memory. tmpfs doesn't create any files on your hard drive. So if you unmount a tmpfs file system, all the files residing in it are lost for ever.
# docker run --rm -it alpine shmount|grep/proc.*tmpfstmpfson/proc/acpitypetmpfs (ro,relatime)tmpfson/proc/kcoretypetmpfs (rw,nosuid,size=65536k,mode=755)tmpfson/proc/keystypetmpfs (rw,nosuid,size=65536k,mode=755)
# docker run --rm --privileged -it alpine shmount|grep/proc.*tmpfs
Linux capabilities
Container engines launch the containers with a limited number of capabilities to control what goes on inside of the container by default. Privileged ones have all the capabilities accesible. To learn about capabilities read:
# docker run --rm -it alpine shapkadd-Ulibcap; capsh--print[...]Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=eip
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
[...]
# docker run --rm --privileged -it alpine shapkadd-Ulibcap; capsh--print[...]Current:=eipcap_perfmon,cap_bpf,cap_checkpoint_restore-eipBounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
[...]
You can manipulate the capabilities available to a container without running in --privileged mode by using the --cap-add and --cap-drop flags.
Seccomp
Seccomp is useful to limit the syscalls a container can call. A default seccomp profile is enabled by default when running docker containers, but in privileged mode it is disabled. Learn more about Seccomp here:
# docker run --rm -it alpine shgrepSeccomp/proc/1/statusSeccomp:2Seccomp_filters:1
# docker run --rm --privileged -it alpine shgrepSeccomp/proc/1/statusSeccomp:0Seccomp_filters:0
# You can manually disable seccomp in docker with--security-optseccomp=unconfined
Also, note that when Docker (or other CRIs) are used in a Kubernetes cluster, the seccomp filter is disabled by default
AppArmor
AppArmor is a kernel enhancement to confine containers to a limited set of resources with per-program profiles. When you run with the --privileged flag, this protection is disabled.
# You can manually disable seccomp in docker with--security-optapparmor=unconfined
SELinux
Running a container with the --privileged flag disables SELinux labels, causing it to inherit the label of the container engine, typically unconfined, granting full access similar to the container engine. In rootless mode, it uses container_runtime_t, while in root mode, spc_t is applied.
# You can manually disable selinux in docker with--security-optlabel:disable
What Doesn't Affect
Namespaces
Namespaces are NOT affected by the --privileged flag. Even though they don't have the security constraints enabled, they do not see all of the processes on the system or the host network, for example. Users can disable individual namespaces by using the --pid=host, --net=host, --ipc=host, --uts=host container engines flags.
# docker run --rm --privileged -it alpine shps-efPIDUSERTIMECOMMAND1root0:00sh18root0:00ps-ef
By default, container engines don't utilize user namespaces, except for rootless containers, which require them for file system mounting and using multiple UIDs. User namespaces, integral for rootless containers, cannot be disabled and significantly enhance security by restricting privileges.
Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!