在这篇文章中,我们将为读者详细介绍在某次渗透测试过程中,我们是如何用本地的GCP工具来进行态势感知和横向移动,从而成功地拿下了一个混合型GCP托管的基础设施的。
在我们继续之前,我想说的是,这里用到的许多技术都不是我们创造出来的,相反,它们基本上都可以在两篇优秀的文章中找到:一篇是来自Gitlab的红队,另一篇是由Tomasz W.撰写的博客文章。
在继续之前,强烈推荐大家先阅读这两篇文章。
初始入侵
下面,我将简要介绍我们是如何在公司的网络中站稳脚跟的。在进行了最初的侦察并在指定网络范围内收集了感兴趣的IP地址之后,对邻近ip地址空间进行了细致的扫描,并返回了一个scriptcase服务器——后来,我们确定这其实是影子云,有人在测试后忘记删除了。
(出于隐私原因,相关的ip地址和端口已经进行了修改)。
在对服务进行暴力搜索一段时间后,我们发现了管理帐户的登陆凭据,并能够从实例内部运行回调脚本。
我不打算详细说明,因为渗透测试过程与特定环境高度相关,可能对读者没有啥用。
枚举与权限提升
然后,我们使用运行scriptcase服务的守护进程帐户来登陆实例。每当您登陆特定的云环境时,使用环境提供的本机工具来执行初始枚举总是一个好主意(例如aws中的aws-cli提供的aws二进制文件,或者GCP中的GCloud/Gutils工具)。这是我们首先要尝试的事情之一。
好了,第一个问题来了。这个守护进程帐户貌似无法创建运行gcloud二进制文件所需的大量文件夹,因为它缺乏相应的权限。也许我们应该尝试手动下载二进制文件,并从tmp文件夹中运行它。下面,让我们检查一下我们的账户在/etc/passwd上是如何配置的(默认的shell、home dir等)。
我们看到,默认shell是nologin(这是大多数服务帐户的标准配置,因为它们根本就不打算以交互方式来使用),我们的home dir是/usr/sbin,但是我们无法访问它(否则提升我们的特权将是轻而易举的事情)。而为了创建配置文件,gcloud二进制文件则需要有一个主文件夹,所以,让我们先给它创建主文件夹,然后手动运行独立安装程序。
设置主目录并下载GCloud
安装二进制文件
Gcloud成功安装
好了,安装成功了!现在,GCP的本机工具已经可以在受限的环境中工作了。
然后,我们就可以访问该二进制文件了。现在,让我们试着枚举一下我们的服务账户角色。重要的是要记住,无论何时在GCP中创建实例,它都需要有一个关联的服务帐户,因此默认情况下为您创建一个。我们可以用以下方法枚举我们的角色:
PROJECT=$(curl http://metadata.google.internal/computeMetadata/v1/project/project-id -H “Metadata-Flavor: Google” -s)
ACCOUNT=$(curl http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email -H “Metadata-Flavor: Google” -s)
gcloud projects get-iam-policy $PROJECT --flatten=”bindings[].members” --format=’table(bindings.role)’ --filter=”bindings.members:$ACCOUNT”
(如果使用本地安装的二进制文件的话,别忘了替换gcloud路径:例如/tmp/google-cloud-sdk/bin/gcloud)
编辑器角色是与服务帐户相关联的默认角色,它可以用来提权。下面,让我们尝试修改实例元数据以注入ssh密钥(关于这种方法的详细解释,请参见前面介绍的文章)。
首先,让我们检查哪些用户的密钥是可以替换的。让我们用以下方法获得实例元数据:
INSTANCEID=$(curl http://metadata.google.internal/computeMetadata/v1/instance/id -H “Metadata-Flavor:Google” -s)
FULLZONE=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone -H “Metadata-Flavor: Google” -s)
gcloud compute instances describe $INSTANCEID --zone $FULLZONE
在这个实例的元数据中似乎没有找到任何ssh密钥。实际上,这才是它应该有的样子。下面给出来自另一个项目的实例:
(密钥也已经被替换了,所以,大家不要太激动)
在这两张图中,我们确实获得了一些重要的信息,比如下面这些内容规定——必须使用oslogin:
-key: enable-oslogin
我们以后再来讨论这个问题。现在,让我们尝试将密钥注入到实例的元数据中:
ssh-keygen -t rsa -C “shenanigans” -f ./key -P “” && cat ./key.pub
gcloud compute instances add-metadata instance012 --metadata-from-file ssh-keys=meta.txt
创建密钥
将密钥注入到元数据中
检查注入的密钥是否可用
我们发现的第二个问题:我们的ssh密钥似乎无法正常发挥作用。下面,让我们验证一下它们是否存在:
是的,都在那里。那么,一定有别的东西阻止我们登录。大家还记得我们说过os-login很重要吗?嗯,这家公司为ssh登录配置了强制性的2FA,而我们没有为账户创建第二个因子。所以,我们需要设法绕过这一点。如果大家读过Gitlab的文章的话,就会知道2FA认证并没有对服务账户强制执行。同时,我们是以gcloud计算实例服务账户(大家可以用auth命令查看是哪个账户)的形式运行的:
gcloud auth list
GCP的另一个很酷的特性是,在默认情况下,从compute API运行ssh命令时,将为您的服务帐户创建密钥,并将它们注入目标实例(在本例中为localhost),以允许您进入sudoers组。下面,让我们来试试:
gcloud compute ssh $INSTANCENAME
创建并注入密钥
我们成功地实现了权限提升。接下来,让我们开始横向移动。
横向移动
我们可以从枚举项目中的实例开始着手:
gcloud compute instances list
该ssh命令应该对其他实例也有效:
该ssh命令的确对其他实例也有效
但是由于某些原因,部分实例对我们的ssh命令没有反应:
在进行快速的端口扫描后,我们发现这个项目同时拥有Linux和Windows机器:
这是一个简单的故障排除方法,但扫描实例并不总是确定其操作系统的最佳方法。比如,在进行渗透测试时,可能有一个IDS在监控扫描。此外,也可能无法使用nmap(当然,可以通过telnet端口或使用socat或类似的方法来解决,但这很不方便)。或者,你可能想把这个过程的某些部分自动化。不管怎样,我们都希望能够找到通过Google的API进行查询的方法,并且没有简单的方法可以做到这一点,除非您非常幸运:系统启用了alpha计算API(我们从未见过IRL)。
幸运的是,有一个变通办法:当你查询实例信息时,JSON结果中的一个参数是Licensing信息。我们可以藉此推断出实例的操作系统。我们可以通过以下方式查询:
INSTANCES=$(gcloud compute instances list — format=json | jq -r .[].name)
ZONE=$(curl http://metadata.google.internal/computeMetadata/v1/instance/zone -H “Metadata-Flavor: Google” -s | cut -d/ -f4)
for i in $(echo $INSTANCES); do echo “$i:” && gcloud compute instances describe g-shr-scriptcase-01 --zone $ZONE --format=json | jq -r .disks[].licenses[] | rev | cut -d / -f 1 | rev && echo; done
根据许可记录枚举操作系统信息
了解一个实例的操作系统是很有用的,但是,我们该如何真正地跳转到Windows主机呢?实际上,我们有一个类似于"compute ssh"的命令,但是它是用于Windows系统的,这方面的详细介绍请参考Tomasz W.的文章。我们可以执行下面的命令:
gcloud compute reset-windows-password g-xbz-qlikview-01 --user=shenanigans
在代理链上定义quick proxy后,我们就可以新创建的用户的身份通过rdp进入实例:
proxychains4 xfreerdp /u:shenanigans /p:’;QfJt@fJt\fJtHfJt4)L’ /v:172.21.31.8
*hacker voice* “We’re in”
小结
在设置云基础设施时,必须意识到这样一个事实:某些配置在默认情况下可能不是100%安全的。在安全性和可用性之间总是很难平衡的,有时人们更倾向于后者。尤其是当默认情况下只有一个命令来执行以下操作时:
- 创建ssh密钥
- 将ssh密钥注入到目标实例
- 将您的密钥添加到该实例
- 将您添加到sudoers组
好了,尤其要注意下面的命令:
gcloud compute ssh $INSTANCENAME
虽然之前也提到过,但我想重申一下,这篇文章参考了很多资源,但其中最有用的两份是:
建议大家仔细阅读这些资料,它们真的太棒了!
原文地址:https://infosecwriteups.com/enumeration-and-lateral-movement-in-gcp-environments-c3b82d342794