Terrance DeJesus

Microsoft Entra ID OAuth 피싱 및 탐지

인더와일드(ItW) Entra ID OAuth 피싱 및 탐지 전략에 대한 집중 과정

40분 읽기보안 연구
Microsoft Entra ID OAuth 피싱 및 탐지

서문

Elastic의 위협 연구 및 탐지 엔지니어링(TRADE) 팀원들은 최근 Microsoft Entra ID(이전의 Azure AD)의 OAuth 워크플로우를 대상으로 하는 새로운 종류의 위협에 주목하게 되었습니다. 이 연구는 Volexity의 최근 블로그, 코드 피싱에서 영감을얻었습니다: 러시아 위협 365 행위자가 Microsoft OAuth 워크플로우를 표적으로 삼다'에서 NGO를 대상으로 한 정교한 OAuth 피싱 캠페인이 UTA0352로 지정된 위협 행위자의 소행이라고 설명합니다.

Volexity의 조사는 공격자가 신뢰할 수 있는 자사 Microsoft 애플리케이션을 악용하여 기존 방어를 우회하는 방법에 대한 강력한 포렌식 증거를 제시합니다. 공격자들은 합법적인 OAuth 흐름과 오픈 소스 도구 ROADtools를 사용하여 맞춤형 Microsoft 인증 URL을 만들고, 보안 토큰을 수집한 후 이를 활용하여 사용자를 가장하고, 권한을 높이고, Microsoft Graph를 통해 Outlook 이메일을 다운로드하고 SharePoint 사이트에 액세스하는 등 데이터를 유출했습니다.

그들의 보고서는 공격의 내용을 철저히 문서화했지만, Elastic 팀은 공격의 방법을 이해하는 데 집중했습니다. 저희는 통제된 환경에서 공격 체인을 에뮬레이션하여 토큰 남용, 디바이스 등록, 토큰 강화의 메커니즘을 직접 살펴봤습니다. 이 실습 실험을 통해 Microsoft의 OAuth 구현의 내부 작동 방식, ROADtools의 실제 사용, 권장 완화 조치, 가장 중요한 것은 유사한 활동을 식별하고 대응하는 효과적인 탐지 전략에 대한 심층적인 인사이트를 얻을 수 있었습니다.

Microsoft Entra ID의 OAuth

Microsoft Entra ID는 OAuth 2.0을 구현하여 Outlook, SharePoint 및 Graph API와 같은 Microsoft 365 서비스에 대한 위임된 액세스를 가능하게 합니다. OAuth 사양은 표준화되어 있지만(RFC6749), Entra ID는 위임된 액세스의 작동 방식과 공격자가 이를 악용하는 방식에 영향을 미치는 고유한 동작과 토큰 유형을 도입합니다.

위임 액세스에서는 앱이 요청하고 사용자 또는 관리자가 동의한 범위(권한)에 따라 앱이 로그인한 사용자를 대신하여 작업할 수 있는 권한이 부여됩니다. 이 모델은 매번 자격 증명을 묻지 않고 앱이 사용자의 이메일, 파일 또는 디렉토리 데이터를 검색하는 엔터프라이즈 환경에서 흔히 볼 수 있는 모델입니다.

일반적인 위임 권한 부여 흐름에는 다음이 포함됩니다:

권한 요청(OAuth 2.0 권한 부여 코드 부여): 앱이 특정 범위(예: Mail.Read, 오프라인_액세스)로 리소스(예: 그래프)에 대한 액세스를 요청합니다. 이는 URI에 매개변수로 추가됩니다.

  • client_id: 애플리케이션의 ID(예: VSCode)
  • 응답 유형: 부여 유형 OAuth 워크플로우를 결정합니다(예 장치 코드, 인증 코드)
  • 범위: 범위: 대상 리소스에 대해 요청된 권한(예 Mail.Read, 오프라인_액세스)
  • Redirect_uri: 인증 코드를 보낼 위치
  • State: CSRF 보호
  • 로그인_hint: 사용자 이름 미리 채우기

사용자 인증(OpenID Connect): Entra ID는 정책(비밀번호, MFA, 장치 신뢰)을 통해 사용자를 인증합니다.

  • 단일 요소 인증(SFA)
  • 다단계 인증(MFA)
  • 디바이스 신뢰(하이브리드 조인, Intune 규정 준수)
  • 조건부 액세스 정책(CAP)
  • 싱글 사인온(SSO)

동의: 동의: 동의는 앱이 인증 코드를 받을 수 있는지 여부와 허용되는 범위를 결정합니다.

  • 사용자가 동의할 수 있는 범위(예 Mail.Read, 오프라인_액세스)
  • 관리자 동의가 필요한 범위(예 Directory.ReadWrite)는 고위급 승인이 필요합니다.

토큰 발급: 앱이 인증 코드를 받은 다음 이를 :

  • 액세스 토큰 - Graph와 같은 API를 호출하는 데 사용되는 단기 토큰입니다.
  • 리프레시 토큰(RT) - 새로운 액세스 토큰을 조용히 획득할 수 있는 수명이 긴 토큰입니다.
  • 신원 토큰 - 인증된 사용자를 설명하며, OpenID 흐름에 존재합니다.
  • (선택 사항) 기본 새로 고침 토큰: 사용자가 도메인에 가입하거나 등록된 디바이스를 사용하는 경우, 기본 새로 고침 토큰(PRT)을 사용하면 사용자 상호작용 없이 자동 SSO 및 추가 토큰 흐름을 사용할 수 있습니다.
  • 토큰 클레임: 클레임은 사용자, 앱, 디바이스, 인증의 범위 및 컨텍스트를 설명하는 JWT 토큰에 포함된 키-값 쌍입니다.

MSFT OAuth 피싱 URL을 정의하는 요소

탐지 전략을 수립하는 데 도움이 되는 Volexity 보고서의 주요 결과를 자세히 살펴보기 전에 Microsoft OAuth 피싱 URL을 정확히 정의하는 것이 무엇인지 분석하는 것이 중요합니다.

앞서 설명한 대로 Microsoft Entra ID는 이러한 URL을 사용하여 어떤 애플리케이션(클라이언트)이 어떤 사용자 주체를 대신하여, 어떤 리소스에, 어떤 권한으로 액세스를 요청하는지 확인합니다. 이러한 컨텍스트의 대부분은 OAuth 인증 요청의 쿼리 매개변수에 직접 포함되어 있으므로 공격자와 방어자 모두에게 중요한 메타데이터 소스가 됩니다.

다음은 Volexity의 블로그에서 발췌한 인증 코드 부여 흐름에 맞춘 피싱 URL의 예시입니다:

https://login.microsoftonline[.]com/organizations/oauth2/v2.0/authorize?state=https://mae.gov[.]ro/[REMOVED]&client_id=aebc6443-996d-45c2-90f0-388ff96faa56&scope=https://graph.microsoft.com/.default&response_type=code&redirect_uri=https://insiders.vscode.dev/redirect&login_hint=<EMAIL HERE>

