Tìm kiếm trang web

Vô hiệu hóa PowerShell cho người dùng Exchange Online


Loại bỏ Exchange Online PowerShell để giảm bề mặt tấn công

Trừ khi chúng thuộc về quản trị viên, hộp thư của người dùng không cần quyền truy cập vào Exchange Online PowerShell. Khi Exchange 2007 ban đầu giới thiệu hỗ trợ PowerShell, người dùng cuối đã mong muốn chạy PowerShell cho mục đích tự động hóa của riêng họ. Mặc dù có thể, nhưng tôi chưa bao giờ gặp người dùng cuối chạy Get-Mailbox để kiểm tra cài đặt hộp thư của họ hoặc Get-MailboxStatistics để kiểm tra kích thước hộp thư của họ.

Sự xuất hiện của kiểm soát truy cập dựa trên vai trò (RBAC) trong Exchange 2010 đã hạn chế những gì mọi người có thể làm bằng cách giới hạn tập hợp các lệnh ghép ngắn và tham số có sẵn dựa trên vai trò do tài khoản người dùng nắm giữ. Điều này khiến PowerShell dành cho người dùng cuối trở thành một triển vọng kém hấp dẫn hơn nhưng khả năng chạy PowerShell vẫn là mặc định cho cả Exchange Online và Exchange Server. Và đó là một vấn đề.

Đã khóa Exchange Online PowerShell

Vấn đề rất đơn giản. Mặc dù Microsoft đã khóa mô-đun quản lý Exchange Online đối với những người dùng không giữ vai trò quản trị viên để họ không thể chạy nhiều lệnh ghép ngắn (Hình 1), nhưng vẫn nên loại bỏ quyền truy cập vào các tính năng mà mọi người không cần chỉ sử dụng trong trường hợp kẻ tấn công xâm phạm tài khoản và tìm ra điểm yếu để khai thác.

Tài liệu của Microsoft hướng dẫn cách tắt PowerShell cho người dùng cuối đã lỗi thời. Ví dụ: nó đề xuất sử dụng các quy tắc truy cập của máy khách để chặn quyền truy cập PowerShell mặc dù thực tế là Microsoft sẽ vô hiệu hóa hầu hết các quy tắc truy cập của máy khách vào tháng 9 năm 2023. Các đề xuất về cách chạy lệnh ghép ngắn Set-User để chặn PowerShell là chính xác nhưng còn hạn chế. Chúng ta có thể làm tốt hơn.

Phác thảo giải pháp

Các đặc điểm của một giải pháp khả thi để sử dụng trong sản xuất có thể bao gồm:

  • Cho phép quyền truy cập PowerShell cho bất kỳ tài khoản nào giữ vai trò Quản trị viên toàn cầu hoặc quản trị viên Exchange.
  • Xóa quyền truy cập PowerShell cho bất kỳ tài khoản người dùng nào khác.
  • Chạy theo lịch trình để vô hiệu hóa quyền truy cập cho các hộp thư mới được tạo.

Việc biến những điểm này thành mã PowerShell khá đơn giản:

  • Tìm các thành viên của nhóm vai trò Quản trị viên toàn cầu và quản trị viên Exchange.
  • Loại trừ các nguyên tắc dịch vụ có thể nằm trong nhóm vai trò quản trị viên Exchange để cho phép các ứng dụng hoạt động với tư cách quản trị viên Exchange. Ví dụ: nguyên tắc dịch vụ cho các tài khoản Azure Automation chạy tập lệnh Exchange phải được thêm vào nhóm vai trò quản trị viên Exchange (xem ví dụ trong bài viết này).
  • Tìm hộp thư của người dùng bằng Get-ExoMailbox.
  • Đối với mỗi hộp thư, hãy kiểm tra xem hộp thư đó có thuộc quyền sở hữu của quản trị viên hay không. Nếu không, hãy vô hiệu hóa quyền truy cập PowerShell và ghi lại thông tin thực tế trong thuộc tính tùy chỉnh (vì không cần truy cập thông tin thông qua Entra ID nên cũng có thể sử dụng thuộc tính tiện ích mở rộng tùy chỉnh Exchange).

