针对docker系统的渗透测试方法

翻译总结于:《A Methodology for Penetration Testing Docker Systems》

    文章从两个攻击模型进行分析,结合错误配置和已知漏洞对docker渗透测试进行总结归纳,并给出了一份docker渗透测试检查清单。

一 攻击模型

    作者讨论了两种情况:在容器内和在容器外。在容器内部,攻击者会聚焦在逃逸隔离(即容器逃逸)。在容器外部,即宿主机上,攻击者还没有主机特权,这时候攻击者将会使用Docker(即Docker daemon攻击)来获得权限。


攻击内容可视化

    容器逃逸重点在攻击和绕过隔离和保护机制,其中又可分成两种:一种是从容器逃逸到主机(CVE-2017-7308),另一种是从容器逃逸到另一个容器获取其中数据。


容器逃逸两种情景

    在Docker守护程序攻击中,攻击者不会攻击docker或者docker隔离,而是使用docker来执行恶意操作。因为Docker Daemon需要以root身份运行,攻击者恶意控制Docker Daemon后能以root权限执行操作。
Docker Daemon攻击:非特权进程B通过Docker Daemon来访问进程A中的特权数据

二 Docker中的已知漏洞

    作者从错误配置和安全漏洞两个角度对上述两个场景中的安全问题进行了梳理。漏洞问题是自身程序问题,错误配置更多的是用户使用问题。

1、错误配置

    前两个错误配置与在主机上执行的Docker Daemon有关,其他错误配置与从容器内执行的容器逃逸攻击有关。


misconfigurations
  • A.Docker Permissions
    (1)没有sudo权限的用户添加到docker用户组后,该用户可以通过运行docker挂载文件来读取host上的敏感信息甚至对系统进行改变。
# 没有sudo权限的用户但在docker用户组中
(host)$ sudo -v
(host)$ groups | grep -o docker
# 用户可以通过运行docker挂载文件来读取host上的敏感信息
(host)$ docker run -it --rm -v /:/host ubuntu:latest bash
(cont)# grep admin /host/etc/shadow

(2)可读写的Docker Socket:一些管理员设置了所有用户的读写权限,给了所有用户Docker Daemon的权限,尽管用户不在docker group也能使用docker。

# 所有用户对Docker Daemon都有读写权限(666)
(host)$ groups | grep -o docker
(host)$ ls -l /var/run/docker.sock
# 用户可以通过运行docker挂载文件来读取host上的敏感信息
(host)$ docker run -it --rm -v /:/host ubuntu:latest bash
(cont)# grep admin /host/etc/shadow

(3)setuid bit:系统管理员在docker二进制文件上设置setuid位。setuid位是Unix中的权限位,它允许用户运行二进制文件而不是其本身作为二进制文件的所有者。如果为docker二进制文件错误配置了setuid位,那么用户将能够以root身份执行docker。

# 允许用户运行docker二进制文件(chmod +s)
(host)$ sudo -v
(host)$ groups | grep -o docker
(host)$ ls -halt /usr/bin/docker
# 用户可以运行docker文件
(host)$ docker run -it --rm -v /:/host ubuntu:latest bash
(cont)# grep admin /host/etc/shadow
  • B.Readable Configuration Files
        docker用户为了减少docker设置环境的复杂性,会使用docker-compose等保存一些必要的设置。但这些配置文件经常包含一些敏感信息,如果文件权限配置不当,可能会造成信息泄露。
    (1).docker/config.json:.docker/config.json中会缓存用户登录到仓库的凭证。
    (2)docker-compose.yaml:docker-compose.yaml文件中会包含一些敏感信息如密码等。

  • C.Privileged Mode:使用特权模式启动容器,可以获取大量设备文件访问权限。因为当管理员执行docker run —privileged时,Docker容器将被允许访问主机上的所有设备,并可以执行mount命令进行挂载。当控制使用特权模式启动的容器时,docker管理员可通过mount命令将外部宿主机磁盘设备挂载进容器内部,获取对整个宿主机的文件读写权限,此外还可以通过写入计划任务等方式在宿主机执行命令。该文章中作者还介绍了特权模式下滥用cgroups特性的一个例子。

  • D.Capabilities
        Docker容器在启动时只有最小的Capabilities,但是在运行时添加的额外的Capabilities可能会给容器执行某些操作的权限,其中一些操作允许docker逃逸。
    (1)CAP_SYS_ADMIN。
    (2)CAP_DAC_READ_SEARCH:这个功能允许进程对容器进行转义,见https://medium.com/@fun_cuddles/docker-breakout-exploit- analysis-a274fff0e6b3。

  • E.Docker Socket
        Docker Socket(即/var/run/docker.sock)是客户端与Docker Daemon通信的方式。每当用户执行docker client命令时,docker客户端就会向socket发送一个http请求。用户不使用docker客户端也可以直接向套接字发送http请求。因此,一些错误配置socket的方法也会带来很多安全危险。

