一. 概述

Docker提供了一种快速、灵活和可移植的方式来构建和交付应用程序,Docker镜像仓库使得用户能够更加方便地存储和共享Docker镜像。然而,镜像泄露敏感信息事件屡有发生,因此,在使用Docker镜像仓库过程中,我们应该始终关注其安全性,并且采取必要的措施以保护敏感信息和数据的安全。

Docker镜像仓库分为公共镜像仓库和私有镜像仓库,公共镜像仓库主要是由一些官方机构提供给用户免费使用的存储和共享Docker镜像的平台,常见的公共镜像仓库有Docker Hub,阿里云镜像仓库、Google镜像仓库等,都包含了广泛的公共镜像供用户使用。私有镜像仓库是用户自己搭建用于存储和共享Docker镜像的平台。用户可以在私有镜像仓库中存储自己的镜像,并控制访问权限,使其只能被特定的用户或组织使用。常见的私有镜像仓库有Harbor和Docker Registry,其中Harbor提供了企业级的镜像仓库管理功能,包括镜像复制、安全扫描等功能。

本文主要对公共镜像仓库Docker Hub、私有镜像仓库Harbor、Docker Registry的数据泄露风险进行了分析。

文中涉及到的技术仅供教学、研究使用,禁止用于非法用途,文中所涉及漏洞验证,均使用本地服务器。

二. Docker Hub镜像泄露分析

2.1Docker Hub镜像密钥泄露情况

今年7月,德国亚琛工业大学(RWTH-Aachen University)的研究人员在Docker Hub上发现了数万个暴露了敏感数据、源代码的镜像[1]。他们在分析了337171个镜像,包含了1647300层的复杂数据集后,最终在28621个镜像(占比8.5%)中发现了52107个有效的私钥和3158个API密钥。

图1 研究人员最终获取的敏感信息汇总

从图1中可以看出,私钥的泄露可能会导致中间人攻击、身份伪造等后果,主要私钥类型有PEM Private Key、PEM Private Key Block等。API敏感信息主要包括公有云服务凭证、金融支付凭证、社交媒体凭证和物联网凭证,其中泄露的公有云服务凭证类型的包括了阿里云、亚马逊云、Azure等多个大型公有云服务,金融支付凭证则包含了亚马逊MWS、Bitfinex、Coinbase等大型国外交易网站或加密货币的交易凭证,社交媒体的凭证主要包含了Facebook和Twitter,物联网设备的凭证数量相对较少,但也可能会导致物联网设备数据被窃取的严重后果,例如汽车位置信息的跟踪定位。

2.2 暴露敏感信息分析

另外,德国亚琛工业大学的研究人员还对暴露的敏感信息进行了分析,确定其实际用途进而了解所暴露的攻击面的大小。结果根据泄露的密钥发现了22082个证书,其中还包括7546个私有签名证书和1060个公共CA签名证书,研究者对这些CA证书进行了深入分析后,发现仍有141份证书有效。

图2 Docker Hub泄露信息类型汇总

研究人员进一步通过Censys数据库[2]对密钥进行分析,发现了存在275269个主机使用了这些泄露的密钥。如图2所示,其中包括了可能传输物联网敏感数据的MQTT资产以及AMQP资产,存储重要敏感数据的FTP资产、PostgreSQL资产和MYSQL资产,还包括上万台用于SMTP、POP3、IMAP等邮件系统服务器。

对于SSH服务器和Kubernetes服务器,泄露的密钥可能会带来远程恶意shell访问、僵尸网络扩张等威胁。

(备注:基于白帽原则研究人员并未对暴露的服务验证其密钥)

Docker Hub免费版只支持公开镜像的托管,因此只能使用其公共镜像仓库的功能。如果用户缺乏安全意识,将带有敏感信息的镜像上传至公共镜像仓库,将导致镜像和敏感信息泄露的风险。因此,建议避免将存储敏感信息的镜像上传至Docker Hub公共镜像仓库,而是选择自建Harbor或Docker Registry私有镜像仓库。同时,使用自建私有镜像仓库时也需要注意安全性。接下来的内容将分析私有镜像仓库的安全性。

三. Harbor镜像泄露分析

3.1 Harbor组件公网暴露情况

