社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  docker

安全盲点:如何从Docker Registry到RCE

白帽子左一 • 5 月前 • 422 次点击  

扫码领资料

获网安教程

介绍

在本文中,我们将深入研究存储在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 dockersudo 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密钥

另外值得一提的是,在某些情况下,通过查看某些应用程序的代码,可以发现某些应用程序存在不同类型的漏洞,包括:

· API中的IDOR· SQL注入· SSRF

总结项目的这一部分,可以说,在大多数情况下,当渗透测试人员将注意力放在意外暴露的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 内无条件自助退款。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/173621
 
422 次点击