몇 가지 주요 구성 요소를 분석해 보겠습니다:

  • login.microsoftonline.com - 글로벌 Microsoft Entra ID 인증 엔드포인트입니다.
  • /oauth2/v2.0/authorize - 권한 부여 워크플로우를 위한 MSFT Entra ID OAuth v2.0 엔드포인트
  • 상태 - CSRF를 방지하고 애플리케이션 상태를 유지하는 데 사용되는 선택적 값입니다. 피싱 리디렉션을 난독화하기 위해 악용되기도 합니다.
  • client_id - 요청을 하는 애플리케이션 ID입니다. 이는 Microsoft 퍼스트 파티 앱(예: VSCode, Teams) 또는 공격자가 등록한 악성 타사 앱에 속할 수 있습니다.
  • 범위 - 애플리케이션이 요청하는 권한을 정의합니다(예: Mail.Read, 오프라인_액세스). .default 범위는 클라이언트 자격 증명 흐름에서 사전 동의된 권한을 얻기 위해 자주 사용됩니다.
  • 응답 유형=코드 - 흐름이 나중에 액세스 및/또는 새로 고침 토큰으로 교환할 수 있는 인증 코드를 요청하고 있음을 나타냅니다.
  • redirect_uri - 사용자가 인증한 후 엔트라 ID가 응답을 보낼 곳입니다. 공격자가 이 URI를 제어하면 코드를 얻거나 MSFT에서 관리하는 유효한 URI입니다.
  • login_hint - 대상 사용자를 지정합니다(예: alice @ tenant.onmicrosoft.com). 피싱 시 마찰을 줄이기 위해 미리 채워져 있는 경우가 많습니다.

참고: 이 예는 일반적인 Microsoft Entra ID OAuth 피싱 URL을 보여 주지만, 다양한 변형이 있습니다. 공격자는 지속적인 액세스, 이메일 유출, 광범위한 동의 부여를 통한 권한 확대 등 특정 목적에 따라 클라이언트 ID, 범위, 부여 유형 또는 리디렉션 URI와 같은 매개변수를 조정할 수 있습니다.

이것이 왜 중요할까요?

이러한 매개변수는 사용자 지정이 가능하기 때문에 공격자는 자신의 작전에 맞게 값을 쉽게 바꿀 수 있습니다. 예를 들어

  • 합법적인 Microsoft 클라이언트 ID를 사용하여 정상 애플리케이션과 혼합할 수 있습니다.
  • .default 범위를 설정하여 특정 동의 프롬프트를 건너뛸 수 있습니다.
  • 인증 코드를 수집하기 위해 redirect_uri를 자신이 관리하는 사이트로 가리키게 됩니다.
  • 정찰 중에 식별했을 수 있는 특정 사용자 주체를 타겟팅할 수 있습니다.
  • 운영상의 필요에 따라 대상 리소스에 대한 권한을 조정할 수 있습니다.

대상이 인증되면 목표는 간단합니다. 인증 코드를 획득하는 것입니다. 그런 다음 이 코드는 (종종 ROADtools와 같은 도구를 사용하여) 새로 고침 토큰 및/또는 액세스 토큰으로 교환되어 공격자가 추가 사용자 상호 작용 없이 Graph API 호출을 수행하거나 다른 Microsoft 365 서비스로 피벗할 수 있게 해줍니다.

Volexity의 주요 결과 추상화

위협 탐지를 위해서는 OAuth와 같은 프로토콜, Microsoft Entra ID의 워크플로 구현, 이 작업과 관련하여 공격자가 수행한 동작 및/또는 단계에 대한 컨텍스트 메타데이터를 이해하는 것이 중요합니다.

Volexity의 조사 및 연구를 통해 보고된 다양한 OAuth 피싱의 변종에 주목할 수 있습니다. 이해를 돕기 위해 이를 세분화하여 설명하기로 했습니다:

표적 사용자 주체를 대신하여 VSCode 클라이언트로 그래프 API에 액세스하는 OAuth 피싱: 이러한 URL은 "MSFT OAuth 피싱 URL 정의하기" 예시와 유사하며, 최종 목표는 기본 권한으로 그래프 API에 액세스 토큰을 얻는 것입니다.

  • "authorize" 엔드포인트를 가리키는 사용자 지정 OAuth 피싱 URL입니다.
  • 클라이언트 ID는 구체적으로 VSCode ("aebc6443-996d-45c2-90f0-388ff96faa56")
  • 리소스/범위는 MSFT 그래프 ("https://graph.microsoft.com/.default") .default 권한
  • 토큰 부여 흐름은 인증 코드(응답 유형=코드)였습니다.
  • 리디렉션 URI는 합법적인 MSFT 도메인(insiders[.]vscode[.]dev 또는 vscode-redirect[.]azurewebsites[.]net)
  • 로그인 힌트는 서비스 주체가 아닌 특정 사용자 주체를 대상으로 합니다.
  • 공격자는 표적에게 URL을 열고 인증 코드를 인증한 후 공유하도록 요구했습니다(1.AXg....).