Việc sử dụng thuộc tính để ghi lại xem hộp thư có thể sử dụng PowerShell hay không sẽ cho phép Get-ExoMailbox sử dụng bộ lọc phía máy chủ để hạn chế tập hợp hộp thư ở những hộp thư chưa được xử lý. Sau lần chạy đầu tiên mà mọi hộp thư của người dùng đều phải được xử lý, bộ lọc sẽ tăng tốc độ xử lý và khiến nó trở nên khả thi ngay cả trong các tổ chức rất lớn.

Dưới đây là một số mã thực hiện công việc bằng cách sử dụng các lệnh ghép ngắn từ Microsoft Graph PowerShell SDK và mô-đun quản lý Exchange Online:

Connect-MgGraph -Scopes Directory.Read.All
Select-MgProfile Beta
Connect-ExchangeOnline

# Get set of accounts holding the Exchange Online Administrator role
$ExoAdminRoleId = Get-MgDirectoryRole | Where-Object {$_.displayName -eq "Exchange administrator"} | Select-Object -ExpandProperty Id
[array]$ExoAdmins = (Get-MgDirectoryRoleMember -DirectoryRoleId $ExoAdminRoleId) | Select-Object -ExpandProperty AdditionalProperties
# Remove any service principals from the set
$ExoAdmins = $ExoAdmins | Where-Object {$_.'@odata.type' -eq '#microsoft.graph.user'}
# Now get the set of accounts holding the Global Administrator role
$GlobalAdminRoleId = Get-MgDirectoryRole | Where-Object {$_.displayName -eq "Global administrator"} | Select-Object -ExpandProperty Id
[array]$GlobalAdmins = (Get-MgDirectoryRoleMember -DirectoryRoleId $GlobalAdminRoleId) | Select-Object -ExpandProperty AdditionalProperties
# Create an array holding the user principal names of the two sets of administrator accounts
[array]$AdminAccounts = $GlobalAdmins.userPrincipalName + $ExoAdmins.userPrincipalName | Sort-Object -Unique

# Find Exchange user mailboxes that need to be processed
[array]$ExoMailboxes = Get-ExoMailbox -Filter {CustomAttribute5 -eq $Null} -ResultSize Unlimited -RecipientTypeDetails UserMailbox -Properties CustomAttribute5

ForEach ($Mbx in $ExoMailboxes) {
   # If not an admin holder, go ahead and block PowerShell
   If ($Mbx.userPrincipalName -notin $AdminAccounts) {
     Write-Output ("Blocking PowerShell access for mailbox {0}..." -f $Mbx.displayName)
     Try {
         Set-User -Identity $Mbx.userPrincipalName -EXOModuleEnabled $False -Confirm:$False
         $MessageText = "PowerShell disabled on " + (Get-Date -format s)
         Set-Mailbox -Identity $Mbx.userPrincipalName -CustomAttribute5 $MessageText
     }
     Catch {
         Write-Output ("Error disabling PowerShell for mailbox {0}" -f $Mbx.userPrincipalNane )
     }
   } Else {
     Set-Mailbox -Identity $Mbx.userPrincipalName -CustomAttribute5 "PowerShell Enabled"
   }
 
} # End ForEach

Ngoài ra, tham số cũ để vô hiệu hóa quyền truy cập PowerShell là RemotePowerShellEnabled. Tham số mới mà bạn nên sử dụng là EXOModuleEnabled. Microsoft đang xóa PowerShell từ xa khỏi Exchange Online nhưng tham số EXOModuleEnabled tiếp tục chi phối quyền truy cập của người dùng vào Exchange PowerShell.

Tự động hóa quy trình cho hộp thư mới

Tập lệnh hoạt động một lần nhưng để hiệu quả hơn, nó nên chạy theo lịch trình tự động. Cách tốt nhất và an toàn nhất mà tôi biết để thực hiện việc này là sử dụng Azure Automation. Vì không yêu cầu đăng ký Azure nên Bộ lập lịch Windows là một lựa chọn rẻ hơn. Nhược điểm là bạn phải lên lịch để tập lệnh chạy trên một máy trạm cụ thể và phải sắp xếp xác thực an toàn cho tài khoản được sử dụng để chạy tập lệnh. Tôi thích khả năng bảo mật và tự động hóa tốt hơn do danh tính được quản lý của Azure Automation cung cấp, đây là những gì tôi sử dụng.

