pyro-0x/untrust

GitHub: pyro-0x/untrust

一款云端 TEE 部署审计工具,专门检测 attestation 机制未覆盖的信任边界安全风险。

Stars: 0 | Forks: 0

untrust — a TEE deployment auditor

untrust

一款针对 attestation 忽略的信任边界的 TEE 部署审计工具。

PyPI Python License Checks Platforms DEF CON 34

云端 TEE(AWS Nitro Enclaves、AMD SEV-SNP、Intel TDX)承诺,即使宿主机被完全攻破,也无法触及硬件隔离的 enclave。其密码学 attestation 的机制是可靠的。但部署层面并非如此。 每个 TEE 工作负载都必须从外部接收*某些内容*:来自云端对象存储的 bootstrap 状态、来自宿主机的环境变量、以及其策略本应(但通常并未)强制执行 attestation 的 KMS 密钥。这些输入均不受 attestation 保证的保护。而所有这些都曾在真实的漏洞利用中被使用过。 `untrust` 会审计 TEE attestation 未覆盖的信任边界,并生成包含具体修复指导的通过/失败报告。 ## 为什么会有这个项目 `untrust` 诞生于一次真实的对抗模拟之后,在这次模拟中,仅仅拥有云存储的单次写入权限,就足以在硬件隔离的 enclave 内部以 root 身份执行完整的远程代码执行 (RCE)。这个漏洞存在于 bootstrap 状态下载过程中的路径遍历问题——这是一种自 1998 年就存在的漏洞类别,却击垮了价值万亿美元的信任边界。 展示此项研究的演讲在 **DEF CON 34**(2026 年 8 月)上进行:*"Enclave 在对你撒谎:通过启动时状态打破 TEE 信任边界。"* ## 安装 ``` pip install untrust ``` 需要 Python 3.10+ 及已配置的 AWS 凭证(用于实时扫描)。 ## 快速入门 ### 针对真实部署的实时扫描 ``` untrust scan \ --target-bucket my-enclave-state \ --kms-key-id arn:aws:kms:us-west-2:111111111111:key/abc... \ --instance-id i-0abc123 \ --region us-west-2 \ --output report.json ``` ### Demo 模式(无需 AWS 凭证) ``` untrust scan --demo ``` ### 示例输出 对内置模拟部署运行 `untrust scan --demo`:

untrust scan --demo output

使用 `untrust list-checks` 列出每项检查及其严重程度:

untrust list-checks output