여기에서 공격자는 MSFT의 OAuth 토큰 엔드포인트(https://login.microsoftonline.com/[tenant_id]/oauth2/v2.0/token)에 요청하여 새로 고침 토큰을 액세스 토큰으로 교환할 수 있습니다. 이는 공격자가 그래프 API에 액세스하여 사용자가 정상적으로 사용할 수 있는 리소스에 액세스할 수 있도록 허용하기에 충분합니다. 이러한 지표는 이 블로그의 뒷부분에서 탐지 및 헌팅 전략을 수립하는 데 중요한 역할을 합니다.

MSFT 인증 브로커로 디바이스 등록을 위한 OAuth 피싱: 이 URL은 가상 디바이스를 등록하고, RT를 PRT로 교환하고, Graph API 및 Sharepoint 액세스를 통해 이메일 액세스를 수행하기 위해 PRT 강화가 필요한 후속 ROADtools 사용과 연결되어 있기 때문에 고유합니다.

  • OAuth 피싱 URL은 사용자 지정으로, 권한 부여(https://login.microsoftonline.com/[tenant_id]/oauth2/v2.0/authorize)를 가리킵니다. 엔드포인트
  • 클라이언트 ID는 특히 MSFT 인증 브로커 ("29d9ed98-a469-4536-ade2-f981bc1d605e")
  • 리소스/범위는 장치 등록 서비스(DRS) ("01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9")
  • 토큰 부여 흐름은 인증 코드(응답 유형=코드)였습니다.
  • 리디렉션 URI에는 클라우드 기반 도메인 조인 엔드포인트(일반적으로 Windows 설정 또는 자동 조종 장치에서 사용됨)가 포함됩니다.
  • 로그인 힌트에 사용자 기본 이메일 주소(Target)가 포함되어 있습니다.
  • 요청은 궁극적으로 ADRS 토큰에 대한 것입니다.

피싱을 당한 사용자가 URL을 열면 인증을 통해 공격자가 디바이스를 등록하고 디바이스의 개인 키 및 PEM 파일이 포함된 PRT를 얻는 데 필요한 ADRS 토큰이 제공됩니다.

Volexity의 블로그에는 등록된 디바이스 ID를 통해 유출된 신원의 활동을 추적하는 방법과 승인된 2FA 요청이 확인된 후의 유출 후 활동, 공격자가 새로 등록된 디바이스에 연결된 세션으로 대상의 이메일을 다운로드할 수 있는 방법에 대한 추가 정보도 포함되어 있습니다.

각 피싱 시도에 대한 이해를 바탕으로 다음 목표는 자체 MSFT 테넌트에서 이를 최대한 정확하게 재현하여 그럴듯한 탐지를 위한 데이터를 수집하는 것입니다.

에뮬레이션 노력

지금까지 OAuth의 기본 사항과 Microsoft Entra ID가 이를 구현하는 방법에 대해 살펴봤습니다. Microsoft OAuth 피싱 URL을 정의하는 요소를 분석하고, 중요한 매개 변수를 해독하고, Volexity의 우수한 조사에서 주요 인사이트를 도출하여 이러한 피싱 워크플로와 일치하는 지표를 식별했습니다.

하지만 이론과 Volexity의 노트북을 들여다보는 것만으로는 여기까지만 설명할 수 있습니다.

공격자의 관점, 전체 실행 체인, 툴링의 결함, 미묘한 함정, 악용 가능성을 제대로 이해하기 위해 화이트박스 테스트를 직접 진행하기로 결정했습니다. 저희는 자체 테넌트에서 토큰 채집부터 리소스 액세스까지 모든 것을 에뮬레이션하여 OAuth 피싱 프로세스를 재현했습니다. 목표는? 정적 지표를 넘어 방어자가 확실하게 탐지할 수 있는 행동 흔적을 드러내는 것입니다.

시작해 보겠습니다.

필수 구성 요소

우선, Azure의 위협 연구 및 탐지 환경에 대한 몇 가지 세부 정보를 공유하는 것이 좋습니다.

  • Azure 테넌트를 설정했습니다: TENANT.onmicrosoft.com
  • Sharepoint 도메인을 설정했습니다: DOMAIN.sharepoint.com
  • 기본 IdP Microsoft Entra ID - IAM 활성화
  • 모든 사용자를 위한 Microsoft 365 라이선스(P2)
  • 이벤트허브로 스트리밍하는 Azure 활동 로그
  • 이벤트허브로 스트리밍되는 Microsoft Entra ID 로그인 로그
  • 이벤트허브로 스트리밍되는 Microsoft Entra ID 감사 로그
  • 이벤트허브로 스트리밍되는 Microsoft 그래프 감사 로그
  • Microsoft 365 이벤트허브로 스트리밍하는 감사 로그
  • 이벤트허브의 로그 처리를 위해 Elastic Azure와 M365 통합 지원
  • MFA가 필요한 CAP로 기본 관리자 사용자 활성화
  • 2FA 에뮬레이션을 위한 모바일용 MSFT 인증 앱
  • Windows 10 데스크톱에 NordVPN 설치(Adversary Box)
  • macOS 엔드포인트(피해자 상자)

단일 엔드포인트에서 워크플로우를 따라갈 수도 있지만, 개발자가 불가능한 이동의 변형을 감지하기 위해 별도의 소스 주소를 반영하는 데이터가 필요한 경우가 많습니다.

시나리오 1: VSCode 클라이언트로서의 OAuth 피싱

에뮬레이션

Volexity에서 문서화한 피싱 기법을 에뮬레이트하기 위해 Microsoft Entra ID를 사용하여 OAuth 2.0 인증 URL을 생성하는 Python 스크립트를 만들었습니다. 이 URL은 권한 부여 코드 부여 흐름을 시작하여 퍼스트 파티 Visual Studio Code 앱으로 가장하여 Microsoft Graph API에 대한 위임된 액세스를 요청합니다.

다음 매개 변수를 사용하여 URL을 구성했습니다:

{
  "client_id": "aebc6443-996d-45c2-90f0-388ff96faa56",
  "response_type": "code",
  "redirect_uri": "insiders.vscode.dev/redirect",
  "scope": "https://graph.microsoft.com/.default",
  "login_hint": "user @ tenant.onmicrosoft.com",
  "prompt": "select_account",
  "state": "nothingtoseehere"
}

그림 1: OAuth 피싱 URL의 매개변수

이 URL은 대상(이 경우 MacOS 테스트 사용자)과 공유됩니다. 열면 사용자를 인증하고 OAuth 워크플로우를 완료합니다. 브라우저 개발자 도구를 사용하여 공격자가 피해자에게 보내달라고 요청한 리디렉션 URI에서 반환된 인증 코드를 정확히 캡처합니다.

코드를 받은 후 다음 주소로 POST 요청을 발행합니다:

{token_url: "https://login.microsoftonline.com/organizations/oauth2/v2.0/token"}

이 교환은 authorization_code 부여 유형을 사용하여 코드, 클라이언트 ID 및 리디렉션 URI를 전달합니다. Microsoft는 액세스 토큰은 반환하지만 새로 고침 토큰은 반환하지 않습니다. 왜 그럴까요?

범위 https://graph.microsoft.com/.default 는 Microsoft가 사용자를 대신하여 VSCode 앱에 이미 부여된 모든 그래프 권한에 대한 무기명 토큰을 발급하도록 지시합니다. 이는 앱 등록에서 가져온 정적 범위로, Mail.Read 또는 offline_access와 같은 동적 범위는 포함하지 않습니다.

Microsoft의 문서에는 다음과 같이 명시되어 있습니다:

""클라이언트는 단일 요청에 정적(.기본) 동의와 동적 동의를 결합할 수 없습니다.""

따라서 .default와 함께 오프라인_액세스를 포함하려고 하면 를 입력하면 오류가 발생합니다. 공격자가 새로 고침 토큰을 원한다면 .default를 피해야 합니다. 대신 오프라인_액세스 및 필요한 위임 범위(예: Mail.Read)를 명시적으로 요청하세요(앱 등록이 이를 지원한다고 가정할 때).

액세스 토큰을 손에 넣은 후 두 번째 스크립트로 전환하여 Microsoft Graph API와 상호 작용했습니다. 목표는 공격자가 하는 것처럼 피해자의 계정에서 이메일 메시지를 추출하는 것입니다.

이를 위해 권한 부여 헤더에 액세스 토큰을 Bearer JWT로 포함시키고 다음 엔드포인트에 GET 요청을 보냈습니다:

{graph_url: "https://graph.microsoft.com/v1.0/me/messages"}

응답은 이메일 개체의 JSON 배열을 반환합니다. 여기에서 결과를 반복하여 발신자, 제목, 수신 시간 등 유용한 메타데이터를 구문 분석하기만 하면 됩니다.

토큰의 광범위한 권한을 테스트하기 위해 다음을 사용하여 SharePoint 사이트 열거도 시도했습니다:

{graph_search_url: "https://graph.microsoft.com/v1.0/sites?search=*"}

액세스 거부 오류와 함께 요청이 실패했는데, 이는 중요한 질문으로 이어집니다. 이메일 액세스는 작동하지만 SharePoint 액세스는 작동하지 않는 이유는 무엇인가요? 그 이유는 타사 클라이언트(VSCode: aebc6443-996d-45c2-90f0-388ff96faa56)에 Microsoft에서 미리 정의한 대로 Graph for Sharepoint에 대한 기본 위임 권한이 없기 때문입니다. 따라서 공격자가 액세스할 수 있는 항목에 제한이 있다는 것을 알고 있습니다.

이를 정확하게 확인하기 위해 액세스 토큰을 디코딩하여 VSCode와 연결된 SCP를 .default로 식별했습니다. 그래프에 대한 권한 - 사이트없음 확인 .* Microsoft에서 허가했습니다.

이것은 Volexity에서 설명하는 변형 중 하나이지만, 공격자의 배후 프로세스와 Microsoft Entra ID의 리소스, OAuth 등에 대해 더 많이 이해하는 데 도움이 됩니다.

에뮬레이션이 완료되면 이제 SIEM 탐지 및 위협 헌팅에 사용할 수 있는 고충실도 신호를 식별하는 단계로 넘어갑니다. Microsoft Entra ID 및 Microsoft Graph 로그의 동작 관찰 가능 항목에 초점을 맞추고 있습니다.

탐지

Signal 1 - Visual Studio 코드 클라이언트로서의 Microsoft Entra ID OAuth 피싱

타사 Microsoft 애플리케이션인 Visual Studio Code(VSCode)를 사용하여 OAuth 2.0(권한 부여) 및 OpenID Connect(인증) 플로우를 성공적으로 완료했습니다. 피싱된 사용자 본인을 대신하여 로그인이 발생하여 .default를 사용하여 Microsoft Graph에 대한 위임된 액세스 권한이 발생했습니다. 권한.

event.dataset: "azure.signinlogs" and
event.action: "Sign-in activity" and
event.outcome: "success" and
azure.signinlogs.properties.user_type: "Member" and
azure.signinlogs.properties.authentication_processing_details: *Oauth* and
azure.signinlogs.category: "NonInteractiveUserSignInLogs" and
(
  azure.signinlogs.properties.resource_display_name: "Microsoft Graph" or
  azure.signinlogs.properties.resource_id: "00000003-0000-0000-c000-000000000000"
) and (
  azure.signinlogs.properties.app_id: "aebc6443-996d-45c2-90f0-388ff96faa56" or
  azure.signinlogs.properties.app_display_name: "Visual Studio Code"
)

Signal 2 - 의심스러운 그래프 액세스를 통한 Microsoft Entra 세션 재사용

KQL과 같은 기존 쿼리 언어는 개별 로그 이벤트를 필터링하고 시각화하는 데는 탁월하지만, 탐지가 데이터 세트, 시간, 식별자에 걸쳐 여러 레코드를 상호 연관시키는 데 의존하는 경우에는 어려움을 겪습니다. 바로 이 지점에서 ES|QL(Elasticsearch 쿼리 언어)이 필수적입니다. 이러한 유형의 다중 이벤트 상관 관계, 시간 논리 및 필드 정규화는 여러 개의 분리된 쿼리를 작성하고 사후에 수동으로 상관 관계를 지정하지 않고는 KQL과 같은 정적 필터 기반 쿼리 언어에서는 어렵거나 완전히 불가능합니다.

이 탐지는 서로 가깝지만 서로 다른 데이터 소스, 즉 로그인 로그와 Microsoft Graph 활동에서 발생하는 여러 이벤트의 상관 관계를 파악하는 데 의존합니다. 목표는 여러 IP에서 동일한 세션 ID를 재사용하는 의심스러운 행위를 찾아내어 세션 하이재킹 또는 토큰 도용을 나타내는 것입니다. 이 게시물의 지면 관계상 실제 탐지 규칙은 탐지 규칙 섹션에서 확인할 수 있습니다. 쿼리의 흐름과 의미를 더 잘 설명하기 위해 아래는 보다 높은 수준에서 설명하는 다이어그램입니다.

[ FROM logs-azure.* ]
        |
        |  ← Pulls events from all relevant Microsoft Cloud datasets:
        |     - azure.signinlogs (authentication)
        |     - azure.graphactivitylogs (resource access)
        ↓
[ WHERE session_id IS NOT NULL AND IP NOT MICROSOFT ASN ]
        |
        |  ← Filters out Microsoft-owned infrastructure (e.g., internal proxy,
        |     Graph API relays) using ASN checks.
        |  ← Ensures session ID exists so events can be correlated together.
        ↓
[ EVAL session_id, event_type, time_window, etc. ]
        |
        |  ← Normalizes key fields across datasets:
        |     - session_id (from signin or Graph)
        |     - user ID, app ID, event type ("signin" or "graph")
        |  ← Buckets events into 5-minute windows using DATE_TRUNC()
        ↓
[ KEEP selected fields ]
        |
        |  ← Retains only what's needed:
        |     session_id, timestamp, IP, user, client ID, etc.
        ↓
[ STATS BY session_id + time_window ]
        |
        |  ← Groups by session and time window to compute:
        |     - unique IPs used
        |     - apps involved
        |     - first and last timestamps
        |     - whether both signin and graph occurred
        ↓
[ EVAL time_diff + signin_to_graph_delay ]
        |
        |  ← Calculates:
        |     - time_diff: full session duration
        |     - delay: gap between signin and Graph access
        ↓
[ WHERE types_count > 1 AND unique_ips > 1 AND delay <= 5 ]
        |
        |  ← Flags sessions where:
        |     - multiple event types (signin + graph)
        |     - multiple IPs used
        |     - all occurred within 5 minutes
        ↓
[ Output = Suspicious Session Reuse Detected ]

Signal 3 - 의심스러운 속성을 가진 Microsoft Entra ID 동시 로그인

이 탐지는 사용자가 MFA 없이 디바이스 코드 흐름을 사용하여 인증하거나 VSCode 클라이언트를 사용하여 로그인하는 경우 Microsoft Entra ID에서 의심스러운 로그인을 식별합니다. 짧은 시간 내에 두 개 이상의 서로 다른 IP에서 동일한 ID가 두 가지 이상의 방법을 사용하여 로그인하는 경우 토큰 리플레이, OAuth 피싱 또는 중간자 공격(AitM) 활동을 나타낼 수 있습니다.

[ FROM logs-azure.signinlogs* ]
        |
        |  ← Pulls only Microsoft Entra ID sign-in logs
        ↓
[ WHERE @timestamp > NOW() - 1h AND event.outcome == "success" ]
        |
        |  ← Filters to the last hour and keeps only successful sign-ins
        ↓
[ WHERE source.ip IS NOT NULL AND identity IS NOT NULL ]
        |
        |  ← Ensures the sign-in is tied to a user and IP for correlation
        ↓
[ KEEP fields: identity, app_id, auth_protocol, IP, etc. ]
        |
        |  ← Retains app/client, IP, auth method, and resource info
        ↓
[ EVAL detection flags ]
        |
        |  ← Labels events as:
        |     - device_code: if MFA not required
        |     - visual_studio: if VS Code client used
        |     - other: everything else
        ↓
[ STATS BY identity ]
        |
        |  ← Aggregates all sign-ins per user, calculates:
        |     - IP count
        |     - Device Code or VSCode usage
        |     - App/client/resource details
        ↓
[ WHERE src_ip >= 2 AND (device_code_count > 0 OR vsc > 0) ]
        |
        |  ← Flags users with:
        |     - Sign-ins from multiple IPs
        |     - And either:
        |         - Device Code w/o MFA
        |         - Visual Studio Code app
        ↓
[ Output = Potential OAuth Phishing or Token Misuse ]

이 변종 OAuth 피싱은 새로 고침 토큰이나 PRT가 제공하는 완전한 지속성은 부족하지만, 공격자가 합법적인 채널을 통해 이메일과 같은 민감한 사용자 데이터에 한 번만 액세스할 수 있는 귀중한 기회를 제공합니다. 이 연습은 정적 .default의 한계와 기능을 이해하는 데 도움이 됩니다. 범위, 앱 등록의 영향, 사후 인증에서 Microsoft Graph가 중추적인 역할을 하는 방식에 대해 알아보세요. 또한 모든 OAuth 피싱 공격이 똑같이 만들어지는 것은 아니라는 더 광범위한 교훈을 강조합니다. 일부는 토큰을 새로 고치거나 디바이스 등록을 통해 (나중에 살펴보겠지만) 장기화를 목표로 하는 반면, 일부는 퍼스트 파티 클라이언트를 통해 즉각적인 데이터 도용에 초점을 맞추고 있습니다. 정확한 탐지 로직을 위해서는 뉘앙스를 이해하는 것이 필수적입니다.

시나리오 2: 디바이스 등록을 위한 OAuth 피싱

앞서 언급했듯이 Volexity는 피해자를 대상으로 한 별도의 피싱 플레이북도 보고했는데, 이번에는 가상 디바이스를 등록하고 PRT를 획득하는 것이 목표였습니다. 이 접근 방식은 공격자에게 더 많은 단계를 요구하지만, 그 대가는 토큰을 부여하여 작업을 완료하는 데 훨씬 더 많은 유용성을 제공하는 토큰입니다. 에뮬레이션 작업을 위해 툴셋을 확장하고 공격자가 정확성을 유지하기 위해 했던 것처럼 ROADtools에 의존해야 했지만, 초기 피싱 및 침해 후 조치를 위해 다른 파이썬 스크립트를 몇 개 더 만들었습니다.

에뮬레이션

초기 피싱부터 Python 스크립트를 조정하여 피해자에게 전송할 다른 OAuth URL을 만들었습니다. 이번에는 퍼스트 파티 클라이언트 ID가 Microsoft 인증 브로커이고, 오프라인_액세스로 새로 고침 토큰을 요청하고 Entra ID의 클라우드 도메인 디바이스 가입 엔드포인트 URI로 리디렉션하는 것에 중점을 두었습니다.

{
  "client_id": "29d9ed98-a469-4536-ade2-f981bc1d605e",
  "response_type": "code",
  "response_mode": "query",
  "redirect_uri": "https://login.microsoftonline.com/WebApp/CloudDomainJoin/8",
  "resource": "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9",
  "state": "nothingtoseehere"
}

성공하고 피해자가 인증하면 OAuth 워크플로우가 완료되고 사용자는 쿼리 매개변수에 인증 코드가 추가된 지정된 URI로 리디렉션됩니다. 다시 말하지만, 이 코드는 토큰으로 교환하기 위해 공격자와 다시 공유해야 하는 중요한 부분입니다. 저희의 경우 피싱 URL이 열리고 대상이 인증되면 리디렉션에 포함된 인증 코드를 캡처하고 이를 사용하여 Microsoft Entra ID 토큰 엔드포인트에서 토큰을 요청합니다.

이제 여기서 흥미로운 점이 있습니다. 토큰 요청에 대한 응답으로 액세스 토큰, 새로 고침 토큰, ID 토큰의 세 가지 유형의 토큰을 받습니다. 왜 액세스 토큰 이상의 것을 얻어야 하나요? 그 해답은 처음에 요청한 범위인 openid, offline_access프로필에 있습니다.

  • openid는 OpenID Connect 계층의 일부인 ID 토큰을 부여하고 사용자의 신원을 확인하는데, 이것이 바로 인증(authN) 아티팩트입니다.
  • 오프라인_액세스는 새로 고침 토큰을 제공하여 세션을 유지하고 재인증 없이 새 액세스 토큰을 요청할 수 있도록 하며, 이는 영구 액세스를 지원하지만 ROADtx와 함께 사용하는 데 중요합니다.
  • 그리고 액세스 토큰 자체는 Microsoft Graph와 같은 보호된 API에 대한 요청을 승인하는 데 사용되며, 이는 권한 부여(authZ)를 나타냅니다.

이 세 가지 토큰으로 인증, 권한 부여, 장기적인 세션 연속성 등 모든 것을 갖추게 됩니다. 이는 단순한 OAuth 피싱 플레이에서 Microsoft Entra ID에 새 디바이스를 등록하는 것과 같은 보다 지속적인 발판으로 전환하기에 충분합니다.

이제 두 점을 연결해 보겠습니다. PRT를 사용하려면 장치 인증서와 개인 키를 통해 Entra ID가 인식하는 유효한 장치를 등록해야 합니다. 바로 이 부분에서 ROADtx가 활약합니다. 초기 OAuth 피싱은 가입된 디바이스 플로우를 가장했고, 사용된 클라이언트는 Microsoft 인증 브로커(디바이스 등록 서비스와 상호 작용하는 자사 클라이언트)였으므로 DRS와 상호 작용할 수 있는 올바른 액세스 토큰을 이미 보유하고 있습니다. 반환된 개체에서 범위는 Azure DRS 액세스를 나타내며 나중에 탐지에 중요한 adrs_access임을 알 수 있습니다.

여기에서 토큰 거래소에서 받은 JSON 객체를 .roadtool_auth에 넣기만 하면 됩니다. 파일을 만듭니다. 이 파일은 기본적으로 저장된 토큰을 사용하여 디바이스 등록을 수행하고, 공격자의 지속성 이동을 완료하고 유효한 PRT를 얻기 위한 단계를 설정하는 ROADtools에서 소비합니다.

토큰을 얻은 후에는 JSON 형식을 다시 지정하여 ROADtx에 맞게 토큰을 준비합니다. ROADtx는 대/소문자로 된 키를 요구하며, Microsoft 인증 브로커의 클라이언트 ID도 _clientId로 포함해야 합니다. 이 설정을 통해 새로 고침 토큰을 가져와 DRS로 범위가 지정된 새 JWT(특히 서비스 주체인 urn :ms-drs:enterpriseregistration.windows.net)로 교환하는 refreshtokento 명령을 실행할 수 있습니다.

이 작업이 완료되면 device 명령을 사용하여 새 디바이스 등록을 시뮬레이션합니다. 이 작업은 Entra ID에 항목을 생성하는 백엔드 등록이므로 실제 가상 머신이나 물리적 호스트가 필요하지 않습니다. 성공하면 Microsoft 에코시스템에서 유효한 하이브리드 조인 디바이스를 시뮬레이션하는 데 필요한 유효한 디바이스 ID, PEM 인코딩 인증서 및 개인 키가 발급됩니다.

디바이스 ID가 설정되면 prt 명령을 호출합니다. 이렇게 하면 새로 고침 토큰, 디바이스 인증서 및 개인 키를 사용하여 Microsoft Entra ID에 대한 사용자 및 디바이스 신뢰를 효과적으로 연결하는 높은 권한의 자격 증명인 새 PRT를 생성합니다.

그리고 바로 그 순간, 우와! - PRT가 있습니다.

하지만 왜 이 모든 과정을 거쳐야 할까요? 이미 액세스 토큰, ID 토큰, 새로 고침 토큰이 있는데 왜 디바이스를 등록하고, 인증서를 생성하고, PRT를 받아야 하나요?

PRT는 완전한 사용자 및 디바이스 ID 에뮬레이션의 핵심이기 때문입니다. Entra ID의 세계에서 Kerberos와 유사한 티켓 부여 토큰이라고 생각하면 됩니다. 유효한 PRT로:

  • 공격자는 사용자 상호 작용 없이도 Outlook, SharePoint 또는 Teams와 같은 퍼스트 파티 앱에 대한 새 액세스 및 ID 토큰을 요청할 수 있습니다.
  • PRT는 일반적으로 사용자에게 다시 메시지를 표시하는 MFA 및 기타 조건부 액세스 정책(CAP)을 우회하여 여러 서비스에서 원활한 싱글 사인온 SSO를 가능하게 합니다. CAP와 MFA는 공격자에게 큰 장벽이 되는 경우가 많기 때문에 지속성을 위해 매우 중요합니다.
  • 디바이스 ID를 신뢰할 수 있는 한 세션 간에 PRT를 자동으로 갱신하고 활용할 수 있으므로 오래 지속되는 지속성을 지원합니다.

그리고 가장 위험한 점은 공격자가 PRT를 사용하면 도메인을 완벽하게 준수하는 디바이스와 사용자 조합으로 위장하여 대부분의 기존 탐지 및 대응 제어를 효과적으로 우회할 수 있기 때문에 헌터와 분석가에게 정상과 의심스러운 것 사이의 경계가 매우 희박해진다는 것입니다.

따라서 PRT는 은밀한 측면 이동, 권한 상승, Microsoft 365 서비스에 대한 심층 액세스를 가능하게 하는 매우 귀중한 자산입니다. 이제 더 이상 침입하는 것만이 중요한 것이 아니라 탐지되지 않는 것이 중요합니다.

침해 후 활동도 잊지 마세요...

ROADtx는 공격자들이 자주 사용하는 몇 가지 강력한 명령어인 prtenrich와 browserprtauth를 제공합니다. 예를 들어, 인증 및 권한 부여에 필요한 메타데이터가 포함된 PRT(원래 피싱 피해자(저)의 소유이지만 실제로는 Microsoft 인증 브로커가 대신 처리하는 것)를 제공함으로써 Microsoft 제품군의 대부분의 브라우저 기반 UI 서비스에 액세스할 수 있습니다.

또한 Volexity는 디바이스 등록과 PRT 획득 후 최초 피해자에게 2FA 요청이 전송되고 승인된 후 SharePoint를 통해 이메일에 액세스하는 데 사용되었다고 보고했습니다. 요청이 정확히 어떤 방식으로 이루어졌는지 명시되어 있지는 않지만, 공격자가 PRT를 사용하여 자사 Microsoft 클라이언트를 통해 인증하고 실제 데이터 액세스는 Microsoft Graph를 통해 이루어졌다고 가정하는 것이 합리적입니다. 그래프는 대부분의 Microsoft 365 리소스에 대한 중앙 API 허브 역할을 하기 때문에 침해 이후에도 여전히 인기 있는 표적이 되고 있습니다.

먼저 ROADtx를 활용하여 Microsoft Teams를 클라이언트로, Microsoft Graph를 리소스로 사용하는 PRT로 인증해 보겠습니다. PRT와 함께 prtauth 명령을 사용하면 새 액세스 토큰과 새로 고침 토큰을 얻을 수 있어 Microsoft의 ID 패브릭 내에서 토큰을 부여하는 토큰으로서 PRT의 유용성을 명확하게 보여 줍니다.

액세스 토큰이 확보되면 이를 사용자 지정 Python 스크립트에 연결하여 관심 있는 파일을 식별하고 콘텐츠를 다운로드할 수 있는 SharePoint 사이트, 드라이브, 항목의 열거를 시작합니다.

이 에뮬레이션을 통해 공격자가 Microsoft 인증 브로커로 OAuth 피싱을 연결하고 필요한 자격 증명 자료를 확보하여 ROADtx를 활용하여 PRT를 획득하는 방법을 보여주었습니다. 이 PRT는 중요한 파일에 액세스하고 테넌트 리소스를 열거하는 등의 작업을 수행하는 중요한 유틸리티입니다.

이제 초점을 바꿔서 이러한 활동을 감지할 수 있는 그럴듯하고 정확한 신호는 무엇일까요?

탐지

신호 1 - Microsoft 인증 브로커로서의 Microsoft Entra ID OAuth 피싱

사용자 주체가 MAB(Microsoft 인증 브로커)를 클라이언트로, DRS(디바이스 등록 서비스)를 대상 리소스로 사용하여 OAuth 인증 코드 흐름을 시작하는 인스턴스를 식별합니다. 이 탐지는 짧은 시간 내에 두 개 이상의 서로 다른 IP 주소에서 단일 세션 ID가 재사용되는 경우와 피싱과 일반적으로 연관되는 행동인 브라우저에서 적어도 하나의 요청이 발생하는 경우에 초점을 맞추고 있습니다.

[ FROM logs-azure.signinlogs-* ]
        |
        |  ← Pulls all Microsoft Entra ID sign-in logs
        ↓
[ WHERE app_id == MAB AND resource_id == DRS ]
        |
        |  ← Filters to OAuth auth code requests targeting
        |     Microsoft Authentication Broker + Device Reg Service
        ↓
[ EVAL session_id + is_browser ]
        |
        |  ← Extracts session ID and flags browser-based activity
        ↓
[ STATS BY 30-minute window, user, session_id ]
        |
        |  ← Groups logins within same session and time window,
        |     then aggregates:
        |       - user/session/token identifiers
        |       - distinct IPs and geo info
        |       - user agent, browser presence
        |       - app/resource/client info
        ↓
[ WHERE ip_count ≥ 2 AND session_id_count == 1 ]
        |
        |  ← Identifies reuse of a single session ID
        |     across ≥ 2 different IP addresses
        ↓
[ AND has_browser ≥ 1 AND auth_count ≥ 2 ]
        |
        |  ← Requires at least one browser-based request
        |     and at least two total sign-in events
        ↓
[ Output = Suspicious OAuth Flow with Auth Broker for DRS ]

신호 2 - Microsoft 인증 브로커의 의심스러운 ADRS 토큰 요청

사용자 주체가 MAB(Microsoft 인증 브로커) 클라이언트에 발급된 새로 고침 토큰을 사용하여 인증하는 Microsoft Entra ID 로그인 이벤트를 식별하며, adrs_access OAuth 범위로 DRS(장치 등록 서비스)를 대상으로 합니다. 이 패턴은 초기 인증 코드 피싱 또는 디바이스 등록 흐름에 따른 토큰 기반 DRS 액세스를 나타낼 수 있습니다.

event.dataset: "azure.signinlogs" and azure.signinlogs.properties.app_id : "29d9ed98-a469-4536-ade2-f981bc1d605e" and azure.signinlogs.properties.resource_id : "01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9" and azure.signinlogs.properties.authentication_processing_details.`Oauth Scope Info`: *adrs_access* and azure.signinlogs.properties.incoming_token_type: "refreshToken" and azure.signinlogs.properties.user_type: "Member"

신호 3 - Entra ID에 비정상적인 장치 등록

OAuth 피싱 후에 흔히 볼 수 있는 새로 고침 토큰을 사용한 잠재적인 악성 기기 등록 활동을 나타내는 일련의 Entra ID 감사 로그 이벤트를 탐지합니다. 이 패턴은 장치 등록 서비스에서 새로 등록된 Windows 장치(하드코딩된 OS 버전 10.0.19041.928)를 추가한 다음 사용자 및 소유자를 할당하는 ROADtx와 같은 도구의 동작을 모방합니다. 모든 이벤트는 동일한 상관관계 ID를 공유하고 1분 이내에 발생해야 하며, 이는 합법적인 사용자 행동이 아닌 자동화 또는 스크립트 기반 등록을 강력하게 시사합니다.

sequence by azure.correlation_id with maxspan=1m
[any where event.dataset == "azure.auditlogs" and azure.auditlogs.identity == "Device Registration Service" and azure.auditlogs.operation_name == "Add device" and azure.auditlogs.properties.additional_details.value like "Microsoft.OData.Client/*" and (
  azure.auditlogs.properties.target_resources.`0`.modified_properties.`1`.display_name == "CloudAccountEnabled" and 
azure.auditlogs.properties.target_resources.`0`.modified_properties.`1`.new_value: "[true]") and azure.auditlogs.properties.target_resources.`0`.modified_properties.`3`.new_value like "*10.0.19041.928*"]
[any where event.dataset == "azure.auditlogs" and azure.auditlogs.operation_name == "Add registered users to device" and azure.auditlogs.properties.target_resources.`0`.modified_properties.`2`.new_value like "*urn:ms-drs:enterpriseregistration.windows.net*"]
[any where event.dataset == "azure.auditlogs" and azure.auditlogs.operation_name == "Add registered owner to device"]

신호 3 - 동일한 사용자 및 장치에서 Entra ID RT에서 PRT로 전환하기

이 탐지는 Microsoft Entra ID 사용자가 먼저 MAB(Microsoft 인증 브로커)에 발급된 새로 고침 토큰을 사용하여 인증한 후 곧바로 동일한 디바이스에서 PRT(기본 새로 고침 토큰)를 사용하는 경우를 식별합니다. 이러한 순서는 정상적인 사용자 행동에서는 드물며 공격자가 디바이스를 성공적으로 등록하고 ROADtx와 같은 도구를 사용하여 영구적인 액세스로 에스컬레이션했음을 나타낼 수 있습니다. 이 규칙은 두 번째 단계에서 DRS(장치 등록 서비스)에 연결된 활동을 필터링하여 다른 Microsoft 365 서비스에 액세스하기 위한 PRT의 등록 후 사용에 중점을 둡니다.

이 동작은 특히 디바이스 신뢰가 조용히 설정된 경우 토큰 기반 손상과 장기 세션 에뮬레이션을 강력하게 시사합니다. 새로 고침 토큰에서 PRT로의 전환을 포착하는 것은 OAuth 피싱 및 침해 후 지속성에 대한 고충실도 신호를 파악하는 데 매우 중요합니다.

sequence by azure.signinlogs.properties.user_id, azure.signinlogs.properties.device_detail.device_id with maxspan=1d
  [authentication where 
    event.dataset == "azure.signinlogs" and
    azure.signinlogs.category == "NonInteractiveUserSignInLogs" and
    azure.signinlogs.properties.app_id == "29d9ed98-a469-4536-ade2-f981bc1d605e" and
    azure.signinlogs.properties.incoming_token_type == "refreshToken" and
    azure.signinlogs.properties.device_detail.trust_type == "Azure AD joined" and
    azure.signinlogs.properties.device_detail.device_id != null and
    azure.signinlogs.properties.token_protection_status_details.sign_in_session_status == "unbound" and
    azure.signinlogs.properties.user_type == "Member" and
    azure.signinlogs.result_signature == "SUCCESS"
  ]
  [authentication where 
    event.dataset == "azure.signinlogs" and
    azure.signinlogs.properties.incoming_token_type == "primaryRefreshToken" and
    azure.signinlogs.properties.resource_display_name != "Device Registration Service" and
    azure.signinlogs.result_signature == "SUCCESS"
  ]

신호 4 - 비정상적인 PRT 사용 및 사용자 본인에 대한 등록된 장치

이 탐지는 Microsoft Entra ID 사용자가 지난 7 일 이내에 이전에 볼 수 없었던 새 디바이스를 등록할 때 나타나며, 이는 종종 ROADtx 기반 디바이스 등록으로 연결되는 OAuth 피싱 캠페인과 관련된 행동입니다. 이러한 공격에서 공격자는 사용자를 속여 DRS를 대상으로 하는 MAB(Microsoft 인증 브로커)에 대한 액세스를 승인하도록 한 다음, RT를 획득하고 ROADtx를 사용하여 자동으로 가짜 Windows 장치를 등록하고 PRT를 발급합니다. 이 규칙은 사용자 주체가 새로 관찰된 디바이스 ID로 인증할 때, 특히 세션이 토큰 리플레이 또는 디바이스 스푸핑의 특징인 언바인딩된 경우 알림을 보냅니다. PRT에는 등록되고 신뢰할 수 있는 장치가 필요하므로, 이 신호는 공격자가 기본적인 토큰 남용에서 장기적인 침해와 연계된 지속적이고 은밀한 접근으로 넘어간 시점을 식별하는 데 중요한 역할을 합니다.

event.dataset: "azure.signinlogs" and
    event.category: "authentication" and
    azure.signinlogs.properties.user_type: "Member" and
    azure.signinlogs.properties.token_protection_status_details.sign_in_session_status: "unbound" and
    not azure.signinlogs.properties.device_detail.device_id: "" and
    azure.signinlogs.properties.user_principal_name: *

새로운 용어 값:

  • azure.signinlogs.properties.user_principal_name
  • azure.signinlogs.properties.device_detail.device_id

이 에뮬레이션을 통해 동의를 구하는 피싱부터 디바이스 신뢰 설정, 장기 지속성을 위한 PRT 발행에 이르기까지 전체 공격자 워크플로우를 검증할 수 있었습니다. 공격자는 디바이스 등록과 OAuth 남용을 연결하여 CAP를 충족하고, 규정을 준수하는 엔드포인트를 가장하고, 기존 보안 제어를 트리거하지 않고 클라우드 환경을 횡적으로 이동할 수 있습니다.

이러한 뉘앙스가 중요합니다. 토큰 발급이나 디바이스 등록과 같은 개별 이벤트는 개별적으로 보면 정상으로 보일 수 있습니다. 그러나 로그인 로그, 감사 데이터, 토큰 메타데이터를 상호 연관시키면 뚜렷한 신원 유출 흔적을 발견할 수 있습니다.

탐지 및 악용을 위한 주요 텔레메트리 세부 정보

에뮬레이션 및 탐지 노력 전반에 걸쳐 특정 원격 측정 아티팩트는 양성 OAuth 활동과 악의적인 악용을 구분하는 데 지속적으로 필수적인 것으로 입증되었습니다. 효과적인 헌팅 및 탐지 엔지니어링을 위해서는 Microsoft Entra ID 로그에 이러한 필드가 나타나는 방식과 공격자가 이러한 필드를 조작하는 방법을 이해하는 것이 중요합니다. 클라이언트 ID와 부여 유형부터 디바이스 규정 준수, 토큰 유형, 조건부 액세스 결과까지, 이러한 신호는 ID 기반 공격에 대한 이야기를 들려줍니다. 아래에서 가장 중요한 기능 목록과 이를 통해 얻을 수 있는 이점을 정리해 보았습니다.

클라이언트 애플리케이션 ID(client_id): OAuth 요청을 시작하는 애플리케이션을 식별합니다. 퍼스트 파티 클라이언트(예 VSCode, 인증 브로커)를 악용하여 혼합할 수 있습니다. 타사 클라이언트는 악의적이거나 검토되지 않았을 수 있으며, 이는 종종 동의 승인 공격을 나타냅니다. 주로 위험하거나 예기치 않은 앱 사용을 식별하는 데 사용됩니다.

대상 리소스(resource_id / resource_display_name): 액세스 중인 MSFT 서비스를 정의합니다(예 MSFT 그래프 또는 Teams). 높은 가치 대상에는 Graph API, SharePoint, Outlook, Teams 및 디렉터리 서비스가 포함됩니다. 리소스 타겟팅은 공격자의 목표에 따라 범위가 정해지는 경우가 많습니다.

본인 유형(사용자_유형): 회원(사용자)의 로그인인지 서비스 주체의 로그인인지를 나타냅니다. 피싱 캠페인은 거의 항상 회원 계정을 대상으로 합니다. 이를 통해 탐지 로직에서 쉽게 필터링할 수 있을 뿐만 아니라 사용자 주체를 대신하여 비정상적인 퍼스트 파티 클라이언트 요청을 페어링하는 데 도움이 됩니다.

OAuth 부여 유형(인증_처리_세부정보): 인증 코드, 새로 고침 토큰, 디바이스 코드, 클라이언트 자격 증명 등 토큰을 획득한 방법을 이해하기 위한 핵심 정보입니다. 새로 고침 토큰과 디바이스 코드 재사용은 유출 이후를 알려주는 확실한 신호입니다.

지리적 위치: 비정형 로그인을 식별할 수 있습니다(예 보기 드문 국가) 또는 불가능한 여행(단시간 내에 먼 곳에서 같은 사용자가 이동하는 경우). 세션 ID 및 상관관계 ID와 결합하면 토큰 탈취, 신원 도용 또는 측면 이동을 파악할 수 있습니다.

디바이스 메타데이터(device_detail, trust_type, compliance_state): 디바이스 ID, 운영 체제, 신뢰 유형, 규정 준수, 관리 상태 등이 포함됩니다. 장치 등록 및 PRT 발급은 이 메타데이터에 연결됩니다. 공격자들은 종종 CAP를 만족시키고 신뢰할 수 있는 액세스 권한을 지속적으로 확보하는 것을 목표로 합니다.

인증 프로토콜 및 유형(인증_프로토콜 / 수신_토큰_유형): 세션이 OAuth 기반인지 또는 MFA를 사용했는지 여부를 표시합니다. 들어오는 토큰 소스는 이 요청에 사용되는 authN 또는 authZ를 제공하는 토큰 소스입니다. 토큰 재사용, 비대화형 로그인을 감지하는 데 유용합니다.

인증 자료 및 세션 컨텍스트: 사용된 토큰은 수신 토큰 유형, 토큰 보호 상태 및 세션 ID를 통해 유추할 수 있습니다. 세션 재사용, 긴 세션 기간 또는 단일 세션에 연결된 여러 IP는 종종 남용을 나타냅니다.

조건부 액세스 정책 상태: 토큰 발급 시 평가되지만 액세스 권한 부여 여부에 큰 영향을 미칩니다. 이를 통해 CAP 회피, 예상치 못한 정책 결과 또는 위험 요소를 파악할 수 있습니다.

범위 및 동의 동작: 요청된 범위는 로그인 로그에 캡처된 SCP 또는 OAuth 매개변수에 나타납니다. 남용 지표에는 오프라인_액세스, .default가 포함됩니다, 또는 Mail.ReadWrite와 같은 광범위한 범위. 동의 원격 분석은 사용자가 의심스러운 애플리케이션을 승인했는지 피벗하거나 상관관계를 파악하는 데 도움이 될 수 있습니다.

결론

Microsoft Entra ID의 OAuth 구현은 강력하고 원활한 인증 환경을 제공하지만 공격자가 신뢰, 세션 지속성 및 디바이스 등록 공격 경로를 악용할 수 있는 새로운 기회를 노출하는 양날의 검과도 같습니다.

저희 팀은 Volexity에서 관찰한 OAuth 피싱 기술을 복제하여 공격자가 어떻게 합법적인 Microsoft 애플리케이션, 토큰 흐름 및 오픈 소스 도구를 악용하여 민감한 데이터에 은밀하게 액세스하는지를 검증할 수 있었습니다. 저희는 실습 에뮬레이션을 통해 이 작업을 확장하여 OAuth 피싱과 워크플로, 보안 토큰 메타데이터 및 획득의 메커니즘을 자세히 살펴보고 방어자가 탐지할 수 있는 행동 지표를 드러내는 데 도움을 주었습니다.

이번 조사 결과는 중요한 점을 강조합니다: OAuth 악용은 멀웨어나 코드 실행에 의존하지 않습니다. 신원, 동의, 토큰 재사용을 무기화하여 기존의 보안 제어를 어렵게 만들고 로그 기반 탐지, 상관관계, 행동 분석이 중요한 이유도 여기에 있습니다.

여기에서 공유한 에뮬레이션 아티팩트, 탐지 규칙 및 교훈을 통해 커뮤니티의 방어자들이 진화하는 클라우드 기반 ID 위협을 더 잘 이해하고 탐지/탐색하는 데 도움이 되기를 바랍니다.

Elastic을 사용 중이시라면, 이 블로그에서 설명한 모든 탐색 규칙을 오픈 소스화하여 시작하실 수 있습니다. 다른 SIEM에서 헌팅하는 경우, 로직을 적용하고 환경에 맞게 조정하는 것이 좋습니다.

이제 아이덴티티는 새로운 경계이며, 이제 우리는 아이덴티티를 그렇게 대할 때입니다. 안전하고 즐거운 사냥을 즐기세요!

탐지 규칙

참조: