零信任架构(Zero Trust Architecture,ZTA)是现代企业安全体系中最重要的范式转变之一。传统的"城堡与护城河"边界安全模型基于一个隐含假设:企业网络内部是可信的,外部是不可信的。然而,随着云计算、远程办公、BYOD(Bring Your Own Device)和 SaaS 应用的普及,网络边界日益模糊,这一假设早已不再成立。零信任架构的核心原则——“永不信任,始终验证”(Never Trust, Always Verify)——从根本上重新定义了安全模型,将信任决策从网络位置转移到身份、设备状态和上下文信号上。
对于安全取证分析人员而言,零信任架构既带来了显著的优势,也引入了前所未有的挑战。优势在于:零信任环境天然地生成了大量身份验证、设备状态评估、网络分段决策和策略执行的日志记录,为取证分析提供了丰富的数据源。挑战在于:当攻击者成功绕过或破坏零信任组件时,取证分析需要深入理解零信任架构的每一个组件及其交互机制,才能准确定位攻击路径和评估影响范围。
本文系统性地覆盖零信任架构安全取证分析的全链路方法论,从身份认证持续验证到微隔离策略分析,从 ZTNA/SDP 取证到多源日志关联时间线构建,结合 SolarWinds、Colonial Pipeline、Okta/Lapsus$ 等真实案例还原零信任环境下的完整攻击链,并提供可直接落地的 Sigma 规则和自动化检测脚本。
0x01 技术基础与零信任取证概述 零信任架构核心原则 零信任架构并非单一的产品或技术,而是一套安全策略框架。美国国家标准与技术研究院(NIST)在 SP 800-207 中将零信任架构定义为一种基于明确验证、最小权限访问和假设已被入侵三个核心原则的安全模型。
核心原则 技术含义 取证意义 明确验证(Verify Explicitly) 每次访问请求都基于所有可用数据点进行认证和授权 每次访问都留有日志记录,为取证提供完整访问历史 最小权限访问(Least Privilege Access) 仅授予用户完成工作所需的最小权限 权限越权行为可被快速检测和记录 假设已被入侵(Assume Breach) 假设攻击者已在网络内部,据此设计安全控制 内部流量也需要加密和验证,增加了取证数据维度
Google 的 BeyondCorp 项目是零信任架构最早的工业级实践之一。BeyondCorp 将访问控制从网络边界转移到个体设备和用户,所有访问请求都必须通过访问代理(Access Proxy),无论请求来源是内部网络还是外部网络。这一模型的核心在于将信任决策与网络位置完全解耦,所有访问决策基于设备清单数据库(Inventory Database)和设备信任等级(Device Trust Level)做出。
零信任架构组件模型 一个完整的零信任架构包含五个核心组件层,每一层都产生独特的取证数据源。
组件层 核心功能 代表技术/产品 取证数据源 身份层 用户/服务身份认证与持续验证 Azure AD、Okta、Ping Identity、Keycloak IdP 审计日志、MFA 事件、Session Token 设备层 设备注册、健康评估、信任等级 Intune、Jamf、CrowdStrike、Carbon Black 设备合规状态、EDR 遥测、证书状态 网络层 微隔离、流量加密、分段策略 Zscaler、Illumio、NSX、Calico 网络流日志、分段违规事件、TLS 握手 应用层 应用级访问控制、API 安全 ZTNA Gateway、API Gateway、Service Mesh 应用访问日志、API 调用审计 数据层 数据分类、DLP、加密 Microsoft Purview、Symantec DLP 数据访问日志、DLP 事件、加密操作日志
零信任与传统边界安全的差异对比 对比维度 传统边界安全 零信任架构 信任模型 内网信任,外网不信任 无隐式信任,所有访问需验证 网络位置 决定访问权限 与访问权限无关 认证频率 一次性认证(登录时) 持续认证(每次访问/会话期间) 授权粒度 基于网络段的粗粒度 基于身份+设备+上下文的细粒度 流量加密 仅外网加密(VPN) 所有流量加密(东西向+南北向) 微隔离 无或 VLAN 级别 工作负载级别 日志丰富度 边界设备日志为主 多源海量日志(身份/设备/网络/应用/数据) 取证数据量 相对有限 海量,需要自动化分析
零信任环境下的取证挑战 零信任架构在提供更丰富取证数据的同时,也引入了若干独特的挑战:
网络边界消失与流量加密 :零信任架构要求所有流量加密,包括东西向(服务器到服务器)流量。这意味着传统的网络镜像(SPAN/TAP)捕获方式只能获取加密后的流量,取证分析需要依赖 TLS 终端日志或解密代理日志。此外,微隔离环境中的流量可能通过多个代理转发,增加了流量溯源的复杂度。
持续验证产生的日志洪流 :零信任架构中,每次访问请求都会触发身份验证、设备状态检查、策略评估等多重验证流程,产生海量日志。在大规模部署环境中,每日产生的验证日志可达数十亿条,传统的日志分析方法难以应对如此规模的数据量。
分布式决策与策略冲突 :零信任架构中的策略决策点(PDP)和策略执行点(PEP)通常分布式部署,不同节点的策略评估结果可能存在微小的时间差或配置差异。攻击者可能利用这些差异窗口实施攻击,而取证分析需要跨多个 PDP/PEP 节点的日志进行关联分析。
动态权限调整 :零信任架构中的权限是动态调整的,基于实时的风险评分。同一用户在不同时间、不同设备上可能获得不同的权限,这使得权限基线的建立和异常检测更加复杂。
取证工具链与方法论概览 工具类别 代表工具 功能定位 适用阶段 IdP 日志分析 Azure AD Sign-in Logs、Okta System Log API 身份认证日志查询与分析 身份层取证 设备态势感知 CrowdStrike Falcon、Microsoft Defender for Endpoint 终端遥测与设备状态查询 设备层取证 网络取证 Wireshark、Zeek、Suricata 加密流量分析、网络行为检测 网络层取证 日志关联平台 Elastic SIEM、Splunk、Microsoft Sentinel 多源日志聚合与关联分析 全链路取证 Sigma 规则引擎 Sigma CLI、Uncoder.IO 跨平台检测规则编写与转换 自动化检测 脚本自动化 Python(pandas、scapy)、Bash 自定义日志解析与分析 自动化取证 时间线工具 Plaso/log2timeline、Timesketch 多源日志时间线构建 时间线分析
0x02 身份认证与持续验证取证分析 多因素认证(MFA)攻击与检测 零信任架构的基石是强身份认证。MFA 通过要求用户提供两种或以上的验证因素(知识因素、拥有因素、固有因素)来降低身份被盗用的风险。然而,攻击者已经发展出多种 MFA 绕过技术,取证分析人员需要能够识别这些攻击的痕迹。
MFA 绕过技术 MITRE ATT&CK 攻击原理 取证特征 MFA Fatigue(MFA 疲劳攻击) T1621 反复触发 MFA 推送通知直到用户误批准 短时间内大量 MFA 推送请求,用户最终批准 Real-Time Phishing(实时钓鱼) T1556 使用反向代理拦截并转发认证请求 异常地理位置、设备指纹不匹配 SIM Swapping T1557 劫持受害者手机号接收短信验证码 SIM 更改事件、新设备首次登录 OAuth Token Theft T1550.001 窃取已认证的 OAuth 令牌直接使用 异常 IP 使用有效 Token、Token 无密码验证 Session Token Replay T1550.004 重放已截获的 Session Token 同一 Token 在不同地理位置使用
MFA 疲劳攻击(MFA Fatigue)是近年来急剧增长的攻击手法。攻击者在获取用户凭据后,持续发送 MFA 验证请求,直到用户因疲劳或误操作而批准。取证分析时,需要关注以下日志模式:
cat azure_ad_signin.log | jq 'select(.status.errorCode == "500121" or .status.errorCode == "0") | {time: .createdDateTime, user: .userPrincipalName, ip: .ipAddress, status: .status, mfaDetail: .mfaDetail}' 上述命令从 Azure AD 登录日志中提取 MFA 验证事件,筛选 MFA 失败(500121)和成功(0)的记录,输出时间戳、用户、IP、状态和 MFA 详情。MFA 疲劳攻击的典型特征是:同一用户在短时间内(通常 5-30 分钟)出现大量 MFA 失败记录后突然出现一次成功记录,且成功时的 IP 与之前的失败 IP 可能不同。
持续身份验证机制与取证 零信任架构要求在整个会话期间持续验证用户身份,而非仅在登录时验证一次。持续验证基于以下信号源:
行为生物特征 :键盘击键节奏(Keystroke Dynamics)、鼠标移动模式(Mouse Dynamics)、触屏操作行为(Touch Dynamics)。这些信号通过机器学习模型建立用户行为基线,偏离基线的操作会被标记为异常。
风险评分 :持续计算当前会话的风险评分,综合考虑地理位置变化、设备状态变化、访问模式异常等因素。当风险评分超过阈值时,系统会要求重新认证或降低会话权限。
持续验证信号 正常基线特征 异常指标 取证日志位置 地理位置 常驻城市范围内移动 城市级地理跳跃(Impossible Travel) IdP Sign-in Logs 设备指纹 始终为同一设备或已知设备集合 未知设备或指纹频繁变化 设备信任日志 登录时间 工作日工作时间段 凌晨/节假日异常登录 IdP Sign-in Logs 访问行为 访问已知应用集合 访问从未访问过的敏感应用 应用访问日志 网络位置 已知网络(办公网/家庭网) 新的网络出口或 Tor/VPN 网络代理日志
Impossible Travel(不可能旅行)检测是持续验证中的经典场景。如果用户在短时间内从两个物理距离不可能到达的位置登录,系统应标记为高风险事件。
from geopy.distance import geodesic
from datetime import datetime
def detect_impossible_travel (signin_events):
alerts = []
for i in range(1 , len(signin_events)):
prev = signin_events[i - 1 ]
curr = signin_events[i]
if prev. get("user" ) != curr. get("user" ):
continue
prev_loc = (prev["latitude" ], prev["longitude" ])
curr_loc = (curr["latitude" ], curr["longitude" ])
distance_km = geodesic(prev_loc, curr_loc). kilometers
time_diff_hours = (curr["timestamp" ] - prev["timestamp" ]). total_seconds() / 3600
if time_diff_hours > 0 :
speed_kmh = distance_km / time_diff_hours
if speed_kmh > 900 :
alerts. append({
"user" : curr["user" ],
"prev_location" : prev["location_name" ],
"curr_location" : curr["location_name" ],
"distance_km" : round(distance_km, 2 ),
"time_diff_hours" : round(time_diff_hours, 2 ),
"implied_speed_kmh" : round(speed_kmh, 2 ),
"risk_level" : "CRITICAL"
})
return alerts Session Token 安全分析 零信任环境中的 Session Token(会话令牌)是身份验证的核心凭证。攻击者对 Session Token 的攻击是零信任绕过的关键环节。
JWT(JSON Web Token)安全分析 :JWT 由 Header、Payload 和 Signature 三部分组成。取证分析时需要关注以下安全问题:
JWT 安全问题 风险等级 攻击方式 取证检测方法 弱签名算法(None Algorithm) 严重 将 alg 设为 none 绕过签名验证 检查 Header 中 alg 字段 RS256→HS256 混淆 严重 用公钥作为 HMAC 密钥伪造签名 检查签名算法与密钥类型匹配 无过期时间(Missing exp) 高 Token 永不过期可被无限期使用 检查 Payload 中 exp 字段 过长有效期 中 Token 有效期过长增加泄露风险 检查 exp 与 iat 的差值 敏感数据泄露 中 用户身份信息存储在未加密 Payload 中 检查 Payload 内容
import jwt
import json
from datetime import datetime
def analyze_jwt_security (token):
findings = []
try :
header = jwt. get_unverified_header(token)
payload = jwt. decode(token, options= {"verify_signature" : False })
if header. get("alg" ) == "none" :
findings. append({"issue" : "None Algorithm" , "severity" : "CRITICAL" })
if header. get("alg" ) == "HS256" and "kid" not in header:
findings. append({"issue" : "HS256 without kid - possible key confusion" , "severity" : "HIGH" })
if "exp" not in payload:
findings. append({"issue" : "Missing expiration claim" , "severity" : "HIGH" })
else :
exp_time = datetime. fromtimestamp(payload["exp" ])
iat_time = datetime. fromtimestamp(payload. get("iat" , 0 ))
validity_hours = (exp_time - iat_time). total_seconds() / 3600
if validity_hours > 24 :
findings. append({"issue" : f "Excessive token validity: { validity_hours: .0f } h" , "severity" : "MEDIUM" })
sensitive_claims = ["password" , "ssn" , "credit_card" , "secret" ]
for claim in payload:
if claim. lower() in sensitive_claims:
findings. append({"issue" : f "Sensitive data in claim: { claim} " , "severity" : "HIGH" })
except jwt. InvalidTokenError as e:
findings. append({"issue" : f "Invalid token: { str(e)} " , "severity" : "CRITICAL" })
return findings 身份提供商(IdP)日志取证 身份提供商(Identity Provider)是零信任架构中身份层的核心组件。Azure AD、Okta、Auth0 等 IdP 生成的日志记录是零信任取证的最关键数据源之一。
Azure AD Sign-in Logs 关键字段 :
日志字段 取证意义 示例 createdDateTime 事件发生时间 2026-07-10T08:30:00Z userPrincipalName 用户标识 user@company.com ipAddress 来源 IP 地址 203.0.113.50 clientAppUsed 客户端应用类型 Browser / Mobile Apps mfaDetail.authMethod MFA 认证方法 Phone / FIDO2 / App status.errorCode 认证结果代码 0=成功 / 50126=密码错误 conditionalAccessStatus 条件访问执行结果 Success / Failure / NotApplied deviceDetail.trustType 设备信任类型 Azure AD Joined / Registered locationDetails.city 登录城市 Shanghai
Okta System Log 关键事件类型 :
事件类型 事件描述 取证价值 user.session.start 会话创建 确定会话起始时间 user.session.end 会话终止 确定会话结束时间 user.authentication.sso SSO 认证 SSO 流程审计 user.authentication.mfa MFA 验证事件 MFA 攻击检测 user.account.lock 贴户锁定 暴力破解检测 user.admin.grant_privilege 权限授予 权限提升检测 system.email.send 系统邮件发送 密码重置流程审计
条件访问策略执行日志分析 条件访问(Conditional Access)是零信任架构中实现细粒度访问控制的关键机制。条件访问策略基于用户身份、设备状态、位置、应用敏感度等多个信号做出访问决策。
{
"policyName" : "Require MFA for Admin Roles" ,
"conditions" : {
"users" : {"includeGroups" : ["Global Admins" ]},
"applications" : {"includeApplications" : ["Office 365" ]},
"locations" : {"includeLocations" : ["All" ]}
},
"grantControls" : {
"operator" : "OR" ,
"builtInControls" : ["mfa" , "compliantDevice" ]
},
"sessionControls" : {
"signInFrequency" : {"value" : 4 , "type" : "hours" }
}
} 取证分析条件访问日志时,需要重点关注以下模式:条件访问策略执行失败(Grant Controls 未满足)、策略被绕过(NotApplied 状态)、以及会话控制被异常绕过的情况。
Sigma 规则:检测身份异常 title : 零信任环境 - MFA疲劳攻击检测
id : 7a3b1c4d-5e6f-7890-abcd-ef1234567890
status : experimental
description : 检测短时间内多次MFA推送后突然成功的模式,可能指示MFA疲劳攻击
references :
- https://learn.microsoft.com/en-us/entra/identity/monitoring-health/concept-sign-in-log-activity-details
author : x7peeps
date : 2026 /07/11
tags :
- attack.credential_access
- attack.t1621
- zero_trust
logsource :
product : azure
service : signinlogs
detection :
selection :
status.errorCode :
- 500121
- 500125
timeframe : 10m
condition : selection | count by userPrincipalName > 5
falsepositives :
- 用户设备问题导致的重复MFA失败
level : high title : 零信任环境 - 不可能旅行检测
id : 8b4c2d5e-6f70-8901-bcde-f23456789012
status : experimental
description : 检测同一用户在极短时间内从相距甚远的地理位置登录
author : x7peeps
date : 2026 /07/11
tags :
- attack.initial_access
- attack.t1078
- zero_trust
logsource :
product : azure
service : signinlogs
detection :
selection_success :
status.errorCode : 0
timeframe : 1h
condition : selection_success | dcount(locationDetails.city) > 1
by userPrincipalName
falsepositives :
- 使用VPN导致的IP地理位置不准
- 用户确实在快速旅行
level : high 0x03 设备信任与终端态势感知取证 设备注册与信任评估机制 在零信任架构中,设备本身也是信任评估的关键维度。设备必须经过注册、验证健康状态后才能获得相应的信任等级。不同零信任实现中的设备信任模型存在差异,但核心流程是一致的。
设备信任等级 信任条件 允许的访问范围 降低条件 高信任(Managed + Compliant) 企业托管设备,通过所有合规检查 全部应用和数据 设备未更新或安全软件异常 中信任(Registered + Partial Compliance) 已注册设备,部分合规 非敏感应用和数据 设备恶意软件检测 低信任(Unregistered / Non-compliant) 未注册或不合规设备 仅限自服务门户 无 零信任(Unknown / Blocked) 未知设备或被明确阻止 无访问权限 N/A
Microsoft Intune 和 Azure AD 的设备信任评估流程如下:设备通过 Intune Enrollment 注册后,Intune 对设备进行合规性评估(包括操作系统版本、加密状态、安全软件状态、越狱/root 检测等),合规的设备在 Azure AD 中被标记为 Compliant,不合规的设备被标记为 Not Compliant。条件访问策略可以基于设备合规状态做出访问决策。
设备健康状态评估(UEM/MDM) 统一终端管理(Unified Endpoint Management, UEM)平台持续监控设备健康状态,并将状态变化报告给零信任架构的策略决策点。
评估维度 正常指标 异常指标 取证日志来源 操作系统版本 当前支持版本 已停止支持的版本 UEM 设备清单 安全补丁 最新补丁 缺少关键安全更新 UEM 合规报告 防病毒状态 运行且更新 停止/过期 EDR 控制台 磁盘加密 BitLocker/FileVault 启用 加密未启用或恢复密钥异常 UEM 合规报告 防火墙 启用 已禁用 设备安全基线 越狱/Root 未越狱/Root 已越狱/Root 移动管理日志 屏幕锁定 启用且密码复杂 未启用或密码简单 设备策略日志
curl -X GET "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" | jq '.value[] | {
deviceName: .deviceName,
complianceState: .complianceState,
lastSyncDateTime: .lastSyncDateTime,
osVersion: .osVersion,
jailBroken: .jailBroken,
encryptionDiscovered: .encryptionDiscovered,
threatProtectionEnabled: .threatProtectionEnabled
}' 设备证书与设备身份验证 设备证书是设备身份的密码学凭证。零信任架构中,设备通过 X.509 证书向身份提供者证明自身身份。设备证书的生命周期管理——注册、续期、吊销——是取证分析的重要关注点。
设备证书事件 取证意义 异常模式 证书签发(Enrollment) 新设备注册 大量设备短时间内注册 证书续期(Renewal) 正常生命周期维护 使用异常密钥续期 证书吊销(Revocation) 设备信任降级 批量吊销后出现新设备 证书验证失败 设备身份伪造尝试 频繁的验证失败事件
openssl s_client -connect device-enrollment.company.com:443 -showcerts < /dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates -serial 终端检测与响应(EDR)集成 EDR 是设备层取证的核心数据源。零信任架构中,EDR 遥测数据与身份认证日志、网络流量日志关联,形成完整的取证视图。
EDR 遥测数据类型 取证用途 关联维度 进程创建/终止 恶意进程检测 用户身份、设备状态 文件操作 恶意文件投放检测 设备信任等级 注册表修改 持久化检测 设备合规状态 网络连接 C2 通信检测 网络分段策略 DNS 查询 DGA/隧道检测 网络代理日志 驱动加载 内核级攻击检测 设备证书状态
设备信任降级与撤销事件分析 设备信任降级是零信任架构中的关键安全事件。当设备的健康状态发生变化(如检测到恶意软件、安全软件被禁用、OS 版本过期)时,设备信任等级会自动降级,相应的访问权限也会被收回。
jq 'select(.eventSource == "DeviceCompliance" and .complianceState == "Noncompliant") | {
timestamp: .timestamp,
deviceName: .deviceName,
user: .userPrincipalName,
previousState: .previousComplianceState,
newState: .complianceState,
reason: .complianceReason
}' device_compliance_events.jsonBash 脚本:设备信任状态批量审计 #!/bin/bash
TENANT_ID= " ${ AZURE_TENANT_ID} "
CLIENT_ID= " ${ AZURE_CLIENT_ID} "
CLIENT_SECRET= " ${ AZURE_CLIENT_SECRET} "
TOKEN= $( curl -s -X POST "https://login.microsoftonline.com/ ${ TENANT_ID} /oauth2/v2.0/token" \
-d "client_id= ${ CLIENT_ID} &client_secret= ${ CLIENT_SECRET} &scope=https://graph.microsoft.com/.default" \
| jq -r '.access_token' )
echo "=== Device Compliance Summary ==="
curl -s -X GET "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?\$top=999" \
-H "Authorization: Bearer ${ TOKEN} " | jq '{
total: (.value | length),
compliant: [.value[] | select(.complianceState == "compliant")] | length,
noncompliant: [.value[] | select(.complianceState == "noncompliant")] | length,
conflict: [.value[] | select(.complianceState == "conflict")] | length,
error: [.value[] | select(.complianceState == "error")] | length
}'
echo ""
echo "=== High Risk: Non-compliant Devices ==="
curl -s -X GET "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?\$filter=complianceState eq 'noncompliant'&\$top=50" \
-H "Authorization: Bearer ${ TOKEN} " | jq '.value[] | {
device: .deviceName,
os: .operatingSystem,
version: .osVersion,
user: .userPrincipalName,
lastSync: .lastSyncDateTime
}'
echo ""
echo "=== Jailbroken/Rooted Devices ==="
curl -s -X GET "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?\$filter=jailBroken eq 'True'" \
-H "Authorization: Bearer ${ TOKEN} " | jq '.value[] | {
device: .deviceName,
platform: .managedDeviceOwnerType,
user: .userPrincipalName
}' Python 脚本:设备信任状态变化追踪 import json
import csv
from collections import defaultdict
from datetime import datetime
def track_device_trust_changes (events_file):
events = json. load(open(events_file))
device_history = defaultdict(list)
alerts = []
for event in events:
device_id = event. get("deviceId" )
device_history[device_id]. append({
"timestamp" : datetime. fromisoformat(event["timestamp" ]),
"complianceState" : event. get("complianceState" ),
"trustLevel" : event. get("trustLevel" ),
"event" : event. get("eventType" )
})
for device_id, history in device_history. items():
history. sort(key= lambda x: x["timestamp" ])
for i in range(1 , len(history)):
prev = history[i - 1 ]
curr = history[i]
if prev["complianceState" ] == "compliant" and curr["complianceState" ] == "noncompliant" :
alerts. append({
"device" : device_id,
"event" : "Trust Downgrade" ,
"from" : prev["complianceState" ],
"to" : curr["complianceState" ],
"timestamp" : curr["timestamp" ]. isoformat(),
"severity" : "HIGH"
})
if prev["trustLevel" ] == "high" and curr["trustLevel" ] in ("low" , "none" ):
alerts. append({
"device" : device_id,
"event" : "Trust Level Revoked" ,
"from" : prev["trustLevel" ],
"to" : curr["trustLevel" ],
"timestamp" : curr["timestamp" ]. isoformat(),
"severity" : "CRITICAL"
})
time_diff = (curr["timestamp" ] - prev["timestamp" ]). total_seconds()
if time_diff < 60 and curr["complianceState" ] == "noncompliant" :
alerts. append({
"device" : device_id,
"event" : "Rapid Compliance Change" ,
"details" : f "Two state changes within { time_diff: .0f } s" ,
"severity" : "HIGH"
})
return alerts 0x04 微隔离与网络分段取证分析 微隔离架构设计原则 微隔离(Micro-segmentation)是零信任网络层的核心技术。与传统的基于 VLAN 或子网的网络分段不同,微隔离在工作负载(Workload)级别实施访问控制,每一台服务器、每一个容器、每一个虚拟机都有独立的安全策略。
对比维度 传统网络分段 微隔离 控制粒度 子网/VLAN 级别 单个工作负载级别 策略定义 基于 IP/端口 基于身份+标签+应用 东西向流量 通常不控制 严格控制 策略执行 网络设备(防火墙/ACL) 主机代理 + SDN 动态适应 静态配置为主 动态标签驱动 取证数据 传统防火墙日志 主机代理遥测+策略决策日志
微隔离策略的核心思想是为每个工作负载定义"允许的通信白名单"。策略通常基于标签(Tag)而非 IP 地址来定义,这使得策略在工作负载迁移或扩缩容时仍然有效。例如,策略可以定义为"允许标签为 web 的工作负载访问标签为 api 的工作负载的 TCP 8443 端口",而无需关心具体的 IP 地址。
软件定义网络(SDN)中的微隔离实现 主流的微隔离技术实现方式包括:
实现技术 代表产品 工作层级 取证数据特点 主机代理模式 Illumio、Guardicore OS 内核级 详细的进程级网络事件 云原生安全组 AWS SG、Azure NSG、GCP FW 虚拟化层 API 调用日志+流日志 Service Mesh Istio/Envoy、Linkerd 应用层 L7 访问日志+TLS 握手 容器网络策略 Calico、Cilium、Calico 容器网络层 CNI 策略决策日志 SDN 控制器 VMware NSX、Cisco ACI 网络虚拟化层 策略变化+流量日志
在 Kubernetes 环境中,Calico 和 Cilium 是最常用的微隔离方案。以 Calico 为例,其 GlobalNetworkPolicy 和 NetworkPolicy 定义了 Pod 之间的通信规则:
apiVersion : projectcalico.org/v3
kind : GlobalNetworkPolicy
metadata :
name : deny-cross-namespace
spec :
selector : all()
order : 100
ingress :
- action : Allow
source :
namespaceSelector : kubernetes.io/metadata.name == "frontend"
destination :
namespaceSelector : kubernetes.io/metadata.name == "backend"
protocol : TCP
ports :
- 8443
egress :
- action : Allow
destination :
namespaceSelector : kubernetes.io/metadata.name == "kube-system"
protocol : UDP
ports :
- 53 微隔离策略日志分析 微隔离策略日志记录了每个被允许和被拒绝的网络通信事件。在大规模微隔离环境中,策略日志量可能非常庞大,需要通过筛选和聚合来提取有价值的取证信息。
# Calico flow log 分析
cat calico_flow_logs.json | jq 'select(.action == "deny") | {
timestamp: .timestamp,
src_pod: .meta.src_pod_name,
src_ns: .meta.src_namespace,
dst_pod: .meta.dst_pod_name,
dst_ns: .meta.dst_namespace,
proto: .meta.protocol,
dst_port: .meta.dst_port,
bytes: .bytes
}' | jq -s 'group_by(.src_ns, .dst_ns) | map({
source_ns: .[0].src_ns,
target_ns: .[0].dst_ns,
denied_count: length,
total_bytes: (map(.bytes) | add),
unique_src_pods: (map(.src_pod) | unique | length),
unique_dst_pods: (map(.dst_pod) | unique | length)
})' 横向移动检测在微隔离环境中的方法 微隔离的核心价值之一是限制横向移动。当攻击者尝试在微隔离环境中进行横向移动时,必然会产生策略拒绝(Deny)事件,这些事件是取证分析的重要线索。
横向移动阶段 MITRE ATT&CK 微隔离检测信号 端口扫描 T1046 大量来自同一源的 Deny 事件 远程服务利用 T1021 跨命名空间的 RDP/SSH/SMB Deny 横向工具传输 T1570 非常规端口的 Deny 事件 远程命令执行 T1059 WinRM/SSH 连接后紧接 Deny 的数据传输
# 检测微隔离环境中的端口扫描行为
cat calico_flow_logs.json | jq 'select(.action == "deny")' | \
jq -s 'group_by(.meta.src_pod_name) | map({
src_pod: .[0].meta.src_pod_name,
unique_dst_pods: (map(.meta.dst_pod_name) | unique | length),
unique_dst_ports: (map(.meta.dst_port) | unique | length),
total_denied: length
}) | map(select(.unique_dst_pods > 10 or .unique_dst_ports > 20)) | sort_by(.total_denied) | reverse' 网络分段违规事件取证 网络分段违规是指实际网络流量违反了既定分段策略的情况。这类违规可能源于配置错误、策略变更或恶意活动,取证分析需要区分这三种原因。
Sigma 规则:检测微隔离违规 title : 零信任环境 - 微隔离Deny事件异常激增
id : 9c5d3e4f-6071-8901-cdef-345678901234
status : experimental
description : 检测微隔离策略Deny事件在短时间内异常激增,可能指示横向移动扫描
author : x7peeps
date : 2026 /07/11
tags :
- attack.lateral_movement
- attack.t1046
- zero_trust
- micro_segmentation
logsource :
product : calico
service : flow_log
detection :
deny_events :
action : deny
timeframe : 5m
condition : deny_events | count() by meta.src_pod_name > 100
falsepositives :
- 新部署的服务在收敛过程中的正常Deny事件
level : high title : 零信任环境 - 跨分段拒绝访问
id : 0d6e4f5a-7182-9012-defa-456789012345
status : experimental
description : 检测跨安全分段的高频拒绝访问事件
author : x7peeps
date : 2026 /07/11
tags :
- attack.lateral_movement
- attack.t1021
- zero_trust
logsource :
product : nsx
service : distributed_firewall
detection :
selection :
action : deny
direction : inbound
timeframe : 10m
condition : selection | count() by source_ip > 50
falsepositives :
- 应用部署期间的临时通信尝试
level : medium 0x05 ZTNA与SDP安全取证分析 零信任网络访问(ZTNA)架构 ZTNA(Zero Trust Network Access)是零信任架构在网络访问层面的具体实现。与传统 VPN 不同,ZTNA 不提供对整个网络的访问,而是仅授权用户访问特定的应用。ZTNA 的核心组件包括策略引擎(Policy Engine)、策略代理(Policy Broker)和策略执行点(Policy Enforcement Point)。
对比维度 传统 VPN ZTNA 访问范围 整个网络或子网 仅限授权应用 信任模型 连入即信任 持续验证 网络可见性 VPN 网关可见全部流量 仅可见已授权应用流量 微隔离集成 需额外部署 原生集成 取证数据 VPN 连接日志 丰富的应用级访问日志
软件定义边界(SDP)组件与流程 SDP(Software Defined Perimeter)是零信任网络访问的一种实现框架,由 Cloud Security Alliance(CSA)提出。SDP 的核心概念是"先认证,后连接"(Authenticate-Then-Connect),在用户通过身份认证和设备验证之前,应用服务器在网络上是完全不可见的。
SDP 组件 功能 取证关注点 SDP Controller 策略决策与管理 策略变更日志、管理操作审计 SDP Gateway 流量代理与执行 连接日志、策略执行日志 SDP Host(客户端) 身份验证与设备状态报告 客户端状态变化、认证日志 Identity Provider 用户身份认证 认证事件、MFA 事件
隐身网关与单包授权(SPA) SDP 的核心技术之一是单包授权(Single Packet Authorization,SPA)。SPA 使用加密的单个 UDP 数据包来验证客户端身份并授权网络访问。在 SPA 之前,SDP Gateway 的所有端口对外部扫描都是不可见的,实现了真正的网络隐身。
SPA 数据包结构包含以下关键字段:
SPA 字段 安全功能 取证价值 Random 防重放攻击 验证 SPA 包的唯一性 Timestamp 防重放攻击 确定 SPA 包的发送时间 Life 有效期控制 确定授权的有效期 Username 身份标识 关联到具体用户 Method 请求类型 确定请求的操作类型(Access/Nonce等) Source IP 源地址验证 确认请求来源 HMAC 完整性验证 验证 SPA 包未被篡改
ZTNA 会话日志取证分析 ZTNA 会话日志记录了每次应用访问的完整上下文信息,是零信任取证中最丰富的数据源之一。
import json
from collections import defaultdict
def analyze_ztna_sessions (log_file):
sessions = json. load(open(log_file))
user_sessions = defaultdict(list)
anomalies = []
for session in sessions:
user = session. get("user" )
user_sessions[user]. append(session)
for user, sessions_list in user_sessions. items():
sessions_list. sort(key= lambda x: x["startTime" ])
for i in range(1 , len(sessions_list)):
prev = sessions_list[i - 1 ]
curr = sessions_list[i]
prev_end = prev. get("endTime" , curr["startTime" ])
if isinstance(prev_end, str):
from datetime import datetime
prev_end = datetime. fromisoformat(prev_end)
curr_start = datetime. fromisoformat(curr["startTime" ]) if isinstance(curr["startTime" ], str) else curr["startTime" ]
if prev["accessedApp" ] == curr["accessedApp" ]:
time_gap = (curr_start - prev_end). total_seconds() if isinstance(prev_end, type(curr_start)) else 0
if time_gap < 1 and time_gap >= 0 :
anomalies. append({
"user" : user,
"type" : "Rapid Reconnection" ,
"app" : curr["accessedApp" ],
"gap_seconds" : time_gap
})
if curr. get("deviceTrustScore" , 100 ) < 50 :
anomalies. append({
"user" : user,
"type" : "Low Device Trust" ,
"device" : curr. get("deviceName" ),
"trustScore" : curr. get("deviceTrustScore" ),
"app" : curr. get("accessedApp" ),
"severity" : "HIGH"
})
if curr. get("geoLocation" ) != prev. get("geoLocation" ):
anomalies. append({
"user" : user,
"type" : "Geographic Change" ,
"from" : prev. get("geoLocation" ),
"to" : curr. get("geoLocation" ),
"severity" : "MEDIUM"
})
return anomalies SDP 控制器安全事件检测 SDP 控制器是零信任架构的大脑,其安全事件直接关系到整个零信任体系的完整性。需要监控的关键事件包括:策略变更(Policy Change)、管理员操作(Admin Operation)、异常认证失败(Authentication Failure)和系统完整性校验(Integrity Check)。
0x06 IAM与条件访问策略取证 身份与访问管理(IAM)架构 IAM(Identity and Access Management)是零信任架构的身份核心。零信任 IAM 的关键区别在于:身份不再是一次性验证的静态属性,而是持续评估的动态信号。
IAM 组件 传统 IAM 零信任 IAM 认证频率 登录时一次性 持续/风险驱动 授权模型 RBAC(角色) RBAC + ABAC + Risk-Based 会话管理 长会话 短会话 + 频繁重认证 设备感知 无 设备身份+状态纳入决策 服务认证 静态 API Key 动态 Token + mTLS
条件访问策略引擎工作原理 条件访问策略引擎是零信任架构中的决策中枢。策略评估基于多维度信号的组合逻辑:
IF (用户 IN 高风险组 OR 位置 IN 未知位置)
AND (应用 IN [高敏感应用])
AND (设备.合规状态 == false OR 设备.信任等级 < 中)
THEN
REJECT 或 REQUIRE_STEP_UP_AUTH
ELSE
ALLOW策略引擎的日志记录了每次策略评估的输入信号和决策结果,是取证分析的重要数据源。
RBAC/ABAC 策略执行日志分析 基于角色的访问控制(RBAC)和基于属性的访问控制(ABAC)是零信任架构中两种主要的授权模型。取证分析需要关注以下模式:
异常模式 检测方法 风险等级 角色越权(Privilege Escalation) 用户在短时间内获得多个高级角色 高 权限抖动(Permission Flapping) 权限在授予和撤销之间快速切换 中 非工作时间授权 在非工作时间授予敏感权限 中 越权访问(Broken Access Control) ABAC 属性值被篡改以获取未授权访问 高 服务账号权限膨胀 服务账号获得超出功能需求的权限 高
特权访问管理(PAM)日志取证 特权访问管理(Privileged Access Management)是零信任架构中保护特权账户的关键机制。PAM 系统通过凭证保险库(Credential Vault)、即时访问(Just-In-Time Access)和会话录制(Session Recording)来控制和审计特权访问。
# PAM 日志分析:检测异常特权会话
cat pam_session_logs.json | jq 'select(
.sessionType == "interactive" and
(.targetSystem == "database" or .targetSystem == "domain_controller")
) | {
timestamp: .startTime,
user: .requestor,
target: .targetSystem,
target_account: .targetAccount,
duration_seconds: (.durationSeconds),
commands_executed: (.commandCount),
data_transferred: (.bytesTransferred)
}' | jq -s 'sort_by(.timestamp) | reverse | .[:20]' Sigma 规则:检测权限异常 title : 零信任环境 - 特权角色批量授予检测
id : 1e7f6a5b-8293-0123-efab-567890123456
status : experimental
description : 检测用户在短时间内被授予多个特权角色,可能指示权限提升攻击
author : x7peeps
date : 2026 /07/11
tags :
- attack.privilege_escalation
- attack.t1098
- zero_trust
- iam
logsource :
product : azure
service : auditlogs
detection :
selection :
operationName : "Add member to role"
properties.targetResources[*].type : "Group"
properties.targetResources[*].displayName|contains :
- "Global Admin"
- "Exchange Admin"
- "SharePoint Admin"
- "User Admin"
timeframe : 30m
condition : selection | count() by initiatedBy.userPrincipalName > 2
falsepositives :
- 正常的管理员角色分配流程
level : critical 0x07 零信任环境下的日志关联与时间线构建 零信任日志源分类 零信任架构的日志源横跨多个维度,取证分析需要将这些分散的日志源关联起来才能还原完整的攻击链。
日志源类别 具体日志类型 关键字段 日志量级(万级用户) 身份日志 IdP 登录/注销日志 用户、IP、时间、MFA、设备 50万-200万条/日 设备日志 UEM 合规日志、EDR 遥测 设备ID、状态、事件类型 100万-500万条/日 网络日志 微隔离流量日志、代理日志 源/目标 IP、端口、协议、动作 1000万-1亿条/日 应用日志 ZTNA 会话日志、API 审计 用户、应用、操作、响应码 50万-1000万条/日 数据日志 DLP 事件、加密操作日志 用户、文件、操作、数据分类 10万-100万条/日 策略日志 条件访问决策日志、策略引擎 策略ID、输入信号、决策结果 200万-800万条/日
多源日志关联分析方法 零信任环境中的多源日志关联是取证分析的核心技术。关联维度包括:
时间关联 :以事件时间戳为主键,将不同日志源的事件按时间顺序排列,识别事件之间的因果关系。
身份关联 :以用户标识(User Principal Name、Employee ID)为主键,将同一用户在不同系统中的行为串联起来。
设备关联 :以设备标识(Device ID、MAC Address、证书指纹)为主键,将同一设备上不同用户的行为串联起来。
网络关联 :以 IP 地址为主键,将网络流量与身份认证、设备状态关联。
时间线构建技术 零信任环境的时间线构建需要解决以下技术挑战:
时钟偏移校正(Skew Correction) :不同系统的时钟可能存在毫秒到分钟级的偏差。在关联分析前,需要识别并校正时钟偏移。常用方法包括:NTP 同步日志分析、已知关联事件的统计校正。
事件排序(Event Sequencing) :当两个事件的时间戳完全相同时,需要根据事件的因果逻辑确定正确的顺序。例如,设备合规检查(Device Compliance Check)应该在条件访问决策(Conditional Access Decision)之前。
日志完整性验证 :零信任环境中的日志可能被攻击者篡改或删除。需要通过日志哈希链、日志转发到远程 SIEM 等机制确保日志完整性。
异常行为基线建立与偏差检测 零信任环境取证的一个重要能力是建立正常行为基线,并检测偏离基线的异常行为。
基线维度 正常行为特征 异常偏离模式 检测方法 访问时间 工作日 9:00-18:00 凌晨/周末访问 统计分析 访问应用 固定的应用集合 新应用首次访问 集合差异 访问频率 稳定的请求频率 突发高频请求 时序异常检测 数据量 稳定的数据传输量 大量数据上传/下载 阈值检测 位置 常驻城市 罕见地理位置 地理异常
Python 日志关联脚本 import json
from datetime import datetime, timedelta
from collections import defaultdict
class ZeroTrustLogCorrelator :
def __init__ (self):
self. events = []
self. correlations = []
def load_idp_logs (self, filepath):
with open(filepath) as f:
for line in f:
event = json. loads(line)
self. events. append({
"source" : "idp" ,
"timestamp" : datetime. fromisoformat(event["timestamp" ]),
"user" : event["userPrincipalName" ],
"ip" : event["ipAddress" ],
"event_type" : event["status" ]. get("errorCode" ),
"mfa_result" : event. get("mfaDetail" , {}). get("authResult" ),
"device_id" : event. get("deviceId" ),
"raw" : event
})
def load_edr_logs (self, filepath):
with open(filepath) as f:
for line in f:
event = json. loads(line)
self. events. append({
"source" : "edr" ,
"timestamp" : datetime. fromisoformat(event["timestamp" ]),
"user" : event. get("processUser" ),
"device_id" : event. get("deviceId" ),
"event_type" : event["eventType" ],
"process_name" : event. get("processName" ),
"process_path" : event. get("processPath" ),
"raw" : event
})
def load_network_logs (self, filepath):
with open(filepath) as f:
for line in f:
event = json. loads(line)
self. events. append({
"source" : "network" ,
"timestamp" : datetime. fromisoformat(event["timestamp" ]),
"src_ip" : event["src_ip" ],
"dst_ip" : event["dst_ip" ],
"dst_port" : event["dst_port" ],
"action" : event["action" ],
"bytes" : event. get("bytes" , 0 ),
"raw" : event
})
def correlate_by_user (self, time_window_minutes= 30 ):
user_events = defaultdict(list)
for event in self. events:
if "user" in event and event["user" ]:
user_events[event["user" ]]. append(event)
for user, events in user_events. items():
events. sort(key= lambda x: x["timestamp" ])
for i in range(len(events)):
window_events = [
e for e in events
if e["timestamp" ] >= events[i]["timestamp" ] and
e["timestamp" ] <= events[i]["timestamp" ] + timedelta(minutes= time_window_minutes)
]
sources = set(e["source" ] for e in window_events)
if len(sources) >= 2 :
self. correlations. append({
"user" : user,
"trigger_event" : events[i],
"correlated_events" : window_events,
"sources_involved" : list(sources),
"time_span_minutes" : time_window_minutes
})
return self. correlations
def detect_anomalous_patterns (self):
anomalies = []
user_event_counts = defaultdict(lambda : defaultdict(int))
for event in self. events:
if "user" in event and event["user" ]:
key = f " { event['source' ]} : { event. get('event_type' , 'unknown' )} "
user_event_counts[event["user" ]][key] += 1
for user, counts in user_event_counts. items():
for event_key, count in counts. items():
if "idp:500126" in event_key and count > 10 :
anomalies. append({
"user" : user,
"anomaly" : "Excessive failed authentications" ,
"count" : count,
"severity" : "HIGH"
})
if "idp:0" in event_key and count > 50 :
anomalies. append({
"user" : user,
"anomaly" : "Excessive successful authentications" ,
"count" : count,
"severity" : "MEDIUM"
})
return anomalies
def build_timeline (self):
self. events. sort(key= lambda x: x["timestamp" ])
timeline = []
for event in self. events:
timeline. append({
"time" : event["timestamp" ]. isoformat(),
"source" : event["source" ],
"user" : event. get("user" , "N/A" ),
"event_type" : event. get("event_type" , event. get("action" , "N/A" )),
"details" : {k: v for k, v in event. items()
if k not in ("source" , "timestamp" , "user" , "event_type" , "raw" )}
})
return timeline
def export_timeline (self, output_file):
timeline = self. build_timeline()
with open(output_file, "w" ) as f:
json. dump(timeline, f, indent= 2 , default= str)
print(f "Timeline exported to { output_file} ( { len(timeline)} events)" ) 0x08 零信任架构下的横向移动检测 传统横向移动 vs 零信任环境横向移动 在传统网络环境中,攻击者获取初始立足点后可以通过网络扫描、凭证窃取和远程服务利用来实现横向移动。零信任架构通过微隔离、持续验证和最小权限原则极大地限制了传统横向移动手法的有效性。
横向移动手法 传统环境有效性 零信任环境有效性 零信任检测手段 网络扫描(T1046) 高 极低(微隔离阻断) 微隔离 Deny 日志 Pass-the-Hash(T1550.002) 高 中(需要设备+身份双重验证) 认证链日志分析 Pass-the-Token(T1550.005) 高 中(Token 绑定设备) Token 使用模式分析 远程服务利用(T1021) 高 低(ZTNA 精准授权) ZTNA 访问日志 横向工具传输(T1570) 高 低(DLP+微隔离) 数据流日志分析 内网代理(T1090) 中 极低(持续验证) 代理日志异常检测
基于身份的横向移动检测 在零信任环境中,身份是横向移动检测的核心维度。攻击者窃取凭据后使用该凭据访问其他资源时,会产生与合法用户不同的行为模式。
Token 窃取后的异常行为特征 :
异常行为 正常基线 异常指标 检测日志源 并发会话 同时最多 2-3 个活跃会话 同一身份 5+ 并发会话 IdP Session Log 地理跳跃 15分钟内城市不变 15分钟内跨城市 IdP Sign-in Log 应用访问模式 访问固定应用集合 突然访问高权限应用 应用访问日志 时间模式 工作日工作时间 深夜/节假日活跃 所有身份日志 设备指纹 常用 2-3 台设备 突然出现新设备 设备信任日志
基于设备信任的异常检测 零信任架构中的设备信任降级可以作为横向移动的间接指标。攻击者在控制一台设备后,可能破坏设备的安全状态(如禁用 EDR、卸载管理代理),导致设备信任等级下降。
# 检测设备信任降级后紧接着的身份认证事件
cat device_trust_events.json | jq 'select(.event == "trust_downgrade")' | \
while read -r event; do
device_id= $( echo " $event" | jq -r '.deviceId' )
downgrade_time= $( echo " $event" | jq -r '.timestamp' )
echo "Device $device_id trust downgraded at $downgrade_time"
cat azure_ad_signin.log | jq --arg did " $device_id" --arg dt " $downgrade_time" \
'select(.deviceId == $did and .timestamp > $dt and .status.errorCode == 0) |
{user: .userPrincipalName, app: .appDisplayName, time: .timestamp}'
done 微隔离逃逸检测技术 微隔离逃逸是指攻击者绕过微隔离策略限制的行为。常见的逃逸手法包括:利用允许的通信通道进行数据渗出(C2 over allowed protocols)、利用合法应用的 SSRF 漏洞进行内网探测、篡改主机代理的策略缓存。
横向移动攻击链重建方法 在零信任环境中重建横向移动攻击链需要综合以下数据源:
初始入侵 → 身份认证日志(首次异常登录)
↓
凭据窃取 → EDR 遥测(Mimikatz/LSASS 访问)
↓
设备信任降级 → UEM 日志(安全软件被禁用)
↓
横向移动尝试 → 微隔离日志(Deny 事件)
↓
横向移动成功 → ZTNA 日志(新应用访问)
↓
数据访问 → 应用日志(敏感数据查询)0x09 证据强度分层与案例关联 在零信任环境的取证分析中,不同类型的证据具有不同的可信度和确定性。需要对发现的证据进行分层分类,以便准确评估事件的严重性和制定响应措施。
确认恶意(CRITICAL) 以下证据可以直接确认恶意行为,需要立即响应:
证据类型 具体指标 置信度 响应措施 确认的身份冒用 同一身份在不可能旅行距离内同时认证 >99% 立即禁用账户,强制全局密码重置 确认的策略绕过 条件访问策略被绕过且产生未授权访问 >95% 隔离受影响资源,审计所有策略变更 确认的 Token 窃取 被盗 Token 在新设备上成功使用 >95% 撤销所有会话,重新认证 确认的微隔离逃逸 策略代理被篡改以允许未授权通信 >90% 隔离受损节点,重建策略 确认的设备接管 设备管理代理被卸载或禁用 >85% 隔离设备,强制重新注册
高度可疑(HIGH) 以下证据强烈暗示恶意活动,需要进一步验证:
证据类型 具体指标 置信度 验证方法 异常登录模式 非工作时间的多次认证尝试 70-90% 用户确认、辅助日志验证 设备信任异常降级 合规设备突然变为不合规 60-85% EDR 详细日志、设备取证 MFA 疲劳攻击模式 短时间内大量 MFA 推送 80-95% MFA 日志详细分析 权限异常授予 用户获得非预期的高权限 60-80% IAM 审计、管理员确认 异常数据访问 大量敏感数据下载/外传 70-90% 数据分类审计、DLP 日志
需要关注(MEDIUM/LOW) 以下证据需要关注但可能是正常行为:
证据类型 具体指标 置信度 处理方式 策略配置偏离 条件访问策略与基线不一致 30-50% 策略审查、变更审计 异常认证尝试频率 认证尝试频率高于基线 40-60% 持续监控、用户确认 新设备首次注册 前所未见的设备注册事件 20-40% 自助注册流程审计 低风险策略拒绝 微隔离 Deny 但无后续行为 10-30% 定期审查、趋势分析 会话持续时间异常 会话时间明显长于平均值 30-50% 用户行为分析
证据关联矩阵与可信度评估 当多个低置信度证据同时出现时,通过证据关联可以显著提升整体置信度。
证据组合 组合后置信度 推理逻辑 异常登录 + 设备信任降级 HIGH(>85%) 攻击者先入侵设备再利用凭据 MFA 疲劳 + 新设备登录 HIGH(>90%) 攻击者获取凭据后尝试绕过 MFA 策略变更 + 异常数据访问 CRITICAL(>95%) 攻击者修改策略以实现数据窃取 微隔离 Deny + 端口扫描模式 HIGH(>80%) 攻击者在微隔离环境中侦查 权限授予 + 非工作时间 MEDIUM(>60%) 可能的内部威胁或凭证盗用
0x0A 自动化检测与狩猎 Sigma 规则:零信任环境异常检测规则 规则1:零信任环境 - 条件访问策略批量变更
title : 零信任环境 - 条件访问策略批量变更
id : 2f8a7b6c-9304-1234-fabc-678901234567
status : experimental
description : 检测条件访问策略在短时间内被批量修改,可能指示攻击者试图绕过访问控制
author : x7peeps
date : 2026 /07/11
tags :
- attack.defense_evasion
- attack.t1562
- zero_trust
- conditional_access
logsource :
product : azure
service : auditlogs
detection :
selection :
operationName :
- "Update conditional access policy"
- "Create conditional access policy"
- "Delete conditional access policy"
timeframe : 15m
condition : selection | count() by initiatedBy.userPrincipalName > 3
falsepositives :
- 合法的策略批量部署
level : critical 规则2:零信任环境 - 设备信任状态异常批量变化
title : 零信任环境 - 设备合规状态批量异常变化
id : 3a9b8c7d-0415-2345-abcd-789012345678
status : experimental
description : 检测大量设备在短时间内从合规变为不合规,可能指示攻击者批量破坏设备安全状态
author : x7peeps
date : 2026 /07/11
tags :
- attack.impact
- attack.t1562.001
- zero_trust
- device_compliance
logsource :
product : intune
service : device_compliance
detection :
selection :
complianceState : "noncompliant"
timeframe : 1h
condition : selection | count() > 20
falsepositives :
- 企业统一推送安全更新导致设备暂时不合规
level : high 规则3:零信任环境 - ZTNA 会话异常
title : 零信任环境 - ZTNA异常高并发会话检测
id : 4b0c9d8e-1526-3456-bcde-890123456789
status : experimental
description : 检测同一用户在ZTNA中创建异常高数量的并发会话,可能指示Token盗用或自动化攻击
author : x7peeps
date : 2026 /07/11
tags :
- attack.credential_access
- attack.t1550.004
- zero_trust
- ztna
logsource :
product : zscaler
service : ztna_session
detection :
selection :
event_type : "session_create"
timeframe : 5m
condition : selection | count() by user > 15
falsepositives :
- 自动化脚本或监控探针的正常轮询
level : high Bash 脚本:零信任日志自动化收集与分析 #!/bin/bash
REPORT_DIR= "/tmp/ztna_forensics_ $( date +%Y%m%d_%H%M%S) "
mkdir -p " ${ REPORT_DIR} /identity" " ${ REPORT_DIR} /device" " ${ REPORT_DIR} /network"
TENANT_ID= " ${ AZURE_TENANT_ID} "
CLIENT_ID= " ${ AZURE_CLIENT_ID} "
CLIENT_SECRET= " ${ AZURE_CLIENT_SECRET} "
TOKEN= $( curl -s -X POST "https://login.microsoftonline.com/ ${ TENANT_ID} /oauth2/v2.0/token" \
-d "client_id= ${ CLIENT_ID} &client_secret= ${ CLIENT_SECRET} &scope=https://graph.microsoft.com/.default" \
| jq -r '.access_token' )
echo "[+] Collecting sign-in logs for the last 24 hours..."
SINCE= $( date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ)
curl -s -X GET "https://graph.microsoft.com/v1.0/auditLogs/signIns?\$filter=createdDateTime ge ${ SINCE} &\$top=999" \
-H "Authorization: Bearer ${ TOKEN} " > " ${ REPORT_DIR} /identity/signin_logs.json"
echo "[+] Analyzing MFA failure patterns..."
jq -s 'group_by(.userPrincipalName) | map({
user: .[0].userPrincipalName,
mfa_failures: [.[] | select(.status.errorCode == 500121 or .status.errorCode == 500125)] | length,
mfa_successes: [.[] | select(.status.errorCode == 0)] | length,
unique_ips: ([.[].ipAddress] | unique | length),
unique_cities: ([.[].locationDetails.city] | unique | length)
}) | map(select(.mfa_failures > 5)) | sort_by(.mfa_failures) | reverse' \
" ${ REPORT_DIR} /identity/signin_logs.json" > " ${ REPORT_DIR} /identity/mfa_analysis.json"
echo "[+] Collecting device compliance status..."
curl -s -X GET "https://graph.microsoft.com/v1.0/deviceManagement/managedDevices?\$top=999" \
-H "Authorization: Bearer ${ TOKEN} " > " ${ REPORT_DIR} /device/managed_devices.json"
jq '{
total: (.value | length),
compliant: [.value[] | select(.complianceState == "compliant")] | length,
noncompliant: [.value[] | select(.complianceState == "noncompliant")] | length,
not_checked_in_30d: [.value[] | select(
(.lastSyncDateTime | fromdateiso8601) < (now - 2592000)
)] | length
}' " ${ REPORT_DIR} /device/managed_devices.json" > " ${ REPORT_DIR} /device/compliance_summary.json"
echo "[+] Analyzing conditional access policy changes..."
curl -s -X GET "https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?\$filter=activityDisplayName eq 'Update conditional access policy' or activityDisplayName eq 'Create conditional access policy' or activityDisplayName eq 'Delete conditional access policy'&\$top=100" \
-H "Authorization: Bearer ${ TOKEN} " > " ${ REPORT_DIR} /identity/ca_policy_changes.json"
echo "[+] Generating forensic report..."
cat > " ${ REPORT_DIR} /report_summary.json" <<EOF
{
"report_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"analysis_period": "Last 24 hours",
"mfa_failures_flagged": $(jq 'length' "${REPORT_DIR}/identity/mfa_analysis.json"),
"noncompliant_devices": $(jq '.noncompliant' "${REPORT_DIR}/device/compliance_summary.json"),
"ca_policy_changes": $(jq 'if .value then .value | length else 0 end' "${REPORT_DIR}/identity/ca_policy_changes.json")
}
EOF
echo "[+] Report generated at: ${ REPORT_DIR} "
cat " ${ REPORT_DIR} /report_summary.json" Python 脚本:多源日志关联分析工具 import json
import sys
from datetime import datetime, timedelta
from collections import defaultdict, Counter
class ZTNAForensicsAnalyzer :
def __init__ (self):
self. findings = []
self. timeline = []
def analyze_signin_patterns (self, signin_file):
events = json. load(open(signin_file))
user_stats = defaultdict(lambda : {
"total" : 0 , "success" : 0 , "failure" : 0 ,
"ips" : set(), "cities" : set(), "devices" : set(),
"mfa_failures" : 0 , "timestamps" : []
})
for event in events:
user = event. get("userPrincipalName" , "unknown" )
stats = user_stats[user]
stats["total" ] += 1
stats["timestamps" ]. append(event. get("createdDateTime" ))
stats["ips" ]. add(event. get("ipAddress" , "" ))
city = event. get("locationDetails" , {}). get("city" , "" )
if city:
stats["cities" ]. add(city)
device = event. get("deviceId" , "" )
if device:
stats["devices" ]. add(device)
error_code = event. get("status" , {}). get("errorCode" )
if error_code == 0 :
stats["success" ] += 1
else :
stats["failure" ] += 1
if error_code in (500121 , 500125 ):
stats["mfa_failures" ] += 1
for user, stats in user_stats. items():
if stats["mfa_failures" ] > 5 :
self. findings. append({
"type" : "MFA_FATIGUE_RISK" ,
"severity" : "HIGH" ,
"user" : user,
"mfa_failures" : stats["mfa_failures" ],
"unique_ips" : len(stats["ips" ]),
"unique_cities" : len(stats["cities" ])
})
if len(stats["ips" ]) > 10 :
self. findings. append({
"type" : "IP_DIVERSITY_ANOMALY" ,
"severity" : "MEDIUM" ,
"user" : user,
"unique_ips" : len(stats["ips" ]),
"unique_cities" : len(stats["cities" ])
})
if len(stats["cities" ]) > 3 :
self. findings. append({
"type" : "IMPOSSIBLE_TRAVEL_SUSPECT" ,
"severity" : "HIGH" ,
"user" : user,
"unique_cities" : list(stats["cities" ])
})
def analyze_device_compliance (self, device_file):
devices = json. load(open(device_file))
noncompliant = []
stale_devices = []
for device in devices. get("value" , []):
if device. get("complianceState" ) == "noncompliant" :
noncompliant. append({
"device" : device. get("deviceName" ),
"user" : device. get("userPrincipalName" ),
"os" : device. get("operatingSystem" ),
"lastSync" : device. get("lastSyncDateTime" )
})
if device. get("lastSyncDateTime" ):
last_sync = datetime. fromisoformat(device["lastSyncDateTime" ]. replace("Z" , "+00:00" ))
if datetime. now(last_sync. tzinfo) - last_sync > timedelta(days= 30 ):
stale_devices. append({
"device" : device. get("deviceName" ),
"user" : device. get("userPrincipalName" ),
"days_stale" : (datetime. now(last_sync. tzinfo) - last_sync). days
})
if len(noncompliant) > 20 :
self. findings. append({
"type" : "BULK_NONCOMPLIANT_DEVICES" ,
"severity" : "HIGH" ,
"count" : len(noncompliant),
"devices" : noncompliant[:10 ]
})
if stale_devices:
self. findings. append({
"type" : "STALE_DEVICES" ,
"severity" : "MEDIUM" ,
"count" : len(stale_devices),
"oldest_days" : max(d["days_stale" ] for d in stale_devices)
})
def generate_report (self):
report = {
"analysis_time" : datetime. utcnow(). isoformat(),
"total_findings" : len(self. findings),
"findings_by_severity" : Counter(f["severity" ] for f in self. findings),
"findings" : sorted(self. findings, key= lambda x: {
"CRITICAL" : 0 , "HIGH" : 1 , "MEDIUM" : 2 , "LOW" : 3
}. get(x["severity" ], 4 ))
}
return report
if __name__ == "__main__" :
if len(sys. argv) < 3 :
print("Usage: python ztna_forensics.py <signin_file> <device_file> [output_file]" )
sys. exit(1 )
analyzer = ZTNAForensicsAnalyzer()
analyzer. analyze_signin_patterns(sys. argv[1 ])
analyzer. analyze_device_compliance(sys. argv[2 ])
report = analyzer. generate_report()
output = json. dumps(report, indent= 2 , default= str)
if len(sys. argv) > 3 :
with open(sys. argv[3 ], "w" ) as f:
f. write(output)
print(f "Report written to { sys. argv[3 ]} " )
else :
print(output) 0x0B 公开案例分析 案例1:SolarWinds供应链攻击中的零信任绕过分析(2020年) 攻击概述 :SolarWinds/SUNBURST 攻击是近年来最具影响力的供应链攻击之一。攻击者(APT29/Cozy Bear)通过污染 SolarWinds Orion 平台的软件更新包,将名为 SUNBURST 的后门植入到约 18,000 个 SolarWinds 客户端中。在多个成功渗透的环境中,企业已部署了零信任架构组件,但攻击者通过多层绕过策略成功规避了零信任控制。
攻击链与零信任绕过 :
攻击阶段 使用的 MITRE ATT&CK 技术 零信任绕过方式 初始入侵 T1195.002(供应链污染) 利用对 SolarWinds 更新的信任链,绕过软件白名单 建立持久化 T1546.003(WMI 事件订阅) 在已验证的设备上建立持久化,设备信任等级未受影响 凭据窃取 T1003.001(LSASS 内存转储) 在高信任设备上以合法进程执行凭据窃取 横向移动 T1021.002(SMB/Windows Admin Shares) 使用窃取的合法凭据通过零信任认证 C2 通信 T1071.001(Web 协议) 通过 DNS over HTTPS 混入正常 HTTPS 流量
取证发现 :
SUNBURST 后门在设备上运行时,设备始终处于"合规"状态,因为后门不修改设备安全配置 攻击者使用窃取的 SAML Token 进行身份认证,通过了所有条件访问检查 微隔离环境中,攻击者利用 SolarWinds 服务器之间已有的合法通信通道进行横向移动 最终,攻击者使用窃取的 OAuth Token 访问了目标组织的 Office 365 邮箱 IOC :
恶意 DLL:SolarWinds.Orion.Core.BusinessLayer.dll(被注入 SUNBURST 代码) C2 域名模式:avsvmcloud[.]com 及其子域名(DGA 生成) 后门通信端口:TCP 443(HTTPS) DNS TXT 记录查询用于 C2 通信 恶意 IP 范围:多个 AWS 和 Azure IP 地址(用于 SAML Token 签发) 经验教训 :
供应链信任不能作为零信任的例外——即使是经过签名验证的合法软件也需要运行时行为监控 零信任架构需要结合 EDR 行为检测能力,不能仅依赖网络层和身份层控制 SAML Token 和 OAuth Token 需要实施绑定机制(Token Binding),防止跨设备重放 微隔离策略需要考虑合法软件的异常行为模式,不能仅基于已知恶意特征 案例2:Colonial Pipeline攻击事件中的零信任缺失分析(2021年) 攻击概述 :Colonial Pipeline 于 2021 年 5 月遭受 DarkSide 勒索软件组织攻击,导致美国东海岸最大燃油输送管道停运数日。该事件揭示了关键基础设施中零信任架构缺失的严重后果。尽管 Colonial Pipeline 已部署了部分零信任组件(如 VPN 和基本的网络分段),但其零信任架构的实施存在显著缺陷。
攻击链与零信任缺陷 :
攻击阶段 MITRE ATT&CK 技术 零信任缺失点 初始入侵 T1078.006(VPN 凭据) VPN 使用单一密码认证,未启用 MFA 发现 T1087.002(域账户枚举) 内网无微隔离,域内可自由枚举 横向移动 T1021.001(RDP) IT/OT 网络之间缺乏有效分段 数据窃取 T1567.002(数据渗出到云存储) 无 DLP 控制,无出站数据审计 影响 T1486(数据加密勒索) 备份系统可从主网络访问并被加密
取证发现 :
VPN 账户使用了泄露的密码,且未启用 MFA,这是进入内网的唯一障碍 IT 网络和 OT 网络之间虽有防火墙,但策略过于宽松,允许大量端口通信 攻击者在内网横向移动时,几乎未遇到网络分段的阻断 DarkSide 组织在正式加密前已窃取了约 100GB 数据用于双重勒索 Colonial Pipeline 的零信任架构仅在最外层(VPN)有基本控制,内部完全缺失 IOC :
恶意软件:DarkSide 勒索软件变种 C2 域名:多个 Tor 隐藏服务地址 攻击者使用的工具:Cobalt Strike Beacon 数据外传地址:多个匿名化云存储服务 勒索信文件名:README.TXT 经验教训 :
VPN 单一密码认证在零信任架构中是不可接受的——必须启用 MFA IT/OT 网络分段需要基于零信任原则严格实施,东西向流量必须逐一验证 数据防泄漏(DLP)是零信任数据层的关键组件,缺失 DLP 等于允许攻击者自由窃取数据 关键基础设施的备份系统必须与生产网络完全隔离,确保攻击者无法横向移动到备份系统 案例3:Okta/Lapsus$攻击事件中的身份认证绕过分析(2022年) 攻击概述 :2022 年初,Lapsus$ 黑客组织成功入侵了 Okta 的客户支持系统,并利用该系统的访问权限间接影响了约 366 个 Okta 客户。Lapsus$ 的攻击手法不依赖传统的技术漏洞利用,而是通过社会工程学和 MFA 疲劳攻击等手段直接针对零信任架构的身份层。
攻击链与身份认证绕过 :
攻击阶段 MITRE ATT&CK 技术 零信任绕过方式 初始入侵 T1566.001(鱼叉式钓鱼) 获取 Okta 内部员工凭据 会话劫持 T1539(窃取 Web Session Cookie) 劫持 Okta 管理员的 Web 会话 MFA 绕过 T1621(MFA 疲劳攻击) 反复触发 MFA 推送直到管理员批准 权限提升 T1098(账户操纵) 在 Okta Admin Console 中修改条件访问策略 数据访问 T1530(从云存储对象获取数据) 利用修改后的条件访问策略访问客户数据 影响扩展 T1550.001(应用访问令牌) 使用窃取的 SAML Token 访问客户环境
取证发现 :
Lapsus$ 使用的社会工程手段使 Okta 支持人员在未充分验证身份的情况下提供了帮助 MFA 疲劳攻击在 Okta 平台上留下了清晰的日志痕迹:短时间内大量 MFA 推送请求 攻击者通过 Okta 管理控制台修改了多个客户的条件访问策略,降低了安全控制 部分客户因 Okta 的条件访问策略被修改而遭受进一步攻击 Okta 的审计日志记录了所有策略变更操作,但告警机制未能及时触发 IOC :
攻击者使用的 IP 地址范围(主要在英国和巴西) 攻击者使用的设备指纹(包含特定的浏览器 User-Agent 和屏幕分辨率) 被修改的条件访问策略 ID 列表 被访问的客户 Okta 租户列表 Lapsus$ 使用的 Tailscale VPN 和 Cloudflare WARP 出口 IP 经验教训 :
MFA 疲劳攻击是零信任身份层的现实威胁——需要实施 MFA 推送限速和异常检测 客户支持流程也需要纳入零信任框架——支持人员在提供服务前应验证请求者身份 零信任架构的管理平面(Admin Console)是最高价值目标,需要额外的安全控制 条件访问策略变更需要实施严格的变更管理和告警机制 作为 IdP 供应商,Okta 的安全事件具有级联效应——供应链中的身份提供商需要更严格的安全标准 0x0C 参考资料