2
0
Fork 0
mirror of https://github.com/carlospolop/hacktricks synced 2025-02-21 08:28:27 +00:00
hacktricks/pentesting-web/oauth-to-account-takeover.md

20 KiB

OAuth to Account takeover

Naucz się hackingu AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

{% embed url="https://websec.nl/" %}

Podstawowe informacje

OAuth oferuje różne wersje, z podstawowymi informacjami dostępnymi w OAuth 2.0 documentation. Ta dyskusja koncentruje się głównie na szeroko stosowanym OAuth 2.0 authorization code grant type, zapewniającym ramy autoryzacji, które umożliwiają aplikacji dostęp lub wykonywanie działań na koncie użytkownika w innej aplikacji (serwer autoryzacji).

Rozważmy hipotetyczną stronę https://example.com, zaprojektowaną do prezentowania wszystkich Twoich postów w mediach społecznościowych, w tym prywatnych. Aby to osiągnąć, stosowany jest OAuth 2.0. https://example.com poprosi o Twoją zgodę na dostęp do Twoich postów w mediach społecznościowych. W konsekwencji na https://socialmedia.com pojawi się ekran zgody, przedstawiający uprawnienia, o które się prosi, oraz dewelopera składającego prośbę. Po Twojej autoryzacji, https://example.com zyska możliwość dostępu do Twoich postów w Twoim imieniu.

Ważne jest, aby zrozumieć następujące komponenty w ramach OAuth 2.0:

  • resource owner: Ty, jako użytkownik/podmiot, autoryzujesz dostęp do swojego zasobu, np. postów na koncie w mediach społecznościowych.
  • resource server: Serwer zarządzający uwierzytelnionymi żądaniami po tym, jak aplikacja uzyska access token w imieniu resource owner, np. https://socialmedia.com.
  • client application: Aplikacja ubiegająca się o autoryzację od resource owner, taka jak https://example.com.
  • authorization server: Serwer, który wydaje access tokens do client application po pomyślnym uwierzytelnieniu resource owner i uzyskaniu autoryzacji, np. https://socialmedia.com.
  • client_id: Publiczny, unikalny identyfikator aplikacji.
  • client_secret: Poufny klucz, znany tylko aplikacji i serwerowi autoryzacji, używany do generowania access_tokens.
  • response_type: Wartość określająca typ żądanego tokena, np. code.
  • scope: Poziom dostępu, o który ubiega się client application od resource owner.
  • redirect_uri: URL, na który użytkownik jest przekierowywany po autoryzacji. Zazwyczaj musi być zgodny z wcześniej zarejestrowanym URL przekierowania.
  • state: Parametr do utrzymania danych podczas przekierowania użytkownika do i z serwera autoryzacji. Jego unikalność jest kluczowa dla pełnienia funkcji mechanizmu ochrony przed CSRF.
  • grant_type: Parametr wskazujący typ grantu i typ tokena, który ma zostać zwrócony.
  • code: Kod autoryzacyjny z authorization server, używany w połączeniu z client_id i client_secret przez aplikację kliencką do uzyskania access_token.
  • access_token: Token, którego aplikacja kliencka używa do żądań API w imieniu resource owner.
  • refresh_token: Umożliwia aplikacji uzyskanie nowego access_token bez ponownego pytania użytkownika.

Przebieg

Rzeczywisty przebieg OAuth wygląda następująco:

  1. Przechodzisz na https://example.com i wybierasz przycisk „Integrate with Social Media”.
  2. Strona wysyła żądanie do https://socialmedia.com prosząc o Twoją autoryzację, aby aplikacja https://example.com mogła uzyskać dostęp do Twoich postów. Żądanie jest skonstruowane jako:
https://socialmedia.com/auth
?response_type=code
&client_id=example_clientId
&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
&scope=readPosts
&state=randomString123
  1. Następnie zostanie wyświetlona strona zgody.
  2. Po zatwierdzeniu, Social Media wysyła odpowiedź do redirect_uri z parametrami code i state:
https://example.com?code=uniqueCode123&state=randomString123
  1. https://example.com wykorzystuje ten code, razem z client_id i client_secret, aby wykonać żądanie po stronie serwera w celu uzyskania access_token w Twoim imieniu, umożliwiając dostęp do uprawnień, na które wyraziłeś zgodę:
