关于 detecting-compromised-cloud-credentials
面向云安全分析人员的多云凭据失陷检测技能,覆盖 AWS、Azure 和 GCP 的异常活动识别、跨云关联与事件处置。
主要功能
- 01检查 AWS、Azure、GCP 凭据滥用迹象
- 02分析身份登录与审计日志
- 03关联 SIEM 中的跨云指标
- 04失陷确认后的凭据遏制
- 05检查攻击者持久化迹象
适用场景
- 01调查陌生地点发起的云 API 活动
- 02排查云平台关于凭据泄露的通知
- 03构建跨云凭据滥用检测规则
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill detecting-compromised-cloud-credentials安装后在 Claude Code 中输入/detecting-compromised-cloud-credentials确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
检测已泄露的云凭据
何时使用
- 当调查有关来自陌生位置的异常云 API 活动的告警时
- 当构建针对云环境中凭据窃取和滥用的检测规则时
- 当响应云提供商关于凭据泄露的通知时
- 当监控针对云身份的凭据填充或暴力破解攻击时
- 当在初步检测后评估凭据泄露的影响范围时
不要使用于防止凭据泄露(使用 MFA、凭据轮换和密钥管理)、检测应用层凭据窃取(使用应用安全监控)或端点凭据窃取检测(使用 EDR 工具)。
前置条件
- 在所有账户和区域启用 AWS GuardDuty
- 配置 Azure Defender for Identity 和 Entra ID Protection
- 启用带 Event Threat Detection 的 GCP Security Command Center
- 集中收集 CloudTrail、Azure Activity Log 和 GCP Audit Log 以供分析
- 集成 SIEM 以跨云关联凭据滥用指标
- 提供威胁情报源以获取已知恶意 IP 范围
工作流
步骤 1:检测 AWS 中的凭据泄露指标
监控 GuardDuty 发现结果和 CloudTrail 异常,这些指标表明凭据被滥用。
# List GuardDuty credential-related findings
aws guardduty list-findings \
--detector-id $(aws guardduty list-detectors --query 'DetectorIds[0]' --output text) \
--finding-criteria '{
"Criterion": {
"type": {
"Eq": [
"UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS",
"UnauthorizedAccess:IAMUser/MaliciousIPCaller",
"UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom",
"UnauthorizedAccess:IAMUser/TorIPCaller",
"UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B",
"Recon:IAMUser/MaliciousIPCaller",
"Recon:IAMUser/MaliciousIPCaller.Custom",
"InitialAccess:IAMUser/AnomalousBehavior",
"CredentialAccess:IAMUser/AnomalousBehavior",
"Persistence:IAMUser/AnomalousBehavior"
]
},
"service.archived": {"Eq": ["false"]}
}
}' --output json
# Check for console logins from new locations
aws logs start-query \
--log-group-name cloudtrail-logs \
--start-time $(date -d "7 days ago" +%s) \
--end-time $(date +%s) \
--query-string '
fields @timestamp, userIdentity.userName, sourceIPAddress, responseElements.ConsoleLogin
| filter eventName = "ConsoleLogin"
| filter responseElements.ConsoleLogin = "Success"
| stats count() by userIdentity.userName, sourceIPAddress
| sort count desc
'
# Detect impossible travel (same user from geographically distant IPs within short time)
aws logs start-query \
--log-group-name cloudtrail-logs \
--start-time $(date -d "24 hours ago" +%s) \
--end-time $(date +%s) \
--query-string '
fields @timestamp, userIdentity.arn, sourceIPAddress, eventName
| filter userIdentity.type = "IAMUser"
| stats earliest(@timestamp) as first_seen, latest(@timestamp) as last_seen,
count_distinct(sourceIPAddress) as unique_ips by userIdentity.arn
| filter unique_ips > 3
'
步骤 2:检测 Azure 中的凭据滥用
监控 Entra ID 登录日志和 Defender for Identity 告警,以发现已泄露的凭据。
# Check for risky sign-ins
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/auditLogs/signIns?\$filter=riskLevelDuringSignIn ne 'none' and createdDateTime ge 2026-02-16T00:00:00Z&\$top=50" \
--query "value[*].{User:userPrincipalName,Risk:riskLevelDuringSignIn,IP:ipAddress,Location:location.city,App:appDisplayName,Status:status.errorCode}" \
-o table
# Check for sign-ins from anonymous or Tor IPs
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/auditLogs/signIns?\$filter=riskEventTypes_v2/any(r:r eq 'anonymizedIPAddress') and createdDateTime ge 2026-02-22T00:00:00Z" \
--query "value[*].{User:userPrincipalName,IP:ipAddress,Location:location.city}" \
-o table
# List users flagged as compromised by Identity Protection
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/identityProtection/riskyUsers?\$filter=riskLevel eq 'high'" \
--query "value[*].{User:userPrincipalName,RiskLevel:riskLevel,RiskState:riskState,LastDetected:riskLastUpdatedDateTime}" \
-o table
# Check for suspicious application consent grants
az rest --method GET \
--url "https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?\$filter=activityDisplayName eq 'Consent to application' and activityDateTime ge 2026-02-16T00:00:00Z" \
--query "value[*].{Activity:activityDisplayName,User:initiatedBy.user.userPrincipalName,App:targetResources[0].displayName}" \
-o table
步骤 3:检测 GCP 中的凭据滥用
查询 GCP 审计日志和 SCC 发现结果,以获取凭据泄露指标。
# Check SCC Event Threat Detection findings
gcloud scc findings list ORG_ID \
--filter="state=\"ACTIVE\" AND (category=\"ANOMALOUS_CALLER_LOCATION\" OR category=\"SUSPICIOUS_LOGIN\" OR category=\"CREDENTIAL_ACCESS\")" \
--format="table(finding.category, finding.severity, finding.resourceName, finding.eventTime)"
# Query audit logs for service account key usage from unusual IPs
gcloud logging read '
protoPayload.authenticationInfo.principalEmail:*@*.iam.gserviceaccount.com
AND protoPayload.requestMetadata.callerIp!=("10." OR "172." OR "192.168.")
AND timestamp>="2026-02-22T00:00:00Z"
' --limit=100 --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.requestMetadata.callerIp, protoPayload.methodName)"
# Detect API calls from Tor exit nodes
gcloud logging read '
protoPayload.requestMetadata.callerIp:("185." OR "198." OR "45.")
AND protoPayload.authenticationInfo.principalEmail:*@company.com
AND timestamp>="2026-02-22T00:00:00Z"
' --limit=50 --format=json
# Check for new service account keys created (persistence indicator)
gcloud logging read '
protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"
AND timestamp>="2026-02-16T00:00:00Z"
' --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.request.name)"
步骤 4:构建跨云关联规则
创建 SIEM 规则,以跨云提供商关联凭据滥用指标。
# siem_correlation.py - Cross-cloud credential abuse detection
import json
from datetime import datetime, timedelta
def detect_impossible_travel(events):
"""Detect same identity used from distant locations in short timeframe."""
user_events = {}
for event in events:
user = event.get('principal', '')
ip = event.get('source_ip', '')
ts = event.get('timestamp', '')
cloud = event.get('cloud_provider', '')
key = f"{user}_{cloud}"
if key not in user_events:
user_events[key] = []
user_events[key].append({'ip': ip, 'timestamp': ts, 'cloud': cloud})
alerts = []
for user_key, accesses in user_events.items():
accesses.sort(key=lambda x: x['timestamp'])
for i in range(1, len(accesses)):
time_diff = (datetime.fromisoformat(accesses[i]['timestamp']) -
datetime.fromisoformat(accesses[i-1]['timestamp']))
if time_diff < timedelta(hours=1) and accesses[i]['ip'] != accesses[i-1]['ip']:
alerts.append({
'type': 'IMPOSSIBLE_TRAVEL',
'user': user_key,
'ip_1': accesses[i-1]['ip'],
'ip_2': accesses[i]['ip'],
'time_gap_minutes': time_diff.total_seconds() / 60,
'severity': 'HIGH'
})
return alerts
def detect_credential_stuffing(events, threshold=10):
"""Detect multiple failed logins followed by success."""
user_attempts = {}
for event in events:
user = event.get('principal', '')
success = event.get('success', False)
key = user
if key not in user_attempts:
user_attempts[key] = {'failures': 0, 'success_after_failures': False}
if not success:
user_attempts[key]['failures'] += 1
elif user_attempts[key]['failures'] >= threshold:
user_attempts[key]['success_after_failures'] = True
return [{'user': u, 'failures': d['failures'], 'severity': 'CRITICAL'}
for u, d in user_attempts.items() if d['success_after_failures']]
步骤 5:响应已确认的凭据泄露
在确认凭据泄露后执行遏制操作。
# AWS: Deactivate access key immediately
aws iam update-access-key --user-name COMPROMISED_USER \
--access-key-id AKIA_COMPROMISED --status Inactive
# AWS: Invalidate temporary role credentials by updating role trust policy
aws iam update-assume-role-policy --role-name COMPROMISED_ROLE \
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Principal":"*","Action":"sts:AssumeRole"}]}'
# AWS: Revoke all sessions for an IAM user
aws iam put-user-policy --user-name COMPROMISED_USER \
--policy-name RevokeOldSessions \
--policy-document '{
"Version":"2012-10-17",
"Statement":[{
"Effect":"Deny",
"Action":"*",
"Resource":"*",
"Condition":{"DateLessThan":{"aws:TokenIssueTime":"2026-02-23T10:00:00Z"}}
}]
}'
# Azure: Revoke all sign-in sessions
az rest --method POST \
--url "https://graph.microsoft.com/v1.0/users/COMPROMISED_USER_ID/revokeSignInSessions"
# Azure: Force password reset
az ad user update --id COMPROMISED_USER_ID --force-change-password-next-sign-in true
# GCP: Disable service account
gcloud iam service-accounts disable COMPROMISED_SA_EMAIL
# GCP: Delete service account keys
gcloud iam service-accounts keys delete KEY_ID --iam-account=COMPROMISED_SA_EMAIL
关键概念
| 术语 | 定义 |
|---|---|
| 不可能旅行 | 检测到同一凭据在物理上不可能旅行的时间段内,从地理上相距遥远的位置被使用 |
| 凭据填充 | 利用数据泄露中窃取的用户名/密码组合,尝试登录多个云服务的攻击 |
| 实例凭据外泄 | GuardDuty 发现结果,表明 EC2 实例角色凭据正从预期的 AWS 网络之外被使用 |
| 异常行为 | 基于机器学习的检测,识别显著偏离主体既定基线的 API 调用模式 |
| 会话撤销 | 使已泄露主体的所有活动身份验证会话失效,以强制使用新凭据重新进行身份验证 |
| 持久化指标 | 攻击者在初始入侵后为保持访问而设计的操作,例如创建新的访问密钥或服务账户密钥 |
工具与系统
- AWS GuardDuty:基于 ML 的威胁检测,具有针对凭据泄露和未授权访问的特定发现类型
- Microsoft Entra ID Protection:针对登录异常、已泄露凭据和高风险用户行为的身份风险检测
- GCP Event Threat Detection:SCC 组件,检测 GCP 环境中的异常 API 使用和凭据滥用
- CloudTrail / Activity Log / Audit Log:提供凭据泄露调查原始数据的 API 审计日志
- SIEM(Splunk、Elastic、Sentinel):用于跨云关联凭据滥用指标的集中式平台
常见场景
场景:检测通过钓鱼攻击泄露的访问密钥
背景:一名开发者收到一封钓鱼邮件,其 AWS 控制台凭据被窃取。攻击者从境外 IP 登录,创建一个新的访问密钥,并开始枚举该账户。
处理方式:
- GuardDuty 针对来自异常国家的登录触发
UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B - SOC 审查该发现,并与邮件安全团队报告的钓鱼事件进行关联
- 在 CloudTrail 中查询被泄露用户从攻击者 IP 执行的所有操作
- 发现攻击者创建了新的访问密钥并运行了 IAM 枚举命令
- 立即停用该用户的所有访问密钥并撤销活动会话
- 强制重置密码并重新注册 MFA
- 检查是否存在持久化:新建的 IAM 用户、角色、Lambda 函数或 EC2 实例
- 移除任何持久化痕迹并记录事件时间线
常见陷阱:仅更改密码不会使现有访问密钥或活动会话失效。必须轮换所有访问密钥,并通过为在检测到入侵之前签发的令牌添加拒绝所有策略来撤销临时凭据。攻击者可能会在初始凭据被撤销之前创建新的 IAM 用户或角色以实现持久化。
输出格式
Cloud Credential Compromise Detection Report
===============================================
Detection Date: 2026-02-23
Scope: Multi-cloud (AWS, Azure, GCP)
Period: 2026-02-16 to 2026-02-23
ACTIVE COMPROMISE INDICATORS:
[CRED-001] AWS Console Login from Unusual Location
User: [email protected]
Source IP: 185.x.x.x (Russia)
Normal Location: US-East
GuardDuty Finding: UnauthorizedAccess:IAMUser/ConsoleLoginSuccess.B
Severity: HIGH
Status: Credential deactivated
[CRED-002] Azure Impossible Travel Detection
User: [email protected]
Location 1: New York, US (09:00 UTC)
Location 2: Beijing, CN (09:15 UTC)
Risk Level: HIGH
Status: Sessions revoked, under investigation
DETECTION METRICS (Last 7 Days):
Impossible travel detections: 5
Anomalous API activity alerts: 12
Failed login attempts > threshold: 3
New credentials from unusual IPs: 2
Total compromises confirmed: 2
CONTAINMENT ACTIONS TAKEN:
AWS access keys deactivated: 3
Azure sessions revoked: 2
GCP service accounts disabled: 1
Passwords force-reset: 4
MFA re-enrolled: 4
评论
支持 Markdown