## 审计内容 涵盖八大类别的 33 项检查,每一项都映射到真实的漏洞利用路径。 ### Bootstrap 与供应链 | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **BOOTSTRAP-01** | S3 bucket 是否接受状态前缀中的路径遍历键名 (`../`)? | 通过上传单个对象实现 enclave RCE | | **BOOTSTRAP-02** | bucket 策略是否将 `s3:PutObject` 限制为特定主体? | 任何 IAM 主体都可以在 enclave 的状态中植入文件 | ### 对象存储(状态 bucket) | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **S3-01** | 是否启用了全部四项 S3 公共访问阻断设置? | bootstrap 状态被公开暴露 | | **S3-02** | 是否开启了默认的 SSE-KMS 加密,并配置了仅限 TLS (`aws:SecureTransport`) 的拒绝策略? | 状态在静态和传输过程中面临明文及 MITM 攻击 | | **ROLLBACK-01** | 是否有 S3 Object Lock (WORM) 保护状态以防止回滚? | 攻击者将状态回滚到 enclave 重新加载的旧有效版本 | | **AUDIT-01** | 状态 bucket 是否启用了版本控制和服务器访问日志记录? | 静默覆盖且不留下任何取证痕迹 | ### 替代状态后端 bootstrap 状态的信任边界与后端无关——attestation 完全不覆盖这些。如果 enclave 从 S3 以外的平台加载状态,请使用相应的标志进行定向扫描(`--dynamodb-table`、`--secret-arn`、`--parameter-path`、`--efs-id`、`--db-instance`)。除非指定了后端名称,否则每项检查都将跳过。 | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **DDB-01** | DynamoDB 状态表:客户管理的 CMK、PITR、删除保护、resource-policy 写入范围、数据事件审计 | 项目篡改/回滚、未经 attestation 门控的解密、未经审计的写入 | | **SECRETS-01** | Secrets Manager:客户管理的 CMK、轮换、非通配符 resource policy、数据事件审计 | 未经 attestation 门控的密钥检索、跨账户/通配符读取 | | **SSM-01** | Parameter Store:位于客户管理的 CMK(而非 `alias/aws/ssm`)下的 `SecureString` | 明文配置/机密读取;未经 attestation 门控的解密 | | **EFS-01** | EFS/EBS 状态文件系统:CMK 加密、强制 TLS 的 FS 策略、备份 | 开放挂载、静态明文、篡改后无法恢复 | | **RDS-01** | RDS/Aurora:CMK 存储加密、非公开、无 `0.0.0.0/0` 入口、IAM 认证、删除保护、无公开快照 | 直接连接数据库、静态密码认证、公开快照数据泄露 | ### KMS 与 Attestation | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **KMS-01** | 每条 Allow+Decrypt 语句是否针对**真实的代码度量值**强制执行了 attestation(不是全零,也不是仅限身份的 PCR3/PCR4)? | 绕过 KMS 且无需 enclave,或 debug enclave 解密了生产密钥 | ### IAM 与访问控制 | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **IMDS-01** | 是否强制启用了 IMDSv2 (`HttpTokens: required`)? | 通过 HTTP GET 窃取未认证凭证 | | **IAM-01** | 实例角色是否对 S3/KMS 资源拥有通配符 `*` 权限? | enclave 或攻击者可访问账户中的任何 bucket/密钥 | | **SSH-01** | 是否禁用了 SSH 并移除了 EC2 Instance Connect? | 通过 `SendSSHPublicKey` 权限进行横向移动 | ### 网络与宿主机 | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **NAT-01** | 宿主机的网桥是否从 enclave 流量中过滤了 IMDS? | 在 enclave 内部窃取宿主机 IAM 凭证 | | **PORT-01** | 宿主机上是否存在未预期的监听 TCP 端口? | 额外的远程攻击面 | | **HOST-01** | 敏感文件(EIF、密钥、机密、环境变量)是否配置了受限权限? | 非特权用户窃取凭证/镜像 | | **HOST-02** | 与 enclave 相关的 systemd 服务是否以非 root 用户运行? | 一旦服务被攻破即刻获得 root 权限 | | **EXEC-01** | 状态目录下的文件是否不存在执行权限? | 通过替换状态文件在宿主机上执行代码 | | **VSOCK-01** | 是否存在需要人工认证审查的 vsock 监听器? | 未经认证的宿主机→enclave RPC 攻击面 | | **DNS-01** | 宿主机是否对来自 enclave 的 DNS 进行了 DNAT 重定向? | 若缺少 TLS pinning,则面临基于 DNS 的 MITM | | **VPC-01** | 宿主机是否不存在公网 IP、VPC peering 和 transit-gateway 连接? | 扩大对 enclave 宿主机的网络可访问范围 | ### 宿主机内存与持久化清理 | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **CORE-01** | 是否禁用了核心转储 (core dumps)? | 崩溃时会将 enclave 附近的机密以明文形式写入宿主机磁盘 | | **SWAP-01** | 是否禁用了 swap? | 进程内存被分页到未加密的磁盘上 | | **LOG-01** | enclave 的 journal 日志是否仅限 root 访问? | 非特权日志访问泄露了密钥/token 上下文 | | **RESTART-01** | enclave 服务是否避免了自动重启 + 重新下载不受信任的状态? | 每次重启时都会因一个中毒对象导致被持续重复利用 | ### Enclave 运行时 | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **ENCLAVE-01** | enclave 是否运行在 debug 模式之外? | debug enclave 会将所有 PCR 置零,从而破坏 attestation | | **ENCLAVE-02** | enclave 的 PCR 度量值是否存在且非零? | attestation 实际上并未激活 | | **ENCLAVE-03** | 每台宿主机是否只运行一个 enclave? | 共享大页/CPU 争用以及合租侧信道攻击 | | **ENCLAVE-04** | enclave 是否从**已签名**的 EIF (PCR8) 启动并验证了签名? | 没有签名身份来绑定 KMS;也没有与构建 pipeline 的关联 | ### 配置 | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **ENV-01** | 宿主机提供的环境变量文件是否不含危险变量且在语义上有效? | 流量重定向 (HTTPS_PROXY)、状态注入 (BUCKET_NAME) | ### 检测与取证 | 检查项 | 验证内容 | 失败导致的后果 | |-------|-----------------|-----------------| | **CLOUDTRAIL-01** | 是否存在记录管理事件(KMS `Decrypt`)及状态 bucket 的 S3 数据事件的追踪? | 实时的 KMS 拦截和状态篡改不会留下任何审计痕迹 | ## `untrust` 刻意*不*检查的内容(及原因) 一款诚实的扫描器应当指出自身的盲区。这些威胁是真实存在的,但部署配置扫描器无法对它们进行有效测试——它们需要代码审查、在 enclave *内部*进行运行时自省,或者属于硬件供应商的责任。以上内容已与机密计算联盟威胁模型、MITRE/COIN enclave 接口研究、Trail of Bits 的 Nitro 攻击面说明以及近期的学术研究(SGX.Fail、TEE.Fail)进行了交叉对比。 | 威胁 | 排除原因 | 归属领域 | |--------|----------------------|------------------| | **熵源** (`rng_current` = `nsm-hwrng`) 和 **时钟源** (`kvm-clock`) | 只能在 enclave *内部*观察;没有宿主机/SSM 访问路径 | Enclave 运行时自检 | | **Attestation nonce / 时间戳新鲜度** | 这是 enclave 消耗 attestation 的代码属性,而非部署配置 | 应用程序代码审查 | | **常数时间加密 / 时序侧信道** | 需要代码和微架构分析 | 应用程序代码审查 | | **vsock 接口输入验证** (MITRE COIN: 并发、顺序、输入、嵌套) | 双向的宿主机↔enclave 协议由应用程序定义;`VSOCK-01` 仅标记是否存在监听器 | 应用程序代码审查 / 模糊测试 | | **物理与微架构攻击** (TEE.Fail DDR 介入、Battering RAM、Wiretap、L3 缓存) | 硬件/供应商层面;Nitro 不向客户提供内存加密密钥路径,也无物理操作员访问权限 | AWS 管理 / 可接受的风险 | | **可重复构建与独立 PCR 验证** | 属于 CI/CD 过程控制(例如仲裁构建),而非运行时状态 | 构建 pipeline / 供应链策略 | ## CLI 参考 ``` # 运行所有检查 untrust scan --target-bucket BUCKET --kms-key-id KEY --instance-id INSTANCE # 审计非 S3 状态后端(任意组合) untrust scan --dynamodb-table TABLE --kms-key-id KEY untrust scan --secret-arn ARN untrust scan --parameter-path /enclave/ untrust scan --efs-id fs-0123 --db-instance prod-db # 仅被动扫描 — 跳过侵入性检查(S3 写入探测和所有 # host/nitro-cli SSM 命令),以避免触发 SOC/EDR 检测 untrust scan --target-bucket BUCKET --kms-key-id KEY --instance-id INSTANCE --read-only # 以演示模式运行(模拟易受攻击的部署) untrust scan --demo # 输出 JSON 报告 untrust scan --demo --output report.json untrust scan --demo --json # 列出可用检查 untrust list-checks # 版本 untrust --version ``` ## JSON 输出 `--output` 和 `--json` 标志会生成结构化输出,适合与 CI/CD pipeline、SIEM 系统或安全仪表板集成: ``` { "version": "1.0.0", "timestamp": "2026-08-24T14:30:22.000000+00:00", "target": { "bucket": "enclave-state-XXXXXXXXXXXX", "kms_key_id": "arn:aws:kms:us-west-2:XXXXXXXXXXXX:key/demo-key-id", "instance_id": "i-0abc123def456789a", "region": "us-west-2" }, "summary": { "total": 28, "pass": 0, "fail": 28, "skip": 0, "error": 0 }, "findings": [...] } ``` ## 路线图 - **v1.0 (DEF CON 34, 2026年8月):** AWS Nitro Enclaves,33 项检查(S3 + DynamoDB/Secrets Manager/SSM/EFS/RDS 状态后端),JSON 输出 - **v1.1:** 用于集成 GitHub Advanced Security 的 SARIF 输出格式 - **v2.0:** AMD SEV-SNP attestation 策略审计 - **v2.1:** Intel TDX bootstrap 完整性检查 - **v3.0:** Azure Confidential Containers,GCP Confidential VMs - **未来 针对特定供应商 TEE 平台的 Plugin API ## 工作原理 `untrust` 使用 AWS SDK (boto3) 和 SSM 来检查目标部署。它结合了多类检查(运行 `untrust list-checks` 查看全部 33 项检查): - **Cloud-API 检查** 直接读取 S3、KMS、EC2、IAM 和 CloudTrail 配置 —— 例如 `KMS-01` 执行语义密钥策略评估(拒绝全零和仅限身份的 PCR 条件),`ROLLBACK-01` 读取 S3 Object Lock,`S3-02` 读取 bucket 加密和仅限 TLS 的策略,`CLOUDTRAIL-01` 确认 KMS/S3 活动已被真实记录。 - **替代后端检查** 在定向时对非 S3 状态存储应用相同的存储平面控制:DynamoDB (`DDB-01`)、Secrets Manager (`SECRETS-01`)、SSM Parameter Store (`SSM-01`)、EFS/EBS (`EFS-01`) 以及 RDS/Aurora (`RDS-01`)。每一项都检查客户管理的 CMK(以便 `KMS-01` attestation 能够进行门控)、最小特权/非公开访问、防回滚以及审计覆盖范围。CMK 状态通过 `kms:DescribeKey` (`KeyMetadata.KeyManager`) 权威解析 —— 字符串检查无法区分 AWS 管理的服务密钥和客户 CMK,因为两者都显示为已解析的密钥 ARN。 - **宿主机检查(通过 SSM `AWS-RunShellScript`)** 在父实例上运行只读命令 —— SSH/端口/服务状态、文件和执行权限、IMDS 过滤、DNS DNAT、核心转储/swap/journal 清理以及重启持久化。 - **Enclave 运行时检查(通过 SSM + `nitro-cli`)** 确认 enclave 退出 debug 模式、具有非零 PCR、非合租属性,并且是从已签名的 EFI 启动(`describe-eif` → PCR8 + 签名验证)。 - **BOOTSTRAP-01** 额外上传带有路径遍历键名的金丝雀 (canary) 对象,并删除任何上传成功的对象。被*拒绝*的写入 —— 收到 `403 AccessDenied` **或**任何其他客户端(`4xx`)响应(例如 bucket 策略/加密条件返回的 `400`)—— 将被视为**已阻断(PASS)**,因为对象从未落地。只有临时/服务器端故障(节流、`5xx`)才会被报告为 `ERROR`。 ### 只读模式 `untrust scan --read-only` 仅运行被动的 Cloud-API 检查并跳过侵入性检查 —— 即 `BOOTSTRAP-01` 写入探测以及所有通过 SSM `AWS-RunShellScript` 在实例上执行 shell 的宿主机/enclave 检查。适用于需要安全态势快照,但不想产生写入事件或宿主机命令执行(以免触发 SOC/EDR pipeline 告警)的场景。 ### 所需 IAM 权限 执行扫描的身份需要以下权限: ``` { "Version": "2012-10-17", "Statement": [ { "Sid": "UntrustS3Checks", "Effect": "Allow", "Action": [ "s3:PutObject", "s3:DeleteObject", "s3:GetBucketVersioning", "s3:GetBucketLogging", "s3:GetBucketPolicy", "s3:GetBucketPublicAccessBlock", "s3:GetEncryptionConfiguration", "s3:GetBucketObjectLockConfiguration" ], "Resource": [ "arn:aws:s3:::YOUR-STATE-BUCKET", "arn:aws:s3:::YOUR-STATE-BUCKET/*" ] }, { "Sid": "UntrustKms", "Effect": "Allow", "Action": "kms:GetKeyPolicy", "Resource": "arn:aws:kms:REGION:ACCOUNT:key/KEY-ID" }, { "Sid": "UntrustEc2", "Effect": "Allow", "Action": [ "ec2:DescribeInstances", "ec2:DescribeVpcPeeringConnections", "ec2:DescribeTransitGatewayVpcAttachments" ], "Resource": "*" }, { "Sid": "UntrustCloudTrail", "Effect": "Allow", "Action": [ "cloudtrail:DescribeTrails", "cloudtrail:GetTrailStatus", "cloudtrail:GetEventSelectors" ], "Resource": "*" }, { "Sid": "UntrustIam", "Effect": "Allow", "Action": [ "iam:GetInstanceProfile", "iam:ListRolePolicies", "iam:GetRolePolicy", "iam:ListAttachedRolePolicies", "iam:GetPolicy", "iam:GetPolicyVersion" ], "Resource": "*" }, { "Sid": "UntrustStateBackends", "Effect": "Allow", "Action": [ "kms:DescribeKey", "dynamodb:DescribeTable", "dynamodb:DescribeContinuousBackups", "dynamodb:GetResourcePolicy", "secretsmanager:DescribeSecret", "secretsmanager:GetResourcePolicy", "ssm:DescribeParameters", "elasticfilesystem:DescribeFileSystems", "elasticfilesystem:DescribeFileSystemPolicy", "elasticfilesystem:DescribeBackupPolicy", "rds:DescribeDBInstances", "rds:DescribeDBSnapshots", "rds:DescribeDBSnapshotAttributes", "ec2:DescribeSecurityGroups" ], "Resource": "*" }, { "Sid": "UntrustSsm", "Effect": "Allow", "Action": [ "ssm:SendCommand", "ssm:GetCommandInvocation" ], "Resource": [ "arn:aws:ssm:REGION:ACCOUNT:document/AWS-RunShellScript", "arn:aws:ec2:REGION:ACCOUNT:instance/INSTANCE-ID" ] } ] } ``` **BOOTSTRAP-01** 会向目标 bucket 写入金丝雀对象并在完成后将其删除 —— 请将 `s3:PutObject`/`s3:DeleteObject` 操作范围限制为专用的审计角色。**宿主机和 enclave 运行时检查**(SSH-01、PORT-01、NAT-01、HOST-01、HOST-02、EXEC-01、ENV-01、VSOCK-01、DNS-01、CORE-01、SWAP-01、LOG-01、RESTART-01、ENCLAVE-01/02/03/04)通过 SSM 在宿主机上执行只读 shell/`nitro-cli` 命令 —— 请确保 SSM 代理正在运行,且实例配置文件允许 SSM 会话。其余检查使用 S3、KMS、EC2、IAM 和 CloudTrail 读取 API。 ## 背景阅读 - [AWS Nitro Enclaves 用户指南](https://docs.aws.amazon.com/enclaves/latest/user/nitro-enclave.html) - [使用 AWS KMS 进行 Nitro Enclaves 的密码学 Attestation](https://docs.aws.amazon.com/kms/latest/developerguide/services-nitro-enclaves.html) - [NCC Group, "公开报告 — AWS Nitro 系统安全审查" (2023)](https://research.nccgroup.com/2023/04/) - [Trail of Bits, "AWS Nitro Enclaves 安全评估" (2022)](https://github.com/trailofbits/publications) - [OWASP, "路径遍历"](https://owasp.org/www-community/attacks/Path_Traversal) ## 披露 促成本工具开发的漏洞是在针对生产环境 TEE 部署的授权对抗模拟中发现的。它们已被报告给受影响的供应商,修复程序已在后续版本中发布。协调披露流程已完成。`untrust` 不包含任何特定于供应商的漏洞利用代码或专有信息 —— 它基于公开的云 API 通用化地实现了这些审计检查。 ## 许可证 MIT。详见 [LICENSE](LICENSE)。 ## 作者 [Sandeep Jayashankar](https://github.com/pyro-0x) (pyro) — 进攻性云安全研究员。 DEF CON 34 演讲者。研究方向:针对机密计算部署的对抗模拟。
标签:Python, TEE可信执行环境, 关系图谱, 基线检查, 安全合规, 无后门, 网络代理, 逆向工具