POST /oauth/access_token
Host: socialmedia.com
...{"client_id": "example_clientId", "client_secret": "example_clientSecret", "code": "uniqueCode123", "grant_type": "authorization_code"}
6. Finally, the process concludes as https://example.com employs your `access_token` to make an API call to Social Media to access

## Vulnerabilities <a href="#id-323a" id="id-323a"></a>

### Open redirect\_uri <a href="#cc36" id="cc36"></a>

`redirect_uri` jest kluczowy dla bezpieczeństwa w implementacjach OAuth i OpenID, ponieważ kieruje, gdzie wysyłane są wrażliwe dane, takie jak kody autoryzacyjne, po autoryzacji. Jeśli jest źle skonfigurowany, może pozwolić atakującym na przekierowanie tych żądań na złośliwe serwery, umożliwiając przejęcie konta.

Techniki eksploatacji różnią się w zależności od logiki walidacji serwera autoryzacyjnego. Mogą obejmować od ścisłego dopasowania ścieżki do akceptowania dowolnego URL w określonej domenie lub podkatalogu. Powszechne metody eksploatacji obejmują otwarte przekierowania, przejścia ścieżek, wykorzystywanie słabych wyrażeń regularnych i wstrzykiwanie HTML w celu kradzieży tokenów.

Oprócz `redirect_uri`, inne parametry OAuth i OpenID, takie jak `client_uri`, `policy_uri`, `tos_uri` i `initiate_login_uri`, są również podatne na ataki przekierowania. Te parametry są opcjonalne i ich wsparcie różni się w zależności od serwerów.

Dla tych, którzy celują w serwer OpenID, punkt odkrywania (`**.well-known/openid-configuration**`) często zawiera cenne szczegóły konfiguracyjne, takie jak `registration_endpoint`, `request_uri_parameter_supported` i `require_request_uri_registration`. Te szczegóły mogą pomóc w identyfikacji punktu rejestracji i innych specyfikacji konfiguracyjnych serwera.

### XSS in redirect implementation <a href="#bda5" id="bda5"></a>

Jak wspomniano w tym raporcie o bug bounty [https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html](https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html) może być możliwe, że **URL przekierowania jest odzwierciedlany w odpowiedzi** serwera po uwierzytelnieniu użytkownika, będąc **podatnym na XSS**. Możliwy ładunek do testowania:
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>

CSRF - Improper handling of state parameter

W implementacjach OAuth niewłaściwe użycie lub pominięcie parametru state może znacznie zwiększyć ryzyko ataków Cross-Site Request Forgery (CSRF). Ta podatność pojawia się, gdy parametr state jest nieużywany, używany jako wartość statyczna lub nie jest odpowiednio walidowany, co pozwala atakującym na obejście zabezpieczeń CSRF.

Atakujący mogą to wykorzystać, przechwytując proces autoryzacji, aby połączyć swoje konto z kontem ofiary, co może prowadzić do potencjalnych przejęć konta. Jest to szczególnie krytyczne w aplikacjach, gdzie OAuth jest używany do celów uwierzytelniania.

Przykłady tej podatności w rzeczywistych sytuacjach zostały udokumentowane w różnych wyzwaniach CTF i platformach hakerskich, co podkreśla jej praktyczne implikacje. Problem ten dotyczy również integracji z usługami zewnętrznymi, takimi jak Slack, Stripe i PayPal, gdzie atakujący mogą przekierowywać powiadomienia lub płatności na swoje konta.

Prawidłowe obsługiwanie i walidacja parametru state są kluczowe dla ochrony przed CSRF i zabezpieczenia przepływu OAuth.

Pre Account Takeover

  1. Bez weryfikacji e-maila przy tworzeniu konta: Atakujący mogą z wyprzedzeniem utworzyć konto, używając e-maila ofiary. Jeśli ofiara później użyje usługi zewnętrznej do logowania, aplikacja może nieumyślnie połączyć to konto zewnętrzne z wcześniej utworzonym kontem atakującego, prowadząc do nieautoryzowanego dostępu.
  2. Wykorzystywanie luźnej weryfikacji e-maila w OAuth: Atakujący mogą wykorzystać usługi OAuth, które nie weryfikują e-maili, rejestrując się w ich usłudze, a następnie zmieniając e-mail konta na e-mail ofiary. Ta metoda podobnie ryzykuje nieautoryzowany dostęp do konta, podobnie jak w pierwszym scenariuszu, ale przez inny wektor ataku.