截至2023年11月,在Shodan上可以检测到12379个暴露的Harbor资产,如图3所示,其中检测到国内3377个Harbor资产,国外9002个资产,值得一提的是,在2022年4月,国内的Harbor资产暴露数量仅为2557[4],在近一年半的时间内增长了820个,增长率为32%。这些资产都是暴露在公网上,且大量资产都处于存活状态。

图3 Harbor资产在Shodan上扫描的结果

3.2 镜像泄露风险分析

既然Harbor在公网上暴露了这么多资产,且暴露资产的数量增长如此迅猛,公网上的Harbor资产是否也存在镜像泄露风险呢?本文将逐步进行分析。

3.2.1 CVE-2022-46463导致镜像泄露过程验证

提到Harbor镜像泄露风险,不得不说其近年来频频爆出漏洞,如CVE-2022-46463,NVD对该漏洞的描述如图4所示[5],我们可以得出攻击者可在无认证情况下,访问公开和私有的镜像仓库。

图4 NVD对CVE-2022-46463的描述

虽然图4的公告中明确指出了该漏洞所影响的范围是2.5.3以下的版本,但经过实际安装测试,笔者发现截至2023年11月,Harbor最新Release版本2.9.1,以及之前发布的2.8.4及更老的版本,依然还存在该镜像泄露风险。利用该Harbor特性获取镜像信息的验证过程如下:

首先在服务器上安装harbor目前的最新release版本2.9.1,如图5所示。

图5 测试环境的Harbor版本为2.9.1

之后任意上传测试镜像至Harbor,并将其设置为公开,如图6、图7所示。

图6 将测试镜像打标签,并上传到Harbor

图7 Harbor上可以查询到该镜像

最后,在另外一台服务器上,依然可以现通过Harbor的API接口获取服务器上存储的镜像信息,再进一步获取某个镜像的digest等具体信息后,可以组装出该镜像的拉取命令,并对该镜像进行拉取,结果成功拉取了该测试镜像。具体过程如图8到图10所示。

图8 通过CVE-2022-46463发现了上传的镜像仓库名称

图9 通过Harbor的API接口进一步获取该镜像的digest

图10 通过镜像的digest组装出镜像拉取命令,并成功拉取该镜像

上述过程是在没有任何认证前提下,从目前最新Release版本(2.9.1)Harbor项目中获取镜像信息的过程,可以看出我们能够获取Harbor私有仓库中被设置为“公开”的镜像仓库的信息,甚至能够进行拉取。

行文至此,想必读者一定会好奇,为何如此严重的漏洞,官方迟迟不修复呢?

3.2.2 “假漏洞”乌龙事件

细心一点的读者可以发现,NVD对该漏洞的描述(如图4)中最后的NOTE对该漏洞做出了补充说明:即官方认为这个“漏洞”是Harbor的一个特性。

官方具体的回应如图11所示。

图11 Harbor官方对此漏洞的回复

官方回应明确指出,他们不认为公开的CVE-2022-46463是Harbor的一个漏洞,而是Harbor官方文档中所明确定义的特性之一,即用户可以设置一些镜像为公开,该特性导致Harbor上的所有被设置为公开的项目都通过相应的API接口被列举,获取详细信息,甚至被拉取。

笔者在测试过程中,确实发现在新建项目时可以对项目的访问级别进行勾选,如图12所示。

图12 新建项目界面

而且,在访问级别后面的说明也对项目公开做出了详细且明确的描述,当项目设置为公开时,任何人都有该项目下的读权限,且命令行用户不需要“docker login”就可拉取该项目下的镜像。

测试过程中,如果用户不对项目访问级别勾选“公开”项,则只有项目设置所属账户和admin账户可以看到此类项目,因而所有未认证的用户均无法通过API或前端查询到任何信息,如图13所示。

图13 未认证用户无法通过API获取到该项目的任何信息

尽管该项目对“公开”的描述已经很详实,但由于Harbor的前端界面需要登录认证,针对使用Harbor不熟悉的用户在操作时仍有可能会误用该功能,从而使包含敏感信息的镜像仓库对所有人开放,而用户的初衷可能只是对认证用户开放。