Việc thực thi mã hiển thị ở trên trong sổ tay chạy Azure Automation rất đơn giản. Các yêu cầu là:

  • Sử dụng tài khoản Azure Automation được chỉ định quyền cần thiết (Directory.Read.All) để đọc thông tin vai trò từ thư mục.
  • Tài khoản Azure Automation cũng phải có vai trò Quản lý Exchange dưới dạng ứng dụng.
  • Tạo một runbook có nhiều mã giống nhau. Sự khác biệt là ở kết nối và xác thực. Đây là cách runbook nhận được mã thông báo truy cập để đăng nhập vào Biểu đồ và kết nối với Exchange Online. Phần còn lại của mã vẫn giữ nguyên.
Connect-AzAccount -Identity
$AccessToken = Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com"
Connect-MgGraph -AccessToken $AccessToken.Token
# Connect to Exchange Online
Connect-ExchangeOnline -ManagedIdentity -Organization office365itpros.onmicrosoft.com

Kiểm tra sổ tay chạy với các yêu cầu này để đưa ra kết quả mong đợi. Trong Hình 2, chúng ta thấy tập hợp các tài khoản quản trị viên (bị che khuất) và bốn hộp thư hiện không thể sử dụng PowerShell.

Tập lệnh được sử dụng ở đây không bao gồm việc ghi nhật ký. Sẽ thật đơn giản khi thêm tính năng ghi nhật ký hành động được thực hiện cho mỗi hộp thư và sau đó gửi nhật ký cho quản trị viên qua email hoặc bằng cách đăng lên kênh Nhóm.

Lập kế hoạch Runbook

Sau khi điều chỉnh sổ chạy để thực thi thành công, bạn có thể xuất bản sổ chạy và liên kết sổ chạy với lịch trình tự động hóa. Lịch trình là tài nguyên thuộc về tài khoản tự động hóa, quyết định thời điểm Azure Automation thực thi công việc. Lịch trình có thể là một lần hoặc định kỳ. Trong trường hợp này, kiểm tra hàng tuần có thể đủ để chặn PowerShell đối với các hộp thư mới. Hình 3 cho thấy runbook được liên kết với một lịch trình.

Không cần sự can thiệp của quản trị viên để đảm bảo công việc được thực hiện. Azure Automation có công cụ lập kế hoạch và thực thi mạnh mẽ mà bạn có thể tin cậy. Tuy nhiên, điều khôn ngoan là xác minh rằng công việc đó có tạo ra kết quả như mong đợi hay không. Mã này kiểm tra xem PowerShell có bị chặn đối với tất cả các hộp thư không phải của quản trị viên hay không (sử dụng mã ở trên để xây dựng mảng $AdminAccounts).

$Report =  [System.Collections.Generic.List[Object]]::new()
[array]$ExoMailboxes = Get-ExoMailbox -Filter {CustomAttribute5 -ne $Null} -ResultSize Unlimited -RecipientTypeDetails UserMailbox -Properties CustomAttribute5

ForEach ($Mbx in $ExoMailboxes) {
   # If not an admin holder, go ahead and block PowerShell
   If ($Mbx.userPrincipalName -notin $AdminAccounts) {
      $Status = (Get-User -Identity $Mbx.userPrincipalName).EXOModuleEnabled 
      $UserData = [PSCustomObject][Ordered]@{  
         User   = $Mbx.userPrincipalName
         Name   = $Mbx.displayName
         PS     = $Status
         Status = $Mbx.CustomAttribute5}
      $Report.Add($UserData) }
}
$Report | Out-GridView

Kết thúc

Chúng tôi đã khám phá một số khái niệm trong bài viết này từ chặn hộp thư Exchange Online PowerShell cho người dùng đến sử dụng Azure Automation với danh tính được quản lý và chạy công việc theo lịch trình. Vấn đề là không có gì khó khăn trong những gì tôi mô tả ở đây. Tất cả đều rất có thể và dễ thực hiện.

Cập nhật: Tôi mô tả một cách tiếp cận khác để chặn quyền truy cập của người dùng vào mô-đun Microsoft 365 PowerShell tại đây.

Di chuyển theo yêu cầu

Di chuyển tất cả khối lượng công việc và Active Directory của bạn bằng một giải pháp di chuyển toàn diện từ đối tượng thuê sang đối tượng thuê Office 365.

Bài viết liên quan