Disclosure of Secrets

Identyfikacja i ochrona tajnych parametrów OAuth jest kluczowa. Podczas gdy client_id może być bezpiecznie ujawniony, ujawnienie client_secret niesie ze sobą znaczące ryzyko. Jeśli client_secret zostanie skompromitowany, atakujący mogą wykorzystać tożsamość i zaufanie aplikacji do kradzieży access_tokens użytkowników i prywatnych informacji.

Częstą podatnością jest sytuacja, gdy aplikacje błędnie obsługują wymianę kodu autoryzacyjnego (code) na access_token po stronie klienta zamiast po stronie serwera. Ten błąd prowadzi do ujawnienia client_secret, umożliwiając atakującym generowanie access_tokens pod pozorem aplikacji. Ponadto, poprzez inżynierię społeczną, atakujący mogą eskalować uprawnienia, dodając dodatkowe zakresy do autoryzacji OAuth, jeszcze bardziej wykorzystując zaufany status aplikacji.

Client Secret Bruteforce

Możesz spróbować bruteforce client_secret dostawcy usług z dostawcą tożsamości, aby spróbować ukraść konta.
Żądanie do BF może wyglądać podobnie do:

POST /token HTTP/1.1
content-type: application/x-www-form-urlencoded
host: 10.10.10.10:3000
content-length: 135
Connection: close

code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce]

Referer Header leaking Code + State

Gdy klient ma code i state, jeśli są one odzwierciedlone w nagłówku Referer podczas przeglądania innej strony, to jest podatny.

Access Token Stored in Browser History

Przejdź do historii przeglądarki i sprawdź, czy access token jest tam zapisany.

Everlasting Authorization Code

Authorization code powinien żyć tylko przez pewien czas, aby ograniczyć okno czasowe, w którym atakujący może go ukraść i użyć.

Authorization/Refresh Token not bound to client

Jeśli możesz uzyskać authorization code i użyć go z innym klientem, możesz przejąć inne konta.

Happy Paths, XSS, Iframes & Post Messages to leak code & state values

Sprawdź ten post

AWS Cognito

W tym raporcie z bug bounty: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ można zobaczyć, że token, który AWS Cognito zwraca użytkownikowi, może mieć wystarczające uprawnienia do nadpisania danych użytkownika. Dlatego, jeśli możesz zmienić email użytkownika na inny email, możesz być w stanie przejąć inne konta.

# Read info of the user
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]

# Change email address
aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ[...] --user-attributes Name=email,Value=imaginary@flickr.com
{
"CodeDeliveryDetailsList": [
{
"Destination": "i***@f***.com",
"DeliveryMedium": "EMAIL",
"AttributeName": "email"
}
]
}

Aby uzyskać bardziej szczegółowe informacje na temat wykorzystywania AWS Cognito, sprawdź:

{% embed url="https://cloud.hacktricks.xyz/pentesting-cloud/aws-pentesting/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum" %}

Wykorzystywanie tokenów innych aplikacji

Jak wspomniano w tym artykule, przepływy OAuth, które oczekują otrzymania tokenu (a nie kodu), mogą być podatne, jeśli nie sprawdzają, czy token należy do aplikacji.

Dzieje się tak, ponieważ atakujący może stworzyć aplikację obsługującą OAuth i zalogować się za pomocą Facebooka (na przykład) w swojej własnej aplikacji. Następnie, gdy ofiara zaloguje się za pomocą Facebooka w aplikacji atakującego, atakujący może uzyskać token OAuth użytkownika przyznany jego aplikacji i użyć go do zalogowania się w aplikacji OAuth ofiary, używając tokenu użytkownika ofiary.

{% hint style="danger" %} Dlatego, jeśli atakujący zdoła skłonić użytkownika do uzyskania dostępu do swojej własnej aplikacji OAuth, będzie mógł przejąć konto ofiary w aplikacjach, które oczekują tokenu i nie sprawdzają, czy token został przyznany ich ID aplikacji. {% endhint %}