通过上述实验可以看出,几乎所有版本的Harbor都存在通过特定方式获取镜像的风险,这可能导致敏感信息泄露。因此,在使用Harbor进行镜像管理时,特别是在部署在公网上的情况下,建议用户先熟悉Harbor的使用方式和特性,并严格控制镜像仓库的公开范围。同时,重视对镜像仓库中的敏感信息和相关配置信息的管理,以避免因公开包含敏感信息的镜像而导致敏感信息泄露的风险。

四. Docker Registry镜像泄露分析

4.1 Docker Registry组件公网暴露情况

截至2023年11月,在Shodan上可以检测到12920个暴露的Docker Registry资产,如图14所示,其中检测到国内2902个Harbor资产,国外10018个。

图14 Docker Registry资产在Shodan上扫描的结果

4.2 镜像泄露风险分析

由于Docker Registry私有仓库的认证机制在默认情况下并不会开启,因而攻击者可以直接调用官方提供的API接口[6]获取私有镜像仓库的列表和版本信息,进而可获取镜像的详细信息,最终导致镜像泄露的风险。以上笔者进行了验证,过程如下:

当使用命令docker run -p 5000:5000 --restart=always --name registry -v /var/lib/registry:/var/lib/registry -d registry进行Docker Registry私有仓库的构建时,默认不会开启认证服务。若该镜像仓库服务暴露在公网时,任意用户可以通过官方API对镜像列表进行获取,如图15所示。

图15 通过API对资产的镜像仓库列表进行读取

在获取到镜像仓库列表后,进一步通过官方API获取tag信息,如图16所示。

图16 通过API获取镜像仓库的tag列表

通过获取仓库名称和tag,我们不仅可以获取镜像构建的详细信息,还能够根据名称和tag信息组合出镜像拉取命令并进行拉取,如图17所示。

图17 组合出来的镜像仓库拉取代码

若要开启认证服务,则需要先创建Docker Registry认证文件目录和认证文件,并使用Apache的htpasswd来创建加密文件,容器的启动方式如图18所示。

图18 开启认证服务时的Docker Registry启动方式(示例)

当给Docker Registry添加了认证机制后,再通过其API接口获取镜像列表时将返回未认证的提示,如图19所示,因此添加认证机制的Docker Registry将可以对私有镜像仓库进行保护。

图19 具有认证机制的Docker Registry将可以对私有镜像仓库进行保护

由此得出,虽然Docker Registry的安装部署和使用起来非常方便,但是直接使用Docker Registry身份认证服务的默认配置并不安全。而且由于Docker Registry没有前端界面,缺少Harbor中直观的用户认证与配置方式,导致用户在使用Docker Registry时,不安全配置的可能性较大。

笔者建议在使用Docker Registry进行私人镜像管理时,应首先开启其认证机制后再进行镜像的传输,从而避免镜像信息的泄露。

五. 总结

本篇文章主要介绍和分析了公共镜像仓库Docker Hub中镜像和敏感信息泄露情况,以及Harbor、Docker Registry两个私有镜像仓库中镜像和敏感信息的泄露风险。

近年来云上数据泄露事件屡见不鲜,公有镜像仓库泄露大量密钥已是事实,私有镜像仓库的安全风险依然存在,因此,建议大家在使用镜像仓库过程中密切关注其安全性,并且采取必要的措施以保护敏感信息和数据的安全,在构建镜像时,避免直接将密钥设置在环境变量中,避免在镜像中直接添加包含源代码、敏感配置信息等。

参考文献

[1] Thousands of images on Docker Hub leak auth secrets, private keys (bleepingcomputer.com)https://www.bleepingcomputer.com/news/security/thousands-of-images-on-docker-hub-leak-auth-secrets-private-keys/

[2] https://search.censys.io/

[3] https://www.docker.com/pricing/

[4] 云原生服务风险测绘分析(二):Harbor – 绿盟科技技术博客 (nsfocus.net)

[5] https://nvd.nist.gov/vuln/detail/CVE-2022-46463

[6] https://docs.docker.com/registry/

内容编辑:创新研究院 程章

责任编辑:创新研究院 陈佛忠

本公众号原创文章仅代表作者观点,不代表绿盟科技立场。所有原创内容版权均属绿盟科技研究通讯。未经授权,严禁任何媒体以及微信公众号复制、转载、摘编或以其他方式使用,转载须注明来自绿盟科技研究通讯并附上本文链接。

声明:本文来自绿盟科技研究通讯,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。