# 使用docker客户端
docker ps -a
# 直接向socket发送http请求
curl --unix-socket /var/run/docker.sock -H 'Content-Type: application/json' "http://localhost/containers/json?all=1"

(1)Container Escape Using the Docker Socket:如果/var/run/docker.sock作为volume挂载到容器上,那么容器中的进程可以完全访问主机上的docker。
(2)Sensitive Information:当容器可以访问/var/run/docker.sock时,用户可以查看现有容器的配置,其中可能包含一些敏感信息。
(3)Remote Access:如果没有配置docker API只监听本地主机,那么网络上的每个主机都可以访问docker,攻击者可以利用这种错误配置启动其他容器。

  • F.iptables Bypass
        linux内核有一个名为Netfilter的内置防火墙,可以配置iptables程序。这个防火墙由存储在表中的多个规则链组成。每个表都有不同的用途,例如,有一个用于地址转换的nat表和一个用于流量过滤的filter表。每个表都有有序的规则链,这些规则链也有不同的用途。例如,filter表中有分别用于所有传出和传入流量的output和input链。可以使用一个名为iptables的程序来配置这些规则。
        当docker daemon启动时,它会建立自己的链和规则来创建隔离网络。可以使用docker绕过防火墙规则。详见https://www.cnblogs.com/qjfoidnh/p/11567309.html

  • G.ARP Spoofing
        默认情况下,所有docker容器都添加到同一个网桥网络中,且docker容器还接收CAP_NET_RAW功能,这允许可以创建原始数据包。因此,默认情况下,容器能够ARP欺骗其他容器。2019 KCon:针对Docker容器网络的ARP欺骗与中间人攻击.pdf

2、软件漏洞

    文章中列举了一些最近的且已完全公开的可能在渗透测试期间使用的bug。
(1)CVE-2019-16884
(2)CVE-2019-13139
(3)CVE-2019-5736
(4)CVE-2019-5021
(5)CVE-2018-15664
(6)CVE-2018-9862
(7)CVE-2016-3697

三 docker下的渗透测试

    首先需要对目标系统执行侦查来收集数据,然后使用收集到的信息来识别弱点和漏洞。

1、手动发现漏洞

  • A.检测是否处于容器中
        首先,需要判断系统是否处于docker容器中。
    (1)检查/.dockerenv文件是否存在。
    (2)Control Group,检查/proc/1/cgroup内是否包含"docker"等字符串。
    (3)Running Processes,进程的数量和pid为1的进程可以很好地指示是否在容器中。
    (4)Available Libraries and Binaries,如果我们看到大量丢失的包、二进制文件或库,说明是在容器中运行的。
    (5)检查是否存在container环境变量。
  • B.在容器内的渗透测试
        在容器内执行代码,攻击者着重于容器逃逸。docker daemon是以root权限运行的,因此容器逃逸后就可以获得对主机的root权限。
    (1)用户识别:第一步需要确定是否是特权用户并识别其他用户。
# 使用id查看当前用户
(cont)# id
# 查看/etc/passwd查看所有用户
(cont)# cat /etc/passwd

(2)识别容器的操作系统(或者Docker镜像)

# 所有linux发行版都有/etc/os-release,其中包含了正在运行的操作系统的信息
docker run -it --rm centos:latest cat /etc/os-release
# 还可以看看容器正在运行的进程
docker exec database ps -A -o pid,cmd

(3)识别主机操作系统:因为容器使用宿主的内核,所以可以使用内核版本来标识宿主信息,从而检测一些内核利用。

docker run -it --rm alpine:latest cat /etc/os-release

(4)读环境变量:环境变量是启动容器时与容器通信信息的一种方式。当一个容器启动时,环境变量被传递给它,这些变量通常包含密码和其他敏感信息。

(host)$ docker run --rm -e MYSQL_ROOT_PASSWORD=supersecret -- name=database mariadb:latest
(host)$ docker exec -it database bash 
# 使用env命令列出在docker中设置的所有环境变量,或者查看进程的/proc/lib/environment文件
(cont)# env

