介绍
在本文中,我们将深入研究存储在Docker镜像中的秘密,如果攻击者访问私有Docker注册表,这些秘密可能会被利用。从攻击者的角度来看,获取目标的Docker镜像可能与访问目标的git或源代码相同。存储的凭据、漏洞研究和镜像投毒--对于渗透测试人员来说,有很多机会。我们开始吧
基本解释:Docker和Docker Registry
我们周围几乎到处都是Docker容器:Web应用程序,Web服务器,数据库和几乎所有我们能想到的软件。Docker镜像实际上只是代码和依赖项的集合,开发人员将其放在一起,以简化软件的激活和部署。一个docker镜像的Dockerfile示例:
上图演示了一个基于NodeJS 14的Web应用程序,它包含了Web应用程序的所有代码(第5行),然后安装了应用程序的所有依赖项(第7行),并在端口3000上运行(第9行)。现在,要运行此应用程序,要做的就是从存储它的存储库中拉取镜像并运行它,实际上只需一个简单的命令。
您可以从DockerHub(如Nginx,Python,MySQL等)查找和下载公共Docker镜像,如果您想要为您的组织或自己创建一个私有DockerHub,您可以创建Docker Registry来存储所有Docker镜像。如果你选择使用docker镜像,那么无论你使用什么样的docker注册表(DockerHub或私有注册表),其中都包含了你的代码,类似于你的Git仓库。
要了解它有多简单,以下是创建私有Docker注册表的ChatGPT指南:
Docker注册表的默认端口是5000,它通过HTTP运行,无需任何身份验证。当然,您应该使用有限的访问权限或至少密码来保护注册表。否则,您将向互联网上可以找到您的注册表的任何人公开您的代码。
如果你想设置访问注册表的身份验证,这里再次用ChatGPT回答:
这个命令只是比上一个命令更复杂一点。
此外,为了使用私有docker注册表,我们需要通过编辑/etc/docker/daemon.json允许docker守护进程信任指定的地址:
然后重启docker服务:
sudo systemctl stop docker
sudo systemctl start docker
接着我们就可以使用私有Docker注册表了。
理论:
对于许多公司来说,Docker注册表将是一个安全盲点,即使是那些认为自己安全且严格遵守最佳实践的科技公司。通过找到一个开放的私有Docker注册表,我将能够通过以下方法之一获得访问权限:
·代码秘密-存储的凭证、安全令牌、JWT密钥等。
·漏洞研究-通过查看代码并进行白盒审计。
·镜像投毒-推送包含恶意代码的恶意镜像。
通过在Shodan中实用语法搜索“Docker Registry HTTP API”,我们得到以下结果:
在结合使用Censys、fofa、扫描仪和其他工具之后,我能够映射大约100万个Docker注册表,其中大多数都可以访问,无需任何身份验证。
从代码到RCE
为了找到有价值的镜像,我通过关注包含名称为“backend”,“API”,“database”,“crm”等镜像的注册表来缩小搜索范围。
我选择了一个为企业提供SaaS平台的软件公司的注册表,这里将其称为REDACTED(不暴露真实的名称)。
REDACTED在它的注册表上有很多可用的镜像,所以我拉了一个有趣的名字-“crm”。
现在我有了镜像,我需要将它的文件系统挂载到我的机器上,以便读取应用程序代码。这里有一个简单的技巧。
Docker可以选择导出正在运行的容器的文件系统(而不是静态镜像)。
在这一点上,我不知道什么是正确的方式来运行容器,所以如果我只是简单地运行容器,它可能会在几秒钟后崩溃。但这就是诀窍。我将运行容器,知道它会崩溃,我只需要足够快,在容器崩溃之前执行导出命令。因此,在一个终端上运行容器并立即转移到第二个终端以导出文件系统:
运行容器:
导出文件系统:
现在我们需要从tar文件中提取文件:
进入app目录并查看其内容,我注意到一个名为js.json的文件。阅读其内容后发现:
果然是密码!
现在我们持有PostgreSQL的数据库凭证。快速查找在公司范围内的IP地址,在一个IP上暴露端口5432。我试了一下我得到的凭证:
登录成功了,很明显,这是该公司的真实的CRM!
不仅如此,我拥有的用户具有超级用户权限。因此,通过授予自己额外的权限:
现在我们可以从远程服务器获取一个目录列表:
我们有权限使用Postgres读取文件:
根据我们的权限,我们还可以在远程服务器上写入文件。但是现在让我们尝试运行命令并在这里正式获得RCE:
类似于这个例子,我尝试了几个来自不同注册表的镜像,发现了一些凭据:
· AWS token
· Stripe secret keys
· JWT密钥
· 电子邮件帐户凭据
· API密钥
另外值得一提的是,在某些情况下,通过查看某些应用程序的代码,可以发现某些应用程序存在不同类型的漏洞,包括:
总结项目的这一部分,可以说,在大多数情况下,当渗透测试人员将注意力放在意外暴露的Docker注册表上时,会发现有价值的信息,这些信息对挖掘目标基础设施漏洞非常有用。
当代码是“安全的”时
现在我们做了一些测试,通过访问私有Docker镜像,我们可以发现许多漏洞,让我们假设我们遇到了一个以安全方式编写代码的目标,并且严格遵守最佳实践(例如,不存储硬编码的凭证)。
我们怎么还能赢这场比赛?可以,镜像投毒!
大多数情况下,当我有拉权限下载镜像时,我也有推权限。这意味着现在可以将原始镜像与恶意镜像进行切换:
·拉取目标镜像
·在本地挂载文件系统
·添加一段恶意代码(打开反向shell,下载webshell,植入JS键盘记录器...)
·在本地重建镜像
·将镜像推回目标注册表并覆盖原始镜像
这样一来,无论开发团队是否做得很好,DevOps都足以以一种草率的方式管理注册表权限,让攻击者毒害组织的整个Docker镜像。
漏洞修复措施
· 使用安全密码保护Docker注册表!
· 如非必要不要将注册表暴露在互联网上
· 避免在代码中硬编码凭证和令牌,而是在运行容器时使用环境变量
以上内容由白帽子左一翻译并整理。原文:https://medium.com/@red.whisperer/blind-spot-from-docker-registry-to-rce-b0d46e043798
声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。所有渗透都需获取授权!
如果你是一个网络安全爱好者,欢迎加入我的知识星球:zk安全知识星球,我们一起进步一起学习。星球不定期会分享一些前言漏洞,每周安全面试经验、SRC实战纪实等文章分享,微信识别二维码,只需25,即可加入,如不满意,72 小时内可在 App 内无条件自助退款。