Zgodnie z tym artykułem, możliwe było skłonienie ofiary do otwarcia strony z returnUrl wskazującym na hosta atakującego. Ta informacja byłaby przechowywana w cookie (RU) i w późniejszym kroku prompt zapyta użytkownika, czy chce dać dostęp do hosta atakującego.

Aby ominąć ten prompt, możliwe było otwarcie karty, aby zainicjować przepływ OAuth, który ustawiłby to cookie RU za pomocą returnUrl, zamknięcie karty przed wyświetleniem promptu i otwarcie nowej karty bez tej wartości. Wtedy prompt nie poinformuje o hoście atakującego, ale cookie będzie ustawione na niego, więc token zostanie wysłany do hosta atakującego w przekierowaniu.

Ominięcie interakcji z promptem

Jak wyjaśniono w tym filmie, niektóre implementacje OAuth pozwalają na wskazanie parametru GET prompt jako None (&prompt=none), aby zapobiec pytaniu użytkowników o potwierdzenie danego dostępu w promptie na stronie, jeśli są już zalogowani na platformie.

response_mode

Jak wyjaśniono w tym filmie, możliwe jest wskazanie parametru response_mode, aby określić, gdzie chcesz, aby kod został dostarczony w końcowym URL:

  • response_mode=query -> Kod jest dostarczany wewnątrz parametru GET: ?code=2397rf3gu93f
  • response_mode=fragment -> Kod jest dostarczany wewnątrz parametru fragmentu URL #code=2397rf3gu93f
  • response_mode=form_post -> Kod jest dostarczany wewnątrz formularza POST z inputem o nazwie code i wartością
  • response_mode=web_message -> Kod jest wysyłany w wiadomości post: window.opener.postMessage({"code": "asdasdasd...

Parametry SSRF

Sprawdź to badanie dla dalszych szczegółów tej techniki.

Dynamiczna rejestracja klienta w OAuth służy jako mniej oczywisty, ale krytyczny wektor dla luk bezpieczeństwa, szczególnie dla ataków Server-Side Request Forgery (SSRF). Ten endpoint pozwala serwerom OAuth na odbieranie szczegółów dotyczących aplikacji klienckich, w tym wrażliwych URL, które mogą być wykorzystane.

Kluczowe punkty:

  • Dynamiczna rejestracja klienta jest często mapowana na /register i akceptuje szczegóły takie jak client_name, client_secret, redirect_uris oraz URL dla logo lub JSON Web Key Sets (JWKs) za pomocą żądań POST.
  • Ta funkcja przestrzega specyfikacji określonych w RFC7591 i OpenID Connect Registration 1.0, które zawierają parametry potencjalnie podatne na SSRF.
  • Proces rejestracji może nieumyślnie narażać serwery na SSRF na kilka sposobów:
  • logo_uri: URL dla logo aplikacji klienckiej, który może być pobrany przez serwer, wywołując SSRF lub prowadząc do XSS, jeśli URL jest niewłaściwie obsługiwany.
  • jwks_uri: URL do dokumentu JWK klienta, który, jeśli jest złośliwie skonstruowany, może spowodować, że serwer wykona żądania wychodzące do serwera kontrolowanego przez atakującego.
  • sector_identifier_uri: Odnosi się do tablicy JSON redirect_uris, którą serwer może pobrać, tworząc możliwość SSRF.
  • request_uris: Lista dozwolonych URI żądań dla klienta, które mogą być wykorzystane, jeśli serwer pobiera te URI na początku procesu autoryzacji.

Strategia eksploatacji:

  • SSRF można wywołać, rejestrując nowego klienta z złośliwymi URL w parametrach takich jak logo_uri, jwks_uri lub sector_identifier_uri.
  • Chociaż bezpośrednia eksploatacja za pomocą request_uris może być ograniczona przez kontrole białej listy, dostarczenie wcześniej zarejestrowanego, kontrolowanego przez atakującego request_uri może ułatwić SSRF podczas fazy autoryzacji.

Warunki wyścigu dostawców OAuth

Jeśli platforma, którą testujesz, jest dostawcą OAuth, przeczytaj to, aby przetestować możliwe warunki wyścigu.

Referencje

{% embed url="https://websec.nl/" %}

Naucz się hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks: