OAuth to Account takeover
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
OAuth는 다양한 버전을 제공하며, 기본적인 통찰력은 OAuth 2.0 documentation에서 확인할 수 있습니다. 이 논의는 주로 널리 사용되는 OAuth 2.0 authorization code grant type에 중점을 두며, 애플리케이션이 다른 애플리케이션의 사용자 계정에 접근하거나 작업을 수행할 수 있도록 하는 인증 프레임워크를 제공합니다.
가상의 웹사이트 _https://example.com_을 고려해 보십시오. 이 사이트는 모든 소셜 미디어 게시물을 보여주기 위해 설계되었습니다, 개인적인 게시물도 포함됩니다. 이를 위해 OAuth 2.0이 사용됩니다. _https://example.com_은 소셜 미디어 게시물에 접근할 수 있는 권한을 요청합니다. 따라서 _https://socialmedia.com_에서 요청된 권한과 요청하는 개발자를 설명하는 동의 화면이 나타납니다. 귀하가 승인하면, _https://example.com_은 귀하를 대신하여 게시물에 접근할 수 있는 능력을 갖게 됩니다.
OAuth 2.0 프레임워크 내에서 다음 구성 요소를 이해하는 것이 중요합니다:
resource owner: 귀하, 즉 사용자/엔티티가 소셜 미디어 계정 게시물과 같은 리소스에 대한 접근을 승인합니다.
resource server: access token
을 확보한 후 인증된 요청을 관리하는 서버, 예: https://socialmedia.com.
client application: resource owner
로부터 권한을 요청하는 애플리케이션, 예: https://example.com.
authorization server: resource owner
의 성공적인 인증 후 client application
에 access tokens
를 발급하는 서버, 예: https://socialmedia.com.
client_id: 애플리케이션의 공개 고유 식별자.
client_secret: 애플리케이션과 인증 서버만 알고 있는 비밀 키로, access_tokens
를 생성하는 데 사용됩니다.
response_type: 요청된 토큰의 유형을 지정하는 값, 예: code
.
scope: client application
이 resource owner
로부터 요청하는 접근 수준.
redirect_uri: 사용자가 승인 후 리디렉션되는 URL. 일반적으로 사전 등록된 리디렉션 URL과 일치해야 합니다.
state: 사용자의 인증 서버로의 리디렉션 간 데이터를 유지하기 위한 매개변수. 고유성이 CSRF 보호 메커니즘으로서 중요합니다.
grant_type: 부여 유형 및 반환될 토큰 유형을 나타내는 매개변수.
code: authorization server
에서 발급된 인증 코드로, client application
이 access_token
을 얻기 위해 client_id
및 client_secret
과 함께 사용합니다.
access_token: resource owner
를 대신하여 API 요청에 사용하는 클라이언트 애플리케이션의 토큰.
refresh_token: 애플리케이션이 사용자에게 다시 요청하지 않고 새로운 access_token
을 얻을 수 있게 해줍니다.
실제 OAuth 흐름은 다음과 같이 진행됩니다:
귀하는 https://example.com으로 이동하여 “소셜 미디어와 통합” 버튼을 선택합니다.
사이트는 귀하의 게시물에 접근하기 위해 https://example.com의 애플리케이션이 귀하의 승인을 요청하는 요청을 https://socialmedia.com으로 보냅니다. 요청은 다음과 같이 구성됩니다:
그런 다음 동의 페이지가 표시됩니다.
승인이 완료되면 소셜 미디어는 redirect_uri
에 code
및 state
매개변수를 포함하여 응답을 보냅니다:
https://example.com은 이 code
를 사용하여 client_id
와 client_secret
과 함께 서버 측 요청을 만들어 귀하를 대신하여 access_token
을 얻어, 귀하가 동의한 권한에 대한 접근을 가능하게 합니다:
마지막으로, https://example.com이 귀하의 access_token
을 사용하여 소셜 미디어에 API 호출을 하여 접근합니다.
redirect_uri
는 OAuth 및 OpenID 구현에서 보안에 매우 중요하며, 이는 민감한 데이터(예: 인증 코드)가 인증 후 어디로 전송되는지를 지시합니다. 잘못 구성된 경우, 공격자가 이러한 요청을 악성 서버로 리디렉션할 수 있어 계정 탈취를 가능하게 합니다.
악용 기술은 인증 서버의 검증 논리에 따라 다릅니다. 이는 엄격한 경로 일치에서 지정된 도메인 또는 하위 디렉토리 내의 모든 URL을 수용하는 것까지 다양합니다. 일반적인 악용 방법에는 오픈 리디렉션, 경로 탐색, 약한 정규 표현식 악용, 토큰 탈취를 위한 HTML 주입이 포함됩니다.
redirect_uri
외에도 client_uri
, policy_uri
, tos_uri
, initiate_login_uri
와 같은 다른 OAuth 및 OpenID 매개변수도 리디렉션 공격에 취약합니다. 이러한 매개변수는 선택 사항이며, 서버마다 지원 여부가 다릅니다.
OpenID 서버를 목표로 하는 경우, 발견 엔드포인트(**.well-known/openid-configuration**
)는 종종 registration_endpoint
, request_uri_parameter_supported
, 및 "require_request_uri_registration
"과 같은 유용한 구성 세부정보를 나열합니다. 이러한 세부정보는 등록 엔드포인트 및 서버의 기타 구성 세부정보를 식별하는 데 도움이 될 수 있습니다.
이 버그 바운티 보고서 https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html에서 언급된 바와 같이, 리디렉션 URL이 사용자가 인증한 후 서버의 응답에 반영될 수 있으며, XSS에 취약할 수 있습니다. 테스트할 수 있는 가능한 페이로드:
OAuth 구현에서 state
매개변수의 오용 또는 누락은 교차 사이트 요청 위조(CSRF) 공격의 위험을 크게 증가시킬 수 있습니다. 이 취약점은 state
매개변수가 사용되지 않거나, 정적 값으로 사용되거나, 제대로 검증되지 않을 때 발생하여 공격자가 CSRF 보호를 우회할 수 있게 합니다.
공격자는 이를 이용해 권한 부여 프로세스를 가로채어 자신의 계정을 피해자의 계정과 연결할 수 있으며, 이는 잠재적인 계정 탈취로 이어질 수 있습니다. 이는 OAuth가 인증 목적으로 사용되는 애플리케이션에서 특히 중요합니다.
이 취약점의 실제 사례는 다양한 CTF 챌린지와 해킹 플랫폼에서 문서화되어 있으며, 그 실질적인 영향을 강조합니다. 이 문제는 Slack, Stripe, PayPal과 같은 제3자 서비스와의 통합에도 확장되어, 공격자가 알림이나 결제를 자신의 계정으로 리디렉션할 수 있습니다.
state
매개변수의 적절한 처리 및 검증은 CSRF로부터 보호하고 OAuth 흐름을 안전하게 유지하는 데 중요합니다.
계정 생성 시 이메일 검증 없이: 공격자는 피해자의 이메일을 사용하여 미리 계정을 생성할 수 있습니다. 피해자가 나중에 타사 서비스를 사용하여 로그인하면, 애플리케이션이 이 타사 계정을 공격자가 미리 생성한 계정에 우연히 연결할 수 있어 무단 접근이 발생할 수 있습니다.
느슨한 OAuth 이메일 검증 악용: 공격자는 이메일을 검증하지 않는 OAuth 서비스를 악용하여 자신의 서비스에 등록한 후 계정 이메일을 피해자의 이메일로 변경할 수 있습니다. 이 방법은 첫 번째 시나리오와 유사하게 무단 계정 접근의 위험을 초래하지만, 다른 공격 벡터를 통해 이루어집니다.
비밀 OAuth 매개변수를 식별하고 보호하는 것은 중요합니다. **client_id
**는 안전하게 공개할 수 있지만, **client_secret
**을 노출하는 것은 상당한 위험을 초래합니다. client_secret
이 유출되면 공격자는 애플리케이션의 신원과 신뢰를 악용하여 사용자 access_tokens
및 개인 정보를 탈취할 수 있습니다.
일반적인 취약점은 애플리케이션이 권한 부여 code
를 access_token
으로 교환하는 과정을 클라이언트 측에서 잘못 처리할 때 발생합니다. 이 실수는 client_secret
의 노출로 이어져, 공격자가 애플리케이션의 가장으로 access_tokens
를 생성할 수 있게 합니다. 또한, 사회 공학을 통해 공격자는 OAuth 권한 부여에 추가 범위를 추가하여 권한을 상승시킬 수 있으며, 애플리케이션의 신뢰된 상태를 더욱 악용할 수 있습니다.
서비스 제공자의 클라이언트 비밀을 무차별 대입하여 계정을 탈취하려고 시도할 수 있습니다. 무차별 대입 요청은 다음과 유사할 수 있습니다:
클라이언트가 코드와 상태를 가지고 있을 때, 만약 그것이 Referer 헤더에 반영된다면 다른 페이지로 이동할 때 취약합니다.
브라우저 기록으로 가서 액세스 토큰이 저장되어 있는지 확인하세요.
인증 코드는 공격자가 훔치고 사용할 수 있는 시간 창을 제한하기 위해 잠시만 존재해야 합니다.
인증 코드를 얻고 다른 클라이언트와 함께 사용할 수 있다면 다른 계정을 탈취할 수 있습니다.
이 버그 바운티 보고서에서: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/ AWS Cognito가 사용자에게 반환하는 토큰이 사용자 데이터를 덮어쓸 수 있는 충분한 권한을 가질 수 있습니다. 따라서, 다른 사용자 이메일로 사용자 이메일을 변경할 수 있다면, 다른 계정을 탈취할 수 있을지도 모릅니다.
For more detailed info about how to abuse AWS cognito check:
이 글에서 언급된 바와 같이, 토큰(코드가 아닌)을 수신할 것으로 예상되는 OAuth 흐름은 토큰이 앱에 속하는지 확인하지 않으면 취약할 수 있습니다.
이는 공격자가 자신의 애플리케이션에서 OAuth를 지원하고 Facebook으로 로그인하는 애플리케이션을 만들 수 있기 때문입니다. 그런 다음, 피해자가 공격자의 애플리케이션에서 Facebook으로 로그인하면, 공격자는 자신의 애플리케이션에 제공된 사용자의 OAuth 토큰을 얻고 이를 사용하여 피해자의 OAuth 애플리케이션에 피해자의 사용자 토큰으로 로그인할 수 있습니다.
따라서 공격자가 사용자가 자신의 OAuth 애플리케이션에 접근하도록 관리하면, 그는 토큰을 기대하고 해당 토큰이 자신의 앱 ID에 부여되었는지 확인하지 않는 애플리케이션에서 피해자의 계정을 탈취할 수 있습니다.
이 글에 따르면, 피해자가 공격자의 호스트를 가리키는 returnUrl이 있는 페이지를 열도록 만드는 것이 가능했습니다. 이 정보는 **쿠키(RU)**에 저장되며, 나중에 프롬프트가 사용자에게 해당 공격자의 호스트에 대한 접근을 허용할 것인지 묻습니다.
이 프롬프트를 우회하기 위해, returnUrl을 사용하여 이 RU 쿠키를 설정하는 Oauth 흐름을 시작하기 위해 탭을 열고, 프롬프트가 표시되기 전에 탭을 닫고, 해당 값 없이 새 탭을 열 수 있었습니다. 그러면 프롬프트는 공격자의 호스트에 대해 알리지 않지만, 쿠키는 설정되므로 토큰은 리디렉션에서 공격자의 호스트로 전송됩니다.
이 비디오에서 설명된 바와 같이, 일부 OAuth 구현에서는 prompt
GET 매개변수를 None(&prompt=none
)으로 지정하여 사용자가 이미 플랫폼에 로그인한 경우 웹에서 주어진 접근을 확인하라는 요청을 방지할 수 있습니다.
이 비디오에서 설명된 바와 같이, 최종 URL에서 코드를 제공할 위치를 지정하기 위해 response_mode
매개변수를 지정하는 것이 가능할 수 있습니다:
response_mode=query
-> 코드는 GET 매개변수 내에 제공됩니다: ?code=2397rf3gu93f
response_mode=fragment
-> 코드는 URL 조각 매개변수 내에 제공됩니다 #code=2397rf3gu93f
response_mode=form_post
-> 코드는 code
라는 입력을 가진 POST 양식 내에 제공됩니다.
response_mode=web_message
-> 코드는 포스트 메시지로 전송됩니다: window.opener.postMessage({"code": "asdasdasd...
이 블로그 포스트에 따르면, 이는 사용자 이름과 비밀번호를 통해 OAuth에 로그인할 수 있는 OAuth 흐름입니다. 이 간단한 흐름에서 모든 작업에 대한 접근 권한이 있는 토큰이 반환되면, 해당 토큰을 사용하여 2FA를 우회할 수 있습니다.
이 블로그 포스트는 리퍼러의 값을 사용하여 열린 리디렉션을 악용하여 OAuth를 ATO로 악용하는 방법에 대해 설명합니다. 공격은 다음과 같았습니다:
피해자가 공격자의 웹 페이지에 접근합니다.
피해자가 악성 링크를 열고, 오프너가 response_type=id_token,code&prompt=none
을 추가 매개변수로 사용하여 공격자의 웹사이트를 리퍼러로 하여 Google OAuth 흐름을 시작합니다.
오프너에서 제공자가 피해자를 승인한 후, redirect_uri
매개변수의 값(피해자 웹)으로 30X 코드와 함께 다시 보냅니다. 이때 여전히 공격자의 웹사이트가 리퍼러에 남아 있습니다.
피해자 웹사이트는 리퍼러를 기반으로 열린 리디렉션을 트리거하여 피해자 사용자를 공격자의 웹사이트로 리디렉션합니다. **respose_type
**이 **id_token,code
**였기 때문에, 코드는 URL의 조각으로 공격자에게 다시 전송되어 피해자의 사이트에서 Google을 통해 사용자의 계정을 탈취할 수 있게 됩니다.
이 연구를 확인하세요 이 기술에 대한 추가 세부정보를 위해.
OAuth의 동적 클라이언트 등록은 보안 취약점, 특히 서버 측 요청 위조(SSRF) 공격에 대한 덜 명백하지만 중요한 벡터로 작용합니다. 이 엔드포인트는 OAuth 서버가 클라이언트 애플리케이션에 대한 세부정보를 수신할 수 있도록 하며, 여기에는 악용될 수 있는 민감한 URL이 포함됩니다.
주요 사항:
동적 클라이언트 등록은 종종 /register
에 매핑되며 client_name
, client_secret
, redirect_uris
, 로고 또는 JSON 웹 키 세트(JWK)에 대한 URL과 같은 세부정보를 POST 요청을 통해 수락합니다.
이 기능은 RFC7591 및 OpenID Connect Registration 1.0에 명시된 사양을 준수하며, SSRF에 취약할 수 있는 매개변수를 포함합니다.
등록 프로세스는 여러 가지 방법으로 SSRF에 서버를 노출시킬 수 있습니다:
logo_uri
: 서버가 가져올 수 있는 클라이언트 애플리케이션의 로고 URL로, SSRF를 유발하거나 URL이 잘못 처리될 경우 XSS로 이어질 수 있습니다.
jwks_uri
: 클라이언트의 JWK 문서에 대한 URL로, 악의적으로 작성된 경우 서버가 공격자가 제어하는 서버로 아웃바운드 요청을 하게 만들 수 있습니다.
sector_identifier_uri
: 서버가 가져올 수 있는 redirect_uris
의 JSON 배열을 참조하여 SSRF 기회를 생성할 수 있습니다.
request_uris
: 클라이언트에 대한 허용된 요청 URI를 나열하며, 서버가 인증 프로세스 시작 시 이러한 URI를 가져오면 악용될 수 있습니다.
악용 전략:
SSRF는 logo_uri
, jwks_uri
또는 sector_identifier_uri
와 같은 매개변수에 악의적인 URL로 새 클라이언트를 등록하여 유발할 수 있습니다.
request_uris
를 통한 직접적인 악용은 화이트리스트 제어로 완화될 수 있지만, 사전 등록된 공격자가 제어하는 request_uri
를 제공하면 인증 단계에서 SSRF를 촉진할 수 있습니다.
테스트 중인 플랫폼이 OAuth 제공자인 경우 가능한 경쟁 조건을 테스트하려면 이 글을 읽으세요.
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)