(5)检查Capabilities:通过查看/proc/self/status来查看容器的内核功能。其中CapEff是当前功能的值,可以使用capsh工具从十六进制值获取功能列表。可以使用这个来检查是否有可以用来容器逃逸的功能。

(cont)# grep Cap /proc/self/status
CapInh: 00000000a80425fb  # CapInh可继承能力是允许子进程获得的功能
CapPrm: 00000000a80425fb  # CapPrm允许能力是一个进程可以使用的最大功能
CapEff: 00000000a80425fb  # CapEff是进程有的功能
CapBnd: 00000000a80425fb # CapBnd是调用树中允许的功能
CapAmb: 0000000000000000 # CapAmb是非root子进程可以继承的功能

(host)$ capsh --decode=00000000a80425fb 0x00000000a80425fb=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

(6)检查特权模式:如果容器以特权模式运行,它将获得所有功能,因此可以通过查看能力(0000003fffffffff是所有能力的表示)来检查是否以特权模式运行进程。

(host)$ docker run -it --rm --privileged ubuntu:latest grep CapEff /proc/1/status
CapEff: 0000003fffffffff
(host)$ capsh --decode=0000003fffffffff 0x0000003fffffffff=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

(7)检查volumes:卷中可能包含敏感信息,可以通过查看挂载的文件系统位置来查看。

(host)$ docker run -it --rm -v /tmp:/host/tmp ubuntu cat /proc /mounts
overlay / overlay...

(8)检查挂载的docker socket

# 查看挂载
(host)$ docker run -it --rm -v /var/run/docker.sock:/var/run/
docker.sock ubuntu grep docker.sock /proc/mounts
tmpfs /run/docker.sock tmpfs rw,nosuid,noexec,relatime,size
   =792244k,mode=755 0 0
# 或者寻找类似于docker.sock名称的文件
(host)$ docker run -it --rm -v /var/run/docker.sock:/var/run/
docker.sock ubuntu find . -name "docker.sock" / /run/docker.sock

(9)检查网络配置

# 查看/etc/hosts/发现可访问地址
(host)$ docker run -it --rm alpine tail -n1 /etc/hosts
172.17.0.2 e0e6b96367db
# nmap查看容器网络
(host)$ docker run -it --rm ubuntu bash (cont)# apt update
(cont)# apt install nmap
(cont)# nmap -sn -PE 172.17.0.0/16 ...
Nmap scan report for 172.17.0.1
  • C.在运行有docker的主机上的渗透测试
    (1)Docker版本
# 检查docker版本,查找其对应版本是否有可用的cve
(host)$ docker -v

(2)拥有docker使用权限的用户

# 1 查找对/var/run/docker.sock有读写权限的用户
# 2 查看/etc/group查找在docker组中的用户
$ grep docker /etc/group
# 3 拥有sudo权限的用户
# 4 docker client上设置了setuid位
(host)$ ls -l $(which docker)
-rwxr-xr-x 1 root root 88965248 nov 13 08:28 /usr/bin/docker
(host)# chmod +s $(which docker)
(host)$ ls -l $(which docker)
-rwsr-sr-x 1 root root 88965248 nov 13 08:28 /usr/bin/docker

(3)配置:/etc/docker/daemon或/etc/default/docker
(4)可获得的镜像和容器

# 列出所有可用的镜像
docker images -a
# 列出所有容器
(host)$ docker ps -a --no-trunc --format="{{.Names}} {{.
Command}} {{.Image}}"
# 查看容器相关信息:传递给容器的环境变量
(host)$ docker run --rm -e MYSQL_ROOT_PASSWORD=supersecret -- name=database mariadb:latest
(host)$ docker inspect database | jq -r '.[0].Config.Env'
# 查看容器相关信息:volumes
(host)$ docker inspect database | jq -r '.[0].HostConfig.Binds'

(5)iptables规则:使用 iptables -vnL 和 iptables -t nat -vnL,可以看到默认表filter和nat的规则。所有关于docker容器的防火墙规则都在filter中的docker -user链中设置。

2、可用的工具—实现自动化部分评估

tools

四 checklist

Are We Running in a Container?
Finding Vulnerabilities in Containers 1
Finding Vulnerabilities in Containers 2
Finding Vulnerabilities on the Host 1
Finding Vulnerabilities on the